mirror of
https://git.proxmox.com/git/systemd
synced 2025-05-30 23:36:31 +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
|
Any configuration options can be specified as -Darg=value... arguments
|
||||||
to meson. After the build directory is initially configured, meson will
|
to meson. After the build directory is initially configured, meson will
|
||||||
refuse to run again, and options must be changed with:
|
refuse to run again, and options must be changed with:
|
||||||
mesonconf -Darg=value...
|
meson configure -Darg=value build/
|
||||||
mesonconf without any arguments will print out available options and
|
meson configure without any arguments will print out available options and
|
||||||
their current values.
|
their current values.
|
||||||
|
|
||||||
Useful commands:
|
Useful commands:
|
||||||
|
@ -145,7 +145,7 @@ names for them in UIs.
|
|||||||
|
|
||||||
## Links
|
## 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>
|
[Discoverable Partitions Specification](https://systemd.io/DISCOVERABLE_PARTITIONS)<br>
|
||||||
[systemd-boot(7)](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<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>
|
[bootctl(1)](https://www.freedesktop.org/software/systemd/man/bootctl.html)<br>
|
||||||
|
@ -277,6 +277,25 @@
|
|||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</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>
|
<varlistentry>
|
||||||
<term><option>skip=</option></term>
|
<term><option>skip=</option></term>
|
||||||
|
|
||||||
|
@ -41,6 +41,9 @@
|
|||||||
symlink target name of <filename>/etc/localtime</filename>, this
|
symlink target name of <filename>/etc/localtime</filename>, this
|
||||||
file may not be a normal file or hardlink.</para>
|
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
|
<para>The timezone may be overridden for individual programs by
|
||||||
using the <varname>$TZ</varname> environment variable. See
|
using the <varname>$TZ</varname> environment variable. See
|
||||||
<citerefentry project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
<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
|
<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
|
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
|
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
|
are allowed, but the whole sequence must be valid UTF-8. (Note that control characters like newline
|
||||||
block is limited to <constant>_SC_ARG_MAX</constant> value defined by
|
(<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>.
|
<citerefentry project='man-pages'><refentrytitle>sysconf</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -1123,10 +1125,12 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Import all, one or more environment variables set on the client into the systemd manager
|
<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.
|
environment block. If a list of environment variable names is passed, client-side values are then
|
||||||
Otherwise, a list of one or more environment variable names should be passed, whose client-side
|
imported into the manager's environment block. If any names are not valid environment variable
|
||||||
values are then imported into the manager's environment block. This command will silently ignore
|
names or have invalid values according to the rules described above, an error is raised. If no
|
||||||
any assignments which do not conform to the rules listed above.</para>
|
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>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</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
|
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
|
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
|
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
|
<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
|
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
|
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
|
<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>
|
<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
|
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.
|
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,
|
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>
|
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
|
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>
|
(in case <varname>PAMName=</varname> is used).</para>
|
||||||
|
|
||||||
<para>
|
<para>See "Environment Variables in Spawned Processes" below for a description of how those
|
||||||
See <citerefentry
|
settings combine to form the inherited environment. See <citerefentry
|
||||||
project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for details
|
project='man-pages'><refentrytitle>environ</refentrytitle><manvolnum>7</manvolnum></citerefentry> for general
|
||||||
about environment variables.</para></listitem>
|
information about environment variables.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
@ -2809,7 +2809,7 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
|
|||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<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
|
<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
|
multiple sources. Processes started by the system service manager generally do not inherit environment variables
|
||||||
@ -2822,410 +2822,427 @@ StandardInputData=SWNrIHNpdHplIGRhIHVuJyBlc3NlIEtsb3BzLAp1ZmYgZWVtYWwga2xvcHAncy
|
|||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem><para>Variables globally configured for the service manager, using the
|
<listitem><para>Variables globally configured for the service manager, using the
|
||||||
<varname>DefaultEnvironment=</varname> setting in
|
<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-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>) or via
|
the kernel command line option <varname>systemd.setenv=</varname> understood by
|
||||||
<command>systemctl set-environment</command> (see <citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>).</para></listitem>
|
<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,
|
<listitem><para>Variables set by any PAM modules in case <varname>PAMName=</varname> is in effect,
|
||||||
cf. <citerefentry
|
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>
|
</itemizedlist>
|
||||||
|
|
||||||
<para>If the same environment variables are set by multiple of these sources, the later source — according to the
|
<para>If the same environment variable is set by multiple of these sources, the later source — according
|
||||||
order of the list above — wins. Note that as final step all variables listed in
|
to the order of the list above — wins. Note that as the final step all variables listed in
|
||||||
<varname>UnsetEnvironment=</varname> are removed again from the compiled environment variable list, immediately
|
<varname>UnsetEnvironment=</varname> are removed from the compiled environment variable list, immediately
|
||||||
before it is passed to the executed process.</para>
|
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
|
<para>The general philosophy is to expose a small curated list of environment variables to processes.
|
||||||
process:</para>
|
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'>
|
<para>Hint: <command>systemd-run -P env</command> and <command>systemd-run --user -P env</command> print
|
||||||
<varlistentry>
|
the effective system and user service environment blocks.</para>
|
||||||
<term><varname>$PATH</varname></term>
|
|
||||||
|
|
||||||
<listitem><para>Colon-separated list of directories to use when launching
|
<refsect2>
|
||||||
executables. <command>systemd</command> uses a fixed value of
|
<title>Environment Variables Set or Propagated by the Service Manager</title>
|
||||||
<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>
|
|
||||||
|
|
||||||
<varlistentry>
|
<para>The following environment variables are propagated by the service manager or generated internally
|
||||||
<term><varname>$LANG</varname></term>
|
for each invoked process:</para>
|
||||||
|
|
||||||
<listitem><para>Locale. Can be set in
|
<variablelist class='environment-variables'>
|
||||||
<citerefentry project='man-pages'><refentrytitle>locale.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
<varlistentry>
|
||||||
or on the kernel command line (see
|
<term><varname>$PATH</varname></term>
|
||||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
|
||||||
and
|
|
||||||
<citerefentry><refentrytitle>kernel-command-line</refentrytitle><manvolnum>7</manvolnum></citerefentry>).
|
|
||||||
</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>Colon-separated list of directories to use when launching
|
||||||
<term><varname>$USER</varname></term>
|
executables. <command>systemd</command> uses a fixed value of
|
||||||
<term><varname>$LOGNAME</varname></term>
|
<literal><filename>/usr/local/sbin</filename>:<filename>/usr/local/bin</filename>:<filename>/usr/sbin</filename>:<filename>/usr/bin</filename></literal>
|
||||||
<term><varname>$HOME</varname></term>
|
in the system manager. When compiled for systems with "unmerged <filename>/usr/</filename>"
|
||||||
<term><varname>$SHELL</varname></term>
|
(<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
|
<varlistentry>
|
||||||
login shell. The variables are set for the units that have
|
<term><varname>$LANG</varname></term>
|
||||||
<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>
|
<listitem><para>Locale. Can be set in <citerefentry
|
||||||
<term><varname>$INVOCATION_ID</varname></term>
|
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
|
<varlistentry>
|
||||||
as 32 character hexadecimal string. A new ID is assigned each time the unit changes from an inactive state into
|
<term><varname>$USER</varname></term>
|
||||||
an activating or active state, and may be used to identify this specific runtime cycle, in particular in data
|
<term><varname>$LOGNAME</varname></term>
|
||||||
stored offline, such as the journal. The same ID is passed to all processes run as part of the
|
<term><varname>$HOME</varname></term>
|
||||||
unit.</para></listitem>
|
<term><varname>$SHELL</varname></term>
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>User name (twice), home directory, and the
|
||||||
<term><varname>$XDG_RUNTIME_DIR</varname></term>
|
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
|
<varlistentry>
|
||||||
services run by the user <command>systemd</command> instance, as well as any system services that use
|
<term><varname>$INVOCATION_ID</varname></term>
|
||||||
<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>
|
<listitem><para>Contains a randomized, unique 128bit ID identifying each runtime cycle of the unit, formatted
|
||||||
<term><varname>$RUNTIME_DIRECTORY</varname></term>
|
as 32 character hexadecimal string. A new ID is assigned each time the unit changes from an inactive state into
|
||||||
<term><varname>$STATE_DIRECTORY</varname></term>
|
an activating or active state, and may be used to identify this specific runtime cycle, in particular in data
|
||||||
<term><varname>$CACHE_DIRECTORY</varname></term>
|
stored offline, such as the journal. The same ID is passed to all processes run as part of the
|
||||||
<term><varname>$LOGS_DIRECTORY</varname></term>
|
unit.</para></listitem>
|
||||||
<term><varname>$CONFIGURATION_DIRECTORY</varname></term>
|
</varlistentry>
|
||||||
|
|
||||||
<listitem><para>Absolute paths to the directories defined with
|
<varlistentry>
|
||||||
<varname>RuntimeDirectory=</varname>, <varname>StateDirectory=</varname>,
|
<term><varname>$XDG_RUNTIME_DIR</varname></term>
|
||||||
<varname>CacheDirectory=</varname>, <varname>LogsDirectory=</varname>, and
|
|
||||||
<varname>ConfigurationDirectory=</varname> when those settings are used.</para>
|
|
||||||
</listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>The directory to use for runtime objects (such as IPC objects) and volatile state. Set for all
|
||||||
<term><varname>$CREDENTIALS_DIRECTORY</varname></term>
|
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
|
<varlistentry>
|
||||||
<varname>LoadCredential=</varname>/<varname>SetCredential=</varname>. The directory is marked
|
<term><varname>$RUNTIME_DIRECTORY</varname></term>
|
||||||
read-only and is placed in unswappable memory (if supported and permitted), and is only accessible to
|
<term><varname>$STATE_DIRECTORY</varname></term>
|
||||||
the UID associated with the unit via <varname>User=</varname> or <varname>DynamicUser=</varname> (and
|
<term><varname>$CACHE_DIRECTORY</varname></term>
|
||||||
the superuser).</para></listitem>
|
<term><varname>$LOGS_DIRECTORY</varname></term>
|
||||||
</varlistentry>
|
<term><varname>$CONFIGURATION_DIRECTORY</varname></term>
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>Absolute paths to the directories defined with
|
||||||
<term><varname>$MAINPID</varname></term>
|
<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
|
<varlistentry>
|
||||||
known. This is only set for control processes as invoked by
|
<term><varname>$CREDENTIALS_DIRECTORY</varname></term>
|
||||||
<varname>ExecReload=</varname> and similar. </para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>An absolute path to the per-unit directory with credentials configured via
|
||||||
<term><varname>$MANAGERPID</varname></term>
|
<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>
|
<varlistentry>
|
||||||
instance, set for processes spawned by it. </para></listitem>
|
<term><varname>$MAINPID</varname></term>
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>The PID of the unit's main process if it is
|
||||||
<term><varname>$LISTEN_FDS</varname></term>
|
known. This is only set for control processes as invoked by
|
||||||
<term><varname>$LISTEN_PID</varname></term>
|
<varname>ExecReload=</varname> and similar. </para></listitem>
|
||||||
<term><varname>$LISTEN_FDNAMES</varname></term>
|
</varlistentry>
|
||||||
|
|
||||||
<listitem><para>Information about file descriptors passed to a
|
<varlistentry>
|
||||||
service for socket activation. See
|
<term><varname>$MANAGERPID</varname></term>
|
||||||
<citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
|
||||||
</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>The PID of the user <command>systemd</command>
|
||||||
<term><varname>$NOTIFY_SOCKET</varname></term>
|
instance, set for processes spawned by it. </para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<listitem><para>The socket
|
<varlistentry>
|
||||||
<function>sd_notify()</function> talks to. See
|
<term><varname>$LISTEN_FDS</varname></term>
|
||||||
<citerefentry><refentrytitle>sd_notify</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
<term><varname>$LISTEN_PID</varname></term>
|
||||||
</para></listitem>
|
<term><varname>$LISTEN_FDNAMES</varname></term>
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>Information about file descriptors passed to a
|
||||||
<term><varname>$WATCHDOG_PID</varname></term>
|
service for socket activation. See
|
||||||
<term><varname>$WATCHDOG_USEC</varname></term>
|
<citerefentry><refentrytitle>sd_listen_fds</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
||||||
|
</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<listitem><para>Information about watchdog keep-alive notifications. See
|
<varlistentry>
|
||||||
<citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry>.
|
<term><varname>$NOTIFY_SOCKET</varname></term>
|
||||||
</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>The socket
|
||||||
<term><varname>$TERM</varname></term>
|
<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
|
<varlistentry>
|
||||||
a terminal (<varname>StandardInput=tty</varname>,
|
<term><varname>$WATCHDOG_PID</varname></term>
|
||||||
<varname>StandardOutput=tty</varname>, or
|
<term><varname>$WATCHDOG_USEC</varname></term>
|
||||||
<varname>StandardError=tty</varname>). See
|
|
||||||
<citerefentry project='man-pages'><refentrytitle>termcap</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
|
||||||
</para></listitem>
|
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>Information about watchdog keep-alive notifications. See
|
||||||
<term><varname>$LOG_NAMESPACE</varname></term>
|
<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
|
<varlistentry>
|
||||||
<varname>LogNamespace=</varname> service setting is used.</para></listitem>
|
<term><varname>$TERM</varname></term>
|
||||||
</varlistentry>
|
|
||||||
|
|
||||||
<varlistentry>
|
<listitem><para>Terminal type, set only for units connected to
|
||||||
<term><varname>$JOURNAL_STREAM</varname></term>
|
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
|
<varlistentry>
|
||||||
journal (for example, by setting <varname>StandardError=journal</varname>) <varname>$JOURNAL_STREAM</varname>
|
<term><varname>$LOG_NAMESPACE</varname></term>
|
||||||
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>
|
|
||||||
|
|
||||||
<para>If both standard output and standard error of the executed processes are connected to the journal via a
|
<listitem><para>Contains the name of the selected logging namespace when the
|
||||||
stream socket, this environment variable will contain information about the standard error stream, as that's
|
<varname>LogNamespace=</varname> service setting is used.</para></listitem>
|
||||||
usually the preferred destination for log data. (Note that typically the same stream is used for both standard
|
</varlistentry>
|
||||||
output and standard error, hence very likely the environment variable contains device and inode information
|
|
||||||
matching both stream file descriptors.)</para>
|
|
||||||
|
|
||||||
<para>This environment variable is primarily useful to allow services to optionally upgrade their used log
|
<varlistentry>
|
||||||
protocol to the native journal protocol (using
|
<term><varname>$JOURNAL_STREAM</varname></term>
|
||||||
<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>
|
<listitem><para>If the standard output or standard error output of the executed processes are connected to the
|
||||||
<term><varname>$SERVICE_RESULT</varname></term>
|
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
|
<para>If both standard output and standard error of the executed processes are connected to the journal via a
|
||||||
<varname>ExecStop=</varname> and <varname>ExecStopPost=</varname> processes, and encodes the service
|
stream socket, this environment variable will contain information about the standard error stream, as that's
|
||||||
"result". Currently, the following values are defined:</para>
|
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>
|
<para>This environment variable is primarily useful to allow services to optionally upgrade their used log
|
||||||
<title>Defined <varname>$SERVICE_RESULT</varname> values</title>
|
protocol to the native journal protocol (using
|
||||||
<tgroup cols='2'>
|
<citerefentry><refentrytitle>sd_journal_print</refentrytitle><manvolnum>3</manvolnum></citerefentry> and other
|
||||||
<colspec colname='result'/>
|
functions) if their standard output or standard error output is connected to the journal anyway, thus enabling
|
||||||
<colspec colname='meaning'/>
|
delivery of structured metadata along with logged messages.</para></listitem>
|
||||||
<thead>
|
</varlistentry>
|
||||||
<row>
|
|
||||||
<entry>Value</entry>
|
|
||||||
<entry>Meaning</entry>
|
|
||||||
</row>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
<varlistentry>
|
||||||
<row>
|
<term><varname>$SERVICE_RESULT</varname></term>
|
||||||
<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>
|
|
||||||
|
|
||||||
<para>This environment variable is useful to monitor failure or successful termination of a service. Even
|
<listitem><para>Only defined for the service unit type, this environment variable is passed to all
|
||||||
though this variable is available in both <varname>ExecStop=</varname> and <varname>ExecStopPost=</varname>, it
|
<varname>ExecStop=</varname> and <varname>ExecStopPost=</varname> processes, and encodes the service
|
||||||
is usually a better choice to place monitoring tools in the latter, as the former is only invoked for services
|
"result". Currently, the following values are defined:</para>
|
||||||
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>
|
|
||||||
|
|
||||||
<varlistentry>
|
<table>
|
||||||
<term><varname>$EXIT_CODE</varname></term>
|
<title>Defined <varname>$SERVICE_RESULT</varname> values</title>
|
||||||
<term><varname>$EXIT_STATUS</varname></term>
|
<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
|
<tbody>
|
||||||
<varname>ExecStop=</varname>, <varname>ExecStopPost=</varname> processes and contain exit status/code
|
<row>
|
||||||
information of the main process of the service. For the precise definition of the exit code and status, see
|
<entry><literal>success</literal></entry>
|
||||||
<citerefentry><refentrytitle>wait</refentrytitle><manvolnum>2</manvolnum></citerefentry>. <varname>$EXIT_CODE</varname>
|
<entry>The service ran successfully and exited cleanly.</entry>
|
||||||
is one of <literal>exited</literal>, <literal>killed</literal>,
|
</row>
|
||||||
<literal>dumped</literal>. <varname>$EXIT_STATUS</varname> contains the numeric exit code formatted as string
|
<row>
|
||||||
if <varname>$EXIT_CODE</varname> is <literal>exited</literal>, and the signal name in all other cases. Note
|
<entry><literal>protocol</literal></entry>
|
||||||
that these environment variables are only set if the service manager succeeded to start and identify the main
|
<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>
|
||||||
process of the service.</para>
|
</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>
|
<para>This environment variable is useful to monitor failure or successful termination of a service. Even
|
||||||
<title>Summary of possible service result variable values</title>
|
though this variable is available in both <varname>ExecStop=</varname> and <varname>ExecStopPost=</varname>, it
|
||||||
<tgroup cols='3'>
|
is usually a better choice to place monitoring tools in the latter, as the former is only invoked for services
|
||||||
<colspec colname='result' />
|
that managed to start up correctly, and the latter covers both services that failed during their start-up and
|
||||||
<colspec colname='code' />
|
those which failed during their runtime.</para></listitem>
|
||||||
<colspec colname='status' />
|
</varlistentry>
|
||||||
<thead>
|
|
||||||
<row>
|
|
||||||
<entry><varname>$SERVICE_RESULT</varname></entry>
|
|
||||||
<entry><varname>$EXIT_CODE</varname></entry>
|
|
||||||
<entry><varname>$EXIT_STATUS</varname></entry>
|
|
||||||
</row>
|
|
||||||
</thead>
|
|
||||||
|
|
||||||
<tbody>
|
<varlistentry>
|
||||||
<row>
|
<term><varname>$EXIT_CODE</varname></term>
|
||||||
<entry morerows="1" valign="top"><literal>success</literal></entry>
|
<term><varname>$EXIT_STATUS</varname></term>
|
||||||
<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>
|
<listitem><para>Only defined for the service unit type, these environment variables are passed to all
|
||||||
</varlistentry>
|
<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>
|
<table>
|
||||||
<term><varname>$PIDFILE</varname></term>
|
<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
|
<tbody>
|
||||||
service that uses the <varname>PIDFile=</varname> setting, see
|
<row>
|
||||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
<entry morerows="1" valign="top"><literal>success</literal></entry>
|
||||||
for details. Service code may use this environment variable to automatically generate a PID file at
|
<entry valign="top"><literal>killed</literal></entry>
|
||||||
the location configured in the unit file. This field is set to an absolute path in the file
|
<entry><literal>HUP</literal>, <literal>INT</literal>, <literal>TERM</literal>, <literal>PIPE</literal></entry>
|
||||||
system.</para></listitem>
|
</row>
|
||||||
</varlistentry>
|
<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>
|
||||||
|
|
||||||
<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
|
<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
|
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>
|
<listitem>
|
||||||
<para>Sets a comma-separated list of IP (v4 or v6) addresses with CIDR masks
|
<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
|
from which this peer is allowed to send incoming traffic and to
|
||||||
which outgoing traffic for this peer is directed. The catch-all
|
which outgoing traffic for this peer is directed.</para>
|
||||||
0.0.0.0/0 may be specified for matching all IPv4 addresses, and
|
<para>The catch-all 0.0.0.0/0 may be specified for matching all IPv4 addresses,
|
||||||
::/0 may be specified for matching all IPv6 addresses. </para>
|
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>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -1032,8 +1032,11 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Scope=</varname></term>
|
<term><varname>Scope=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>The scope of the address, which can be <literal>global</literal>,
|
<para>The scope of the address, which can be
|
||||||
<literal>link</literal> or <literal>host</literal> or an unsigned integer in the range 0—255.
|
<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>
|
Defaults to <literal>global</literal>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -1340,12 +1343,32 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Scope=</varname></term>
|
<term><varname>Scope=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>The scope of the route, which can be <literal>global</literal>, <literal>site</literal>,
|
<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>. For IPv4 route,
|
<literal>link</literal>, <literal>host</literal>, or
|
||||||
defaults to <literal>host</literal> if <varname>Type=</varname> is <literal>local</literal>
|
<literal>nowhere</literal>:</para>
|
||||||
or <literal>nat</literal>, and <literal>link</literal> if <varname>Type=</varname> is
|
<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>.
|
<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>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
symlink in the distribution package, rather than depending on <command>systemctl
|
symlink in the distribution package, rather than depending on <command>systemctl
|
||||||
enable</command> in the postinst scriptlets of your package. More specifically, for your
|
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
|
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>
|
→ <filename index="false">../foobar.service</filename> to your package.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>Restrict processes to be executed on specific memory NUMA nodes. Takes a list of memory NUMA nodes indices
|
<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
|
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
|
<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
|
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
|
elif __contains_word "$verb" ${VERBS[JOBS]}; then
|
||||||
comps=$( __systemctl $mode list-jobs | { while read -r a b; do echo " $a"; done; } )
|
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 \
|
comps=$( __systemctl $mode show-environment \
|
||||||
| while read -r line; do echo " ${line%%=*}="; done )
|
| while read -r line; do echo " ${line%%=*}="; done )
|
||||||
compopt -o nospace
|
compopt -o nospace
|
||||||
|
|
||||||
|
elif [ "$verb" = 'import-environment' ]; then
|
||||||
|
COMPREPLY=( $(compgen -A variable -- "$cur_orig") )
|
||||||
|
return 0
|
||||||
|
|
||||||
elif __contains_word "$verb" ${VERBS[FILE]}; then
|
elif __contains_word "$verb" ${VERBS[FILE]}; then
|
||||||
comps=$( compgen -A file -- "$cur" )
|
comps=$( compgen -A file -- "$cur" )
|
||||||
compopt -o filenames
|
compopt -o filenames
|
||||||
|
@ -365,6 +365,11 @@ for fun in set-environment unset-environment ; do
|
|||||||
}
|
}
|
||||||
done
|
done
|
||||||
|
|
||||||
|
(( $+functions[_systemctl_import-environment] )) || _systemctl_import-environment()
|
||||||
|
{
|
||||||
|
_parameters
|
||||||
|
}
|
||||||
|
|
||||||
(( $+functions[_systemctl_link] )) || _systemctl_link() {
|
(( $+functions[_systemctl_link] )) || _systemctl_link() {
|
||||||
_sd_unit_files
|
_sd_unit_files
|
||||||
}
|
}
|
||||||
|
@ -59,16 +59,13 @@ bool env_value_is_valid(const char *e) {
|
|||||||
if (!utf8_is_valid(e))
|
if (!utf8_is_valid(e))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* bash allows tabs and newlines in environment variables, and so
|
/* Note that variable *values* may contain control characters, in particular NL, TAB, BS, DEL, ESC…
|
||||||
* should we */
|
* When printing those variables with show-environment, we'll escape them. Make sure to print
|
||||||
if (string_has_cc(e, "\t\n"))
|
* environment variables carefully! */
|
||||||
return false;
|
|
||||||
|
|
||||||
/* POSIX says the overall size of the environment block cannot
|
/* POSIX says the overall size of the environment block cannot be > ARG_MAX, an individual assignment
|
||||||
* be > ARG_MAX, an individual assignment hence cannot be
|
* hence cannot be either. Discounting the shortest possible variable name of length 1, the equal
|
||||||
* either. Discounting the shortest possible variable name of
|
* sign and trailing NUL this hence leaves ARG_MAX-3 as longest possible variable value. */
|
||||||
* 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)
|
if (strlen(e) > sc_arg_max() - 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -88,10 +85,8 @@ bool env_assignment_is_valid(const char *e) {
|
|||||||
if (!env_value_is_valid(eq + 1))
|
if (!env_value_is_valid(eq + 1))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* POSIX says the overall size of the environment block cannot
|
/* POSIX says the overall size of the environment block cannot be > ARG_MAX, hence the individual
|
||||||
* be > ARG_MAX, hence the individual variable assignments
|
* variable assignments cannot be either, but let's leave room for one trailing NUL byte. */
|
||||||
* cannot be either, but let's leave room for one trailing NUL
|
|
||||||
* byte. */
|
|
||||||
if (strlen(e) > sc_arg_max() - 1)
|
if (strlen(e) > sc_arg_max() - 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -1976,3 +1976,53 @@ IteratedCache* iterated_cache_free(IteratedCache *cache) {
|
|||||||
|
|
||||||
return mfree(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);
|
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) {
|
int fd_is_mount_point(int fd, const char *filename, int flags) {
|
||||||
_cleanup_free_ struct file_handle *h = NULL, *h_parent = NULL;
|
_cleanup_free_ struct file_handle *h = NULL, *h_parent = NULL;
|
||||||
int mount_id = -1, mount_id_parent = -1;
|
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(filename);
|
||||||
assert((flags & ~(AT_SYMLINK_FOLLOW|AT_EMPTY_PATH)) == 0);
|
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
|
/* First we will try statx()' STATX_ATTR_MOUNT_ROOT attribute, which is our ideal API, available
|
||||||
* since kernel 5.8.
|
* 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_ _cleanup_(set_freep)
|
||||||
#define _cleanup_set_free_free_ _cleanup_(set_free_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 <inttypes.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include "string-util.h"
|
||||||
#include "time-util.h"
|
#include "time-util.h"
|
||||||
|
|
||||||
struct siphash {
|
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);
|
siphash24_compress(&in, sizeof in, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void siphash24_compress_string(const char *in, struct siphash *state) {
|
static inline void siphash24_compress_safe(const void *in, size_t inlen, struct siphash *state) {
|
||||||
if (!in)
|
if (inlen == 0)
|
||||||
return;
|
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);
|
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) {
|
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 (statfs(path, &s) < 0)
|
||||||
if (fd < 0)
|
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
return fd_is_temporary_fs(fd);
|
return is_temporary_fs(&s);
|
||||||
}
|
}
|
||||||
|
|
||||||
int stat_verify_regular(const struct stat *st) {
|
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
|
* 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. */
|
* parameters are validated however, and that'll fail with EBADF then. */
|
||||||
|
|
||||||
attr = (union bpf_attr) {
|
// FIXME: Clang doesn't 0-pad with structured initialization, causing
|
||||||
.attach_type = BPF_CGROUP_INET_EGRESS,
|
// the kernel to reject the bpf_attr as invalid. See:
|
||||||
.target_fd = -1,
|
// https://github.com/torvalds/linux/blob/v5.9/kernel/bpf/syscall.c#L65
|
||||||
.attach_bpf_fd = -1,
|
// 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 (bpf(BPF_PROG_DETACH, &attr, sizeof(attr)) < 0) {
|
||||||
if (errno != EBADF) {
|
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
|
* 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. */
|
* get EINVAL if it's not supported, and EBADF as before if it is available. */
|
||||||
|
|
||||||
attr = (union bpf_attr) {
|
zero(attr);
|
||||||
.attach_type = BPF_CGROUP_INET_EGRESS,
|
attr.attach_type = BPF_CGROUP_INET_EGRESS;
|
||||||
.target_fd = -1,
|
attr.target_fd = -1;
|
||||||
.attach_bpf_fd = -1,
|
attr.attach_bpf_fd = -1;
|
||||||
.attach_flags = BPF_F_ALLOW_MULTI,
|
attr.attach_flags = BPF_F_ALLOW_MULTI;
|
||||||
};
|
|
||||||
|
|
||||||
if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0) {
|
if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0) {
|
||||||
if (errno == EBADF) {
|
if (errno == EBADF) {
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
#include "hexdecoct.h"
|
#include "hexdecoct.h"
|
||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
#include "ioprio.h"
|
#include "ioprio.h"
|
||||||
#include "journal-util.h"
|
#include "journal-file.h"
|
||||||
#include "mountpoint-util.h"
|
#include "mountpoint-util.h"
|
||||||
#include "namespace.h"
|
#include "namespace.h"
|
||||||
#include "parse-util.h"
|
#include "parse-util.h"
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
#include "ioprio.h"
|
#include "ioprio.h"
|
||||||
#include "ip-protocol-list.h"
|
#include "ip-protocol-list.h"
|
||||||
#include "journal-util.h"
|
#include "journal-file.h"
|
||||||
#include "limits-util.h"
|
#include "limits-util.h"
|
||||||
#include "load-fragment.h"
|
#include "load-fragment.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
# RPM macros for packages installing systemd unit files
|
# RPM macros for packages installing systemd unit files
|
||||||
|
|
||||||
|
%_systemd_util_dir @rootlibexecdir@
|
||||||
%_unitdir @systemunitdir@
|
%_unitdir @systemunitdir@
|
||||||
%_userunitdir @userunitdir@
|
%_userunitdir @userunitdir@
|
||||||
%_presetdir @systempresetdir@
|
%_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);
|
n = recvmsg_safe(m->notify_fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC|MSG_TRUNC);
|
||||||
if (IN_SET(n, -EAGAIN, -EINTR))
|
if (IN_SET(n, -EAGAIN, -EINTR))
|
||||||
return 0; /* Spurious wakeup, try again */
|
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 (n < 0)
|
||||||
/* If this is any other, real error, then let's stop processing this socket. This of course
|
/* 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
|
* 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_discards = false;
|
||||||
static bool arg_same_cpu_crypt = false;
|
static bool arg_same_cpu_crypt = false;
|
||||||
static bool arg_submit_from_crypt_cpus = 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_hidden = false;
|
||||||
static bool arg_tcrypt_system = false;
|
static bool arg_tcrypt_system = false;
|
||||||
static bool arg_tcrypt_veracrypt = false;
|
static bool arg_tcrypt_veracrypt = false;
|
||||||
@ -218,6 +220,10 @@ static int parse_one_option(const char *option) {
|
|||||||
arg_same_cpu_crypt = true;
|
arg_same_cpu_crypt = true;
|
||||||
else if (streq(option, "submit-from-crypt-cpus"))
|
else if (streq(option, "submit-from-crypt-cpus"))
|
||||||
arg_submit_from_crypt_cpus = true;
|
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"))
|
else if (streq(option, "luks"))
|
||||||
arg_type = ANY_LUKS;
|
arg_type = ANY_LUKS;
|
||||||
/* since cryptsetup 2.3.0 (Feb 2020) */
|
/* since cryptsetup 2.3.0 (Feb 2020) */
|
||||||
@ -805,6 +811,12 @@ static uint32_t determine_flags(void) {
|
|||||||
if (arg_submit_from_crypt_cpus)
|
if (arg_submit_from_crypt_cpus)
|
||||||
flags |= CRYPT_ACTIVATE_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
|
#ifdef CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF
|
||||||
/* Try to decrease the risk of OOM event if memory hard key derivation function is in use */
|
/* Try to decrease the risk of OOM event if memory hard key derivation function is in use */
|
||||||
/* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */
|
/* 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;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This is invoked if either the download completed
|
/* This is invoked if either the download completed successfully, or the download was skipped because
|
||||||
* successfully, or the download was skipped because we
|
* we already have the etag. */
|
||||||
* already have the etag. */
|
|
||||||
|
|
||||||
if (!tar_pull_is_done(i))
|
if (!tar_pull_is_done(i))
|
||||||
return;
|
return;
|
||||||
@ -340,6 +339,10 @@ static void tar_pull_job_on_finished(PullJob *j) {
|
|||||||
|
|
||||||
tar_pull_report_progress(i, TAR_FINALIZING);
|
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);
|
r = import_make_read_only(i->temp_path);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
@ -1525,6 +1525,44 @@ int journal_file_find_data_object(
|
|||||||
ret, ret_offset);
|
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(
|
static int journal_file_append_field(
|
||||||
JournalFile *f,
|
JournalFile *f,
|
||||||
const void *field, uint64_t size,
|
const void *field, uint64_t size,
|
||||||
@ -1538,6 +1576,9 @@ static int journal_file_append_field(
|
|||||||
assert(f);
|
assert(f);
|
||||||
assert(field && size > 0);
|
assert(field && size > 0);
|
||||||
|
|
||||||
|
if (!journal_field_valid(field, size, true))
|
||||||
|
return -EBADMSG;
|
||||||
|
|
||||||
hash = journal_file_hash_data(f, field, size);
|
hash = journal_file_hash_data(f, field, size);
|
||||||
|
|
||||||
r = journal_file_find_field_object_with_hash(f, field, size, hash, &o, &p);
|
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);
|
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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
const char *namespace;
|
const char *namespace;
|
||||||
|
LogTarget log_target;
|
||||||
Server server;
|
Server server;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -25,8 +26,13 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
namespace = argc > 1 ? empty_to_null(argv[1]) : NULL;
|
namespace = argc > 1 ? empty_to_null(argv[1]) : NULL;
|
||||||
|
|
||||||
log_set_prohibit_ipc(true);
|
/* So here's the deal: journald can't be considered as regular daemon when it comes to
|
||||||
log_set_target(LOG_TARGET_AUTO);
|
* 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_set_facility(LOG_SYSLOG);
|
||||||
log_parse_environment();
|
log_parse_environment();
|
||||||
log_open();
|
log_open();
|
||||||
|
@ -38,11 +38,14 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
|||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
char **s;
|
char **s;
|
||||||
|
|
||||||
|
if (strv_isempty((char **) optval))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
STRV_FOREACH(s, (char **) optval) {
|
STRV_FOREACH(s, (char **) optval) {
|
||||||
size_t len = strlen(*s);
|
size_t len = strlen(*s);
|
||||||
|
|
||||||
if (len > 255)
|
if (len > 255 || len == 0)
|
||||||
return -ENAMETOOLONG;
|
return -EINVAL;
|
||||||
|
|
||||||
total += 1 + len;
|
total += 1 + len;
|
||||||
}
|
}
|
||||||
@ -51,14 +54,13 @@ static int option_append(uint8_t options[], size_t size, size_t *offset,
|
|||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
|
|
||||||
options[*offset] = code;
|
options[*offset] = code;
|
||||||
options[*offset + 1] = total;
|
options[*offset + 1] = total;
|
||||||
*offset += 2;
|
*offset += 2;
|
||||||
|
|
||||||
STRV_FOREACH(s, (char **) optval) {
|
STRV_FOREACH(s, (char **) optval) {
|
||||||
size_t len = strlen(*s);
|
size_t len = strlen(*s);
|
||||||
|
|
||||||
options[*offset] = len;
|
options[*offset] = len;
|
||||||
|
|
||||||
memcpy(&options[*offset + 1], *s, len);
|
memcpy(&options[*offset + 1], *s, len);
|
||||||
*offset += 1 + 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_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_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_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_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 **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_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,
|
int dhcp6_option_parse(uint8_t **buf, size_t *buflen, uint16_t *optcode,
|
||||||
size_t *optlen, uint8_t **optvalue);
|
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;
|
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;
|
_cleanup_free_ uint8_t *p = NULL;
|
||||||
size_t total = 0, offset = 0;
|
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) {
|
STRV_FOREACH(s, user_class) {
|
||||||
size_t len = strlen(*s);
|
size_t len = strlen(*s);
|
||||||
uint8_t *q;
|
uint8_t *q;
|
||||||
|
|
||||||
if (len > 0xffff)
|
if (len > 0xffff || len == 0)
|
||||||
return -ENAMETOOLONG;
|
return -EINVAL;
|
||||||
q = realloc(p, total + len + 2);
|
q = realloc(p, total + len + 2);
|
||||||
if (!q)
|
if (!q)
|
||||||
return -ENOMEM;
|
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);
|
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;
|
_cleanup_free_ uint8_t *p = NULL;
|
||||||
uint32_t enterprise_identifier;
|
uint32_t enterprise_identifier;
|
||||||
size_t total, offset;
|
size_t total, offset;
|
||||||
char **s;
|
char * const *s;
|
||||||
|
|
||||||
assert(buf);
|
assert(buf);
|
||||||
assert(*buf);
|
assert(*buf);
|
||||||
assert(buflen);
|
assert(buflen);
|
||||||
assert(vendor_class);
|
assert(!strv_isempty(vendor_class));
|
||||||
|
|
||||||
enterprise_identifier = htobe32(SYSTEMD_PEN);
|
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);
|
size_t len = strlen(*s);
|
||||||
uint8_t *q;
|
uint8_t *q;
|
||||||
|
|
||||||
|
if (len > UINT16_MAX || len == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
q = realloc(p, total + len + 2);
|
q = realloc(p, total + len + 2);
|
||||||
if (!q)
|
if (!q)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -566,22 +566,26 @@ int sd_dhcp_client_set_mud_url(
|
|||||||
|
|
||||||
int sd_dhcp_client_set_user_class(
|
int sd_dhcp_client_set_user_class(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
const char* const* user_class) {
|
char * const *user_class) {
|
||||||
|
|
||||||
_cleanup_strv_free_ char **s = NULL;
|
char * const *p;
|
||||||
char **p;
|
char **s = NULL;
|
||||||
|
|
||||||
STRV_FOREACH(p, (char **) user_class)
|
assert_return(client, -EINVAL);
|
||||||
if (strlen(*p) > 255)
|
assert_return(!strv_isempty(user_class), -EINVAL);
|
||||||
return -ENAMETOOLONG;
|
|
||||||
|
|
||||||
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)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
client->user_class = TAKE_PTR(s);
|
return strv_free_and_replace(client->user_class, s);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp_client_set_client_port(
|
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);
|
return free_and_strdup(&client->mudurl, mudurl);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp6_client_set_request_user_class(sd_dhcp6_client *client, char **user_class) {
|
int sd_dhcp6_client_set_request_user_class(sd_dhcp6_client *client, char * const *user_class) {
|
||||||
_cleanup_strv_free_ char **s = NULL;
|
char * const *p;
|
||||||
char **p;
|
char **s;
|
||||||
|
|
||||||
assert_return(client, -EINVAL);
|
assert_return(client, -EINVAL);
|
||||||
assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
|
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 (len > UINT16_MAX || len == 0)
|
||||||
if (strlen(*p) > UINT16_MAX)
|
return -EINVAL;
|
||||||
return -ENAMETOOLONG;
|
}
|
||||||
|
|
||||||
s = strv_copy(user_class);
|
s = strv_copy(user_class);
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
client->user_class = TAKE_PTR(s);
|
return strv_free_and_replace(client->user_class, s);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp6_client_set_request_vendor_class(sd_dhcp6_client *client, char **vendor_class) {
|
int sd_dhcp6_client_set_request_vendor_class(sd_dhcp6_client *client, char * const *vendor_class) {
|
||||||
_cleanup_strv_free_ char **s = NULL;
|
char * const *p;
|
||||||
char **p;
|
char **s;
|
||||||
|
|
||||||
assert_return(client, -EINVAL);
|
assert_return(client, -EINVAL);
|
||||||
assert_return(client->state == DHCP6_STATE_STOPPED, -EBUSY);
|
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)
|
STRV_FOREACH(p, vendor_class) {
|
||||||
if (strlen(*p) > UINT8_MAX)
|
size_t len = strlen(*p);
|
||||||
return -ENAMETOOLONG;
|
|
||||||
|
if (len > UINT16_MAX || len == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
s = strv_copy(vendor_class);
|
s = strv_copy(vendor_class);
|
||||||
if (!s)
|
if (!s)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
client->vendor_class = TAKE_PTR(s);
|
return strv_free_and_replace(client->vendor_class, s);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sd_dhcp6_client_get_prefix_delegation(sd_dhcp6_client *client, int *delegation) {
|
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);
|
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;
|
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);
|
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;
|
return r;
|
||||||
|
|
||||||
*ret = TAKE_PTR(c);
|
*ret = TAKE_PTR(c);
|
||||||
|
@ -603,13 +603,15 @@ _public_ int sd_bus_set_property(
|
|||||||
return r;
|
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;
|
sd_bus_creds *c;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert_return(call, -EINVAL);
|
assert_return(call, -EINVAL);
|
||||||
assert_return(call->sealed, -EPERM);
|
assert_return(call->sealed, -EPERM);
|
||||||
assert_return(call->bus, -EINVAL);
|
assert_return(call->bus, -EINVAL);
|
||||||
assert_return(!bus_pid_changed(call->bus), -ECHILD);
|
assert_return(!bus_pid_changed(call->bus), -ECHILD);
|
||||||
|
assert_return(ret, -EINVAL);
|
||||||
|
|
||||||
if (!BUS_IS_OPEN(call->bus->state))
|
if (!BUS_IS_OPEN(call->bus->state))
|
||||||
return -ENOTCONN;
|
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? */
|
/* All data we need? */
|
||||||
if (c && (mask & ~c->mask) == 0) {
|
if (c && (mask & ~c->mask) == 0) {
|
||||||
*creds = sd_bus_creds_ref(c);
|
*ret = sd_bus_creds_ref(c);
|
||||||
return 0;
|
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)
|
if (call->sender)
|
||||||
/* There's a sender, but the creds are missing. */
|
/* 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
|
else
|
||||||
/* There's no sender. For direct connections
|
/* There's no sender. For direct connections
|
||||||
* the credentials of the AF_UNIX peer matter,
|
* the credentials of the AF_UNIX peer matter,
|
||||||
* which may be queried via sd_bus_get_owner_creds(). */
|
* 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) {
|
_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;;) {
|
for (const char *p = value;;) {
|
||||||
_cleanup_free_ char *word = NULL;
|
_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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
|
@ -1518,30 +1518,6 @@ _public_ const char *sd_device_get_devlink_next(sd_device *device) {
|
|||||||
return v;
|
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 device_properties_prepare(sd_device *device) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -1557,46 +1533,39 @@ int device_properties_prepare(sd_device *device) {
|
|||||||
|
|
||||||
if (device->property_devlinks_outdated) {
|
if (device->property_devlinks_outdated) {
|
||||||
_cleanup_free_ char *devlinks = NULL;
|
_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)) {
|
r = set_strjoin(device->devlinks, " ", false, &devlinks);
|
||||||
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);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
if (!isempty(devlinks)) {
|
||||||
|
r = device_add_property_internal(device, "DEVLINKS", devlinks);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
device->property_devlinks_outdated = false;
|
device->property_devlinks_outdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device->property_tags_outdated) {
|
if (device->property_tags_outdated) {
|
||||||
_cleanup_free_ char *tags = NULL;
|
_cleanup_free_ char *tags = NULL;
|
||||||
|
|
||||||
tags = join_string_set(device->all_tags);
|
r = set_strjoin(device->all_tags, ":", true, &tags);
|
||||||
if (!tags)
|
if (r < 0)
|
||||||
return -ENOMEM;
|
return r;
|
||||||
|
|
||||||
if (!streq(tags, ":")) {
|
if (!isempty(tags)) {
|
||||||
r = device_add_property_internal(device, "TAGS", tags);
|
r = device_add_property_internal(device, "TAGS", tags);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(tags);
|
tags = mfree(tags);
|
||||||
tags = join_string_set(device->current_tags);
|
r = set_strjoin(device->current_tags, ":", true, &tags);
|
||||||
if (!tags)
|
if (r < 0)
|
||||||
return -ENOMEM;
|
return r;
|
||||||
|
|
||||||
if (!streq(tags, ":")) {
|
if (!isempty(tags)) {
|
||||||
r = device_add_property_internal(device, "CURRENT_TAGS", tags);
|
r = device_add_property_internal(device, "CURRENT_TAGS", tags);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -112,68 +112,74 @@ static void test_login(void) {
|
|||||||
|
|
||||||
if (session) {
|
if (session) {
|
||||||
r = sd_session_is_active(session);
|
r = sd_session_is_active(session);
|
||||||
assert_se(r >= 0);
|
if (r == -ENXIO)
|
||||||
log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
|
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);
|
||||||
assert_se(r >= 0);
|
log_info("sd_session_is_active(\"%s\") → %s", session, yes_no(r));
|
||||||
log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
|
|
||||||
|
|
||||||
r = sd_session_get_state(session, &state);
|
r = sd_session_is_remote(session);
|
||||||
assert_se(r == 0);
|
assert_se(r >= 0);
|
||||||
log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
|
log_info("sd_session_is_remote(\"%s\") → %s", session, yes_no(r));
|
||||||
|
|
||||||
assert_se(sd_session_get_uid(session, &u) >= 0);
|
r = sd_session_get_state(session, &state);
|
||||||
log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
|
assert_se(r == 0);
|
||||||
assert_se(u == u2);
|
log_info("sd_session_get_state(\"%s\") → \"%s\"", session, state);
|
||||||
|
|
||||||
assert_se(sd_session_get_type(session, &type) >= 0);
|
assert_se(sd_session_get_uid(session, &u) >= 0);
|
||||||
log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
|
log_info("sd_session_get_uid(\"%s\") → "UID_FMT, session, u);
|
||||||
|
assert_se(u == u2);
|
||||||
|
|
||||||
assert_se(sd_session_get_class(session, &class) >= 0);
|
assert_se(sd_session_get_type(session, &type) >= 0);
|
||||||
log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
|
log_info("sd_session_get_type(\"%s\") → \"%s\"", session, type);
|
||||||
|
|
||||||
r = sd_session_get_display(session, &display);
|
assert_se(sd_session_get_class(session, &class) >= 0);
|
||||||
assert_se(IN_SET(r, 0, -ENODATA));
|
log_info("sd_session_get_class(\"%s\") → \"%s\"", session, class);
|
||||||
log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
|
|
||||||
|
|
||||||
r = sd_session_get_remote_user(session, &remote_user);
|
r = sd_session_get_display(session, &display);
|
||||||
assert_se(IN_SET(r, 0, -ENODATA));
|
assert_se(IN_SET(r, 0, -ENODATA));
|
||||||
log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
|
log_info("sd_session_get_display(\"%s\") → \"%s\"", session, strna(display));
|
||||||
session, strna(remote_user));
|
|
||||||
|
|
||||||
r = sd_session_get_remote_host(session, &remote_host);
|
r = sd_session_get_remote_user(session, &remote_user);
|
||||||
assert_se(IN_SET(r, 0, -ENODATA));
|
assert_se(IN_SET(r, 0, -ENODATA));
|
||||||
log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
|
log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
|
||||||
session, strna(remote_host));
|
session, strna(remote_user));
|
||||||
|
|
||||||
r = sd_session_get_seat(session, &seat);
|
r = sd_session_get_remote_host(session, &remote_host);
|
||||||
if (r >= 0) {
|
assert_se(IN_SET(r, 0, -ENODATA));
|
||||||
assert_se(seat);
|
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 push
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
r = sd_seat_can_multi_session(seat);
|
r = sd_seat_can_multi_session(seat);
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
assert_se(r == 1);
|
assert_se(r == 1);
|
||||||
log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
|
log_info("sd_session_can_multi_seat(\"%s\") → %s", seat, yes_no(r));
|
||||||
|
|
||||||
r = sd_seat_can_tty(seat);
|
r = sd_seat_can_tty(seat);
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
|
log_info("sd_session_can_tty(\"%s\") → %s", seat, yes_no(r));
|
||||||
|
|
||||||
r = sd_seat_can_graphical(seat);
|
r = sd_seat_can_graphical(seat);
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
|
log_info("sd_session_can_graphical(\"%s\") → %s", seat, yes_no(r));
|
||||||
} else {
|
} else {
|
||||||
log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session);
|
log_info_errno(r, "sd_session_get_seat(\"%s\"): %m", session);
|
||||||
assert_se(r == -ENODATA);
|
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) {
|
if (seat) {
|
||||||
@ -214,7 +220,7 @@ static void test_login(void) {
|
|||||||
assert_se(sd_get_seats(NULL) == r);
|
assert_se(sd_get_seats(NULL) == r);
|
||||||
|
|
||||||
r = sd_seat_get_active(NULL, &t, NULL);
|
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));
|
log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r), strnull(t));
|
||||||
free(t);
|
free(t);
|
||||||
|
|
||||||
|
@ -532,6 +532,7 @@ int config_parse_dhcp_user_class(
|
|||||||
|
|
||||||
for (const char *p = rvalue;;) {
|
for (const char *p = rvalue;;) {
|
||||||
_cleanup_free_ char *w = NULL;
|
_cleanup_free_ char *w = NULL;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
r = extract_first_word(&p, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
|
r = extract_first_word(&p, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
|
||||||
if (r == -ENOMEM)
|
if (r == -ENOMEM)
|
||||||
@ -544,25 +545,24 @@ int config_parse_dhcp_user_class(
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
len = strlen(w);
|
||||||
if (ltype == AF_INET) {
|
if (ltype == AF_INET) {
|
||||||
if (strlen(w) > UINT8_MAX) {
|
if (len > UINT8_MAX || len == 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
"%s length is not in the range 1-255, ignoring.", w);
|
"%s length is not in the range 1-255, ignoring.", w);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (strlen(w) > UINT16_MAX) {
|
if (len > UINT16_MAX || len == 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
"%s length is not in the range 1-65535, ignoring.", w);
|
"%s length is not in the range 1-65535, ignoring.", w);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
r = strv_push(l, w);
|
r = strv_consume(l, TAKE_PTR(w));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
w = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1452,7 +1452,7 @@ int dhcp4_configure(Link *link) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (link->network->dhcp_user_class) {
|
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)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "DHCP4 CLIENT: Failed to set user class: %m");
|
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)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not create RTM_NEWNEIGH message: %m");
|
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)
|
if (r < 0)
|
||||||
return log_link_error_errno(link, r, "Could not set neighbor flags: %m");
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
rule->manager = m;
|
|
||||||
|
|
||||||
r = routing_policy_rule_copy(rule, in);
|
r = routing_policy_rule_copy(rule, in);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -322,6 +320,8 @@ static int routing_policy_rule_add_internal(Manager *m, Set **rules, RoutingPoli
|
|||||||
if (r == 0)
|
if (r == 0)
|
||||||
return -EEXIST;
|
return -EEXIST;
|
||||||
|
|
||||||
|
rule->manager = m;
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = rule;
|
*ret = rule;
|
||||||
|
|
||||||
|
@ -100,6 +100,10 @@ static int link_set_ipv6_privacy_extensions(Link *link) {
|
|||||||
if (!link->network)
|
if (!link->network)
|
||||||
return 0;
|
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);
|
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);
|
r = link_set_ipv6_privacy_extensions(link);
|
||||||
if (r < 0)
|
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);
|
r = link_set_ipv6_accept_ra(link);
|
||||||
if (r < 0)
|
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);
|
n = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
|
||||||
if (IN_SET(n, -EAGAIN, -EINTR))
|
if (IN_SET(n, -EAGAIN, -EINTR))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (n == -EXFULL) {
|
||||||
|
log_warning("Got message with truncated control data (too many fds sent?), ignoring.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
return log_warning_errno(n, "Couldn't read notification socket: %m");
|
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;
|
return -ENOMEM;
|
||||||
|
|
||||||
*c = (DnsQueryCandidate) {
|
*c = (DnsQueryCandidate) {
|
||||||
|
.n_ref = 1,
|
||||||
.query = q,
|
.query = q,
|
||||||
.scope = s,
|
.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)
|
if (!c)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -68,8 +68,10 @@ DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c) {
|
|||||||
return mfree(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) {
|
static int dns_query_candidate_next_search_domain(DnsQueryCandidate *c) {
|
||||||
DnsSearchDomain *next = NULL;
|
DnsSearchDomain *next;
|
||||||
|
|
||||||
assert(c);
|
assert(c);
|
||||||
|
|
||||||
@ -130,12 +132,16 @@ static int dns_query_candidate_add_transaction(DnsQueryCandidate *c, DnsResource
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int dns_query_candidate_go(DnsQueryCandidate *c) {
|
static int dns_query_candidate_go(DnsQueryCandidate *c) {
|
||||||
|
_cleanup_(dns_query_candidate_unrefp) DnsQueryCandidate *keep_c = NULL;
|
||||||
DnsTransaction *t;
|
DnsTransaction *t;
|
||||||
int r;
|
int r;
|
||||||
unsigned n = 0;
|
unsigned n = 0;
|
||||||
|
|
||||||
assert(c);
|
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 */
|
/* Start the transactions that are not started yet */
|
||||||
SET_FOREACH(t, c->transactions) {
|
SET_FOREACH(t, c->transactions) {
|
||||||
if (t->state != DNS_TRANSACTION_NULL)
|
if (t->state != DNS_TRANSACTION_NULL)
|
||||||
@ -297,11 +303,11 @@ static void dns_query_stop(DnsQuery *q) {
|
|||||||
dns_query_candidate_stop(c);
|
dns_query_candidate_stop(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dns_query_free_candidates(DnsQuery *q) {
|
static void dns_query_unref_candidates(DnsQuery *q) {
|
||||||
assert(q);
|
assert(q);
|
||||||
|
|
||||||
while (q->candidates)
|
while (q->candidates)
|
||||||
dns_query_candidate_free(q->candidates);
|
dns_query_candidate_unref(q->candidates);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dns_query_reset_answer(DnsQuery *q) {
|
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);
|
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_idna);
|
||||||
dns_question_unref(q->question_utf8);
|
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) {
|
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;
|
int r;
|
||||||
|
|
||||||
assert(q);
|
assert(q);
|
||||||
@ -592,8 +598,8 @@ static int dns_query_try_etc_hosts(DnsQuery *q) {
|
|||||||
|
|
||||||
assert(q);
|
assert(q);
|
||||||
|
|
||||||
/* Looks in /etc/hosts for matching entries. Note that this is done *before* the normal lookup is done. The
|
/* Looks in /etc/hosts for matching entries. Note that this is done *before* the normal lookup is
|
||||||
* data from /etc/hosts hence takes precedence over the network. */
|
* done. The data from /etc/hosts hence takes precedence over the network. */
|
||||||
|
|
||||||
r = manager_etc_hosts_lookup(
|
r = manager_etc_hosts_lookup(
|
||||||
q->manager,
|
q->manager,
|
||||||
@ -926,7 +932,7 @@ static int dns_query_cname_redirect(DnsQuery *q, const DnsResourceRecord *cname)
|
|||||||
dns_question_unref(q->question_utf8);
|
dns_question_unref(q->question_utf8);
|
||||||
q->question_utf8 = TAKE_PTR(nq_utf8);
|
q->question_utf8 = TAKE_PTR(nq_utf8);
|
||||||
|
|
||||||
dns_query_free_candidates(q);
|
dns_query_unref_candidates(q);
|
||||||
dns_query_reset_answer(q);
|
dns_query_reset_answer(q);
|
||||||
|
|
||||||
q->state = DNS_TRANSACTION_NULL;
|
q->state = DNS_TRANSACTION_NULL;
|
||||||
|
@ -16,12 +16,14 @@ typedef struct DnsStubListenerExtra DnsStubListenerExtra;
|
|||||||
#include "resolved-dns-transaction.h"
|
#include "resolved-dns-transaction.h"
|
||||||
|
|
||||||
struct DnsQueryCandidate {
|
struct DnsQueryCandidate {
|
||||||
|
unsigned n_ref;
|
||||||
|
int error_code;
|
||||||
|
|
||||||
DnsQuery *query;
|
DnsQuery *query;
|
||||||
DnsScope *scope;
|
DnsScope *scope;
|
||||||
|
|
||||||
DnsSearchDomain *search_domain;
|
DnsSearchDomain *search_domain;
|
||||||
|
|
||||||
int error_code;
|
|
||||||
Set *transactions;
|
Set *transactions;
|
||||||
|
|
||||||
LIST_FIELDS(DnsQueryCandidate, candidates_by_query);
|
LIST_FIELDS(DnsQueryCandidate, candidates_by_query);
|
||||||
@ -31,19 +33,19 @@ struct DnsQueryCandidate {
|
|||||||
struct DnsQuery {
|
struct DnsQuery {
|
||||||
Manager *manager;
|
Manager *manager;
|
||||||
|
|
||||||
/* When resolving a service, we first create a TXT+SRV query,
|
/* When resolving a service, we first create a TXT+SRV query, and then for the hostnames we discover
|
||||||
* and then for the hostnames we discover auxiliary A+AAAA
|
* auxiliary A+AAAA queries. This pointer always points from the auxiliary queries back to the
|
||||||
* queries. This pointer always points from the auxiliary
|
* TXT+SRV query. */
|
||||||
* queries back to the TXT+SRV query. */
|
|
||||||
DnsQuery *auxiliary_for;
|
DnsQuery *auxiliary_for;
|
||||||
LIST_HEAD(DnsQuery, auxiliary_queries);
|
LIST_HEAD(DnsQuery, auxiliary_queries);
|
||||||
unsigned n_auxiliary_queries;
|
unsigned n_auxiliary_queries;
|
||||||
int auxiliary_result;
|
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
|
/* The question, formatted in IDNA for use on classic DNS, and as UTF8 for use in LLMNR or mDNS. Note
|
||||||
* on classic DNS some labels might use UTF8 encoding. Specifically, DNS-SD service names (in contrast to their
|
* that even on classic DNS some labels might use UTF8 encoding. Specifically, DNS-SD service names
|
||||||
* domain suffixes) use UTF-8 encoding even on DNS. Thus, the difference between these two fields is mostly
|
* (in contrast to their domain suffixes) use UTF-8 encoding even on DNS. Thus, the difference
|
||||||
* relevant only for explicit *hostname* lookups as well as the domain suffixes of service lookups. */
|
* 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_idna;
|
||||||
DnsQuestion *question_utf8;
|
DnsQuestion *question_utf8;
|
||||||
|
|
||||||
@ -101,8 +103,9 @@ enum {
|
|||||||
DNS_QUERY_RESTARTED,
|
DNS_QUERY_RESTARTED,
|
||||||
};
|
};
|
||||||
|
|
||||||
DnsQueryCandidate* dns_query_candidate_free(DnsQueryCandidate *c);
|
DnsQueryCandidate* dns_query_candidate_ref(DnsQueryCandidate*);
|
||||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryCandidate*, dns_query_candidate_free);
|
DnsQueryCandidate* dns_query_candidate_unref(DnsQueryCandidate*);
|
||||||
|
DEFINE_TRIVIAL_CLEANUP_FUNC(DnsQueryCandidate*, dns_query_candidate_unref);
|
||||||
|
|
||||||
void dns_query_candidate_notify(DnsQueryCandidate *c);
|
void dns_query_candidate_notify(DnsQueryCandidate *c);
|
||||||
|
|
||||||
|
@ -1373,7 +1373,7 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *
|
|||||||
DnsTxtItem *j;
|
DnsTxtItem *j;
|
||||||
|
|
||||||
LIST_FOREACH(items, j, rr->txt.items) {
|
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"
|
/* Add an extra NUL byte, so that "a" followed by "b" doesn't result in the same hash as "ab"
|
||||||
* followed by "". */
|
* followed by "". */
|
||||||
@ -1418,14 +1418,14 @@ void dns_resource_record_hash_func(const DnsResourceRecord *rr, struct siphash *
|
|||||||
case DNS_TYPE_SSHFP:
|
case DNS_TYPE_SSHFP:
|
||||||
siphash24_compress(&rr->sshfp.algorithm, sizeof(rr->sshfp.algorithm), state);
|
siphash24_compress(&rr->sshfp.algorithm, sizeof(rr->sshfp.algorithm), state);
|
||||||
siphash24_compress(&rr->sshfp.fptype, sizeof(rr->sshfp.fptype), 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;
|
break;
|
||||||
|
|
||||||
case DNS_TYPE_DNSKEY:
|
case DNS_TYPE_DNSKEY:
|
||||||
siphash24_compress(&rr->dnskey.flags, sizeof(rr->dnskey.flags), state);
|
siphash24_compress(&rr->dnskey.flags, sizeof(rr->dnskey.flags), state);
|
||||||
siphash24_compress(&rr->dnskey.protocol, sizeof(rr->dnskey.protocol), 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.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;
|
break;
|
||||||
|
|
||||||
case DNS_TYPE_RRSIG:
|
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.inception, sizeof(rr->rrsig.inception), state);
|
||||||
siphash24_compress(&rr->rrsig.key_tag, sizeof(rr->rrsig.key_tag), state);
|
siphash24_compress(&rr->rrsig.key_tag, sizeof(rr->rrsig.key_tag), state);
|
||||||
dns_name_hash_func(rr->rrsig.signer, 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;
|
break;
|
||||||
|
|
||||||
case DNS_TYPE_NSEC:
|
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.key_tag, sizeof(rr->ds.key_tag), state);
|
||||||
siphash24_compress(&rr->ds.algorithm, sizeof(rr->ds.algorithm), 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_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;
|
break;
|
||||||
|
|
||||||
case DNS_TYPE_NSEC3:
|
case DNS_TYPE_NSEC3:
|
||||||
siphash24_compress(&rr->nsec3.algorithm, sizeof(rr->nsec3.algorithm), state);
|
siphash24_compress(&rr->nsec3.algorithm, sizeof(rr->nsec3.algorithm), state);
|
||||||
siphash24_compress(&rr->nsec3.flags, sizeof(rr->nsec3.flags), 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.iterations, sizeof(rr->nsec3.iterations), state);
|
||||||
siphash24_compress(rr->nsec3.salt, rr->nsec3.salt_size, state);
|
siphash24_compress_safe(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.next_hashed_name, rr->nsec3.next_hashed_name_size, state);
|
||||||
/* FIXME: We leave the bitmaps out */
|
/* FIXME: We leave the bitmaps out */
|
||||||
break;
|
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.cert_usage, sizeof(rr->tlsa.cert_usage), state);
|
||||||
siphash24_compress(&rr->tlsa.selector, sizeof(rr->tlsa.selector), 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.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;
|
break;
|
||||||
|
|
||||||
case DNS_TYPE_CAA:
|
case DNS_TYPE_CAA:
|
||||||
siphash24_compress(&rr->caa.flags, sizeof(rr->caa.flags), state);
|
siphash24_compress(&rr->caa.flags, sizeof(rr->caa.flags), state);
|
||||||
string_hash_func(rr->caa.tag, 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;
|
break;
|
||||||
|
|
||||||
case DNS_TYPE_OPENPGPKEY:
|
case DNS_TYPE_OPENPGPKEY:
|
||||||
default:
|
default:
|
||||||
siphash24_compress(rr->generic.data, rr->generic.data_size, state);
|
siphash24_compress_safe(rr->generic.data, rr->generic.data_size, state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ DnsScope* dns_scope_free(DnsScope *s) {
|
|||||||
dns_scope_abort_transactions(s);
|
dns_scope_abort_transactions(s);
|
||||||
|
|
||||||
while (s->query_candidates)
|
while (s->query_candidates)
|
||||||
dns_query_candidate_free(s->query_candidates);
|
dns_query_candidate_unref(s->query_candidates);
|
||||||
|
|
||||||
hashmap_free(s->transactions_by_key);
|
hashmap_free(s->transactions_by_key);
|
||||||
|
|
||||||
|
@ -152,8 +152,8 @@ bool dns_transaction_gc(DnsTransaction *t) {
|
|||||||
static uint16_t pick_new_id(Manager *m) {
|
static uint16_t pick_new_id(Manager *m) {
|
||||||
uint16_t new_id;
|
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
|
/* Find a fresh, unused transaction id. Note that this loop is bounded because there's a limit on the
|
||||||
* transactions, and it's much lower than the space of IDs. */
|
* number of transactions, and it's much lower than the space of IDs. */
|
||||||
|
|
||||||
assert_cc(TRANSACTIONS_MAX < 0xFFFF);
|
assert_cc(TRANSACTIONS_MAX < 0xFFFF);
|
||||||
|
|
||||||
@ -1338,6 +1338,10 @@ static int dns_transaction_prepare(DnsTransaction *t, usec_t ts) {
|
|||||||
|
|
||||||
assert(t);
|
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);
|
dns_transaction_stop_timeout(t);
|
||||||
|
|
||||||
if (!dns_scope_network_good(t->scope)) {
|
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) {
|
static int dns_transaction_make_packet_mdns(DnsTransaction *t) {
|
||||||
|
|
||||||
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
|
_cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
|
||||||
bool add_known_answers = false;
|
bool add_known_answers = false;
|
||||||
DnsTransaction *other;
|
DnsTransaction *other;
|
||||||
@ -1633,8 +1636,9 @@ int dns_transaction_go(DnsTransaction *t) {
|
|||||||
|
|
||||||
assert(t);
|
assert(t);
|
||||||
|
|
||||||
/* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has finished
|
/* Returns > 0 if the transaction is now pending, returns 0 if could be processed immediately and has
|
||||||
* now. */
|
* 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);
|
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;
|
t->state = DNS_TRANSACTION_PENDING;
|
||||||
|
|
||||||
log_debug("Delaying %s transaction for " USEC_FMT "us.", dns_protocol_to_string(t->scope->protocol), jitter);
|
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 */
|
/* Otherwise, we need to ask the network */
|
||||||
|
@ -943,6 +943,10 @@ int ask_password_agent(
|
|||||||
n = recvmsg_safe(socket_fd, &msghdr, 0);
|
n = recvmsg_safe(socket_fd, &msghdr, 0);
|
||||||
if (IN_SET(n, -EAGAIN, -EINTR))
|
if (IN_SET(n, -EAGAIN, -EINTR))
|
||||||
continue;
|
continue;
|
||||||
|
if (n == -EXFULL) {
|
||||||
|
log_debug("Got message with truncated control data, ignoring.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
r = (int) n;
|
r = (int) n;
|
||||||
goto finish;
|
goto finish;
|
||||||
|
@ -76,15 +76,18 @@ int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
attr = (union bpf_attr) {
|
// FIXME: Clang doesn't 0-pad with structured initialization, causing
|
||||||
.prog_type = p->prog_type,
|
// the kernel to reject the bpf_attr as invalid. See:
|
||||||
.insns = PTR_TO_UINT64(p->instructions),
|
// https://github.com/torvalds/linux/blob/v5.9/kernel/bpf/syscall.c#L65
|
||||||
.insn_cnt = p->n_instructions,
|
// Ideally it should behave like GCC, so that we can remove these workarounds.
|
||||||
.license = PTR_TO_UINT64("GPL"),
|
zero(attr);
|
||||||
.log_buf = PTR_TO_UINT64(log_buf),
|
attr.prog_type = p->prog_type;
|
||||||
.log_level = !!log_buf,
|
attr.insns = PTR_TO_UINT64(p->instructions);
|
||||||
.log_size = log_size,
|
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));
|
p->kernel_fd = bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
|
||||||
if (p->kernel_fd < 0)
|
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 */
|
if (p->kernel_fd >= 0) /* don't overwrite an assembled or loaded program */
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
attr = (union bpf_attr) {
|
zero(attr);
|
||||||
.pathname = PTR_TO_UINT64(path),
|
attr.pathname = PTR_TO_UINT64(path);
|
||||||
};
|
|
||||||
|
|
||||||
p->kernel_fd = bpf(BPF_OBJ_GET, &attr, sizeof(attr));
|
p->kernel_fd = bpf(BPF_OBJ_GET, &attr, sizeof(attr));
|
||||||
if (p->kernel_fd < 0)
|
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)
|
if (fd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
attr = (union bpf_attr) {
|
zero(attr);
|
||||||
.attach_type = type,
|
attr.attach_type = type;
|
||||||
.target_fd = fd,
|
attr.target_fd = fd;
|
||||||
.attach_bpf_fd = p->kernel_fd,
|
attr.attach_bpf_fd = p->kernel_fd;
|
||||||
.attach_flags = flags,
|
attr.attach_flags = flags;
|
||||||
};
|
|
||||||
|
|
||||||
if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0)
|
if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
@ -194,11 +195,10 @@ int bpf_program_cgroup_detach(BPFProgram *p) {
|
|||||||
} else {
|
} else {
|
||||||
union bpf_attr attr;
|
union bpf_attr attr;
|
||||||
|
|
||||||
attr = (union bpf_attr) {
|
zero(attr);
|
||||||
.attach_type = p->attached_type,
|
attr.attach_type = p->attached_type;
|
||||||
.target_fd = fd,
|
attr.target_fd = fd;
|
||||||
.attach_bpf_fd = p->kernel_fd,
|
attr.attach_bpf_fd = p->kernel_fd;
|
||||||
};
|
|
||||||
|
|
||||||
if (bpf(BPF_PROG_DETACH, &attr, sizeof(attr)) < 0)
|
if (bpf(BPF_PROG_DETACH, &attr, sizeof(attr)) < 0)
|
||||||
return -errno;
|
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) {
|
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 = {
|
union bpf_attr attr;
|
||||||
.map_type = type,
|
|
||||||
.key_size = key_size,
|
|
||||||
.value_size = value_size,
|
|
||||||
.max_entries = max_entries,
|
|
||||||
.map_flags = flags,
|
|
||||||
};
|
|
||||||
int fd;
|
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));
|
fd = bpf(BPF_MAP_CREATE, &attr, sizeof(attr));
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
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) {
|
int bpf_map_update_element(int fd, const void *key, void *value) {
|
||||||
|
union bpf_attr attr;
|
||||||
|
|
||||||
union bpf_attr attr = {
|
zero(attr);
|
||||||
.map_fd = fd,
|
attr.map_fd = fd;
|
||||||
.key = PTR_TO_UINT64(key),
|
attr.key = PTR_TO_UINT64(key);
|
||||||
.value = PTR_TO_UINT64(value),
|
attr.value = PTR_TO_UINT64(value);
|
||||||
};
|
|
||||||
|
|
||||||
if (bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)) < 0)
|
if (bpf(BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr)) < 0)
|
||||||
return -errno;
|
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) {
|
int bpf_map_lookup_element(int fd, const void *key, void *value) {
|
||||||
|
union bpf_attr attr;
|
||||||
|
|
||||||
union bpf_attr attr = {
|
zero(attr);
|
||||||
.map_fd = fd,
|
attr.map_fd = fd;
|
||||||
.key = PTR_TO_UINT64(key),
|
attr.key = PTR_TO_UINT64(key);
|
||||||
.value = PTR_TO_UINT64(value),
|
attr.value = PTR_TO_UINT64(value);
|
||||||
};
|
|
||||||
|
|
||||||
if (bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)) < 0)
|
if (bpf(BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr)) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "sd-bus.h"
|
#include "sd-bus.h"
|
||||||
#include "sd-event.h"
|
#include "sd-event.h"
|
||||||
|
|
||||||
|
#include "errno-util.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "time-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);
|
int bus_connect_transport_systemd(BusTransport transport, const char *host, bool user, sd_bus **bus);
|
||||||
|
|
||||||
#define bus_log_address_error(r) \
|
#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" : \
|
int _k = (r); \
|
||||||
"Failed to set bus address: %m")
|
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) \
|
#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" : \
|
int _k = (r); \
|
||||||
"Failed to connect to bus: %m")
|
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) \
|
#define bus_log_parse_error(r) \
|
||||||
log_error_errno(r, "Failed to parse bus message: %m")
|
log_error_errno(r, "Failed to parse bus message: %m")
|
||||||
|
@ -6,6 +6,14 @@
|
|||||||
#if HAVE_LIBCRYPTSETUP
|
#if HAVE_LIBCRYPTSETUP
|
||||||
#include <libcryptsetup.h>
|
#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);
|
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
|
#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);
|
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) {
|
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);
|
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)
|
if (r < 0 && r != -ENOENT)
|
||||||
|
@ -1277,7 +1277,7 @@ int dns_name_apply_idna(const char *name, char **ret) {
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
r = dlopen_idn();
|
r = dlopen_idn();
|
||||||
if (r == EOPNOTSUPP) {
|
if (r == -EOPNOTSUPP) {
|
||||||
*ret = NULL;
|
*ret = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -334,6 +334,16 @@ int journal_importer_process_data(JournalImporter *imp) {
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} 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 = */
|
/* replace \n with = */
|
||||||
line[n-1] = '=';
|
line[n-1] = '=';
|
||||||
|
|
||||||
|
@ -137,41 +137,3 @@ int journal_access_check_and_warn(sd_journal *j, bool quiet, bool want_other_use
|
|||||||
|
|
||||||
return r;
|
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"
|
#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_blocked(sd_journal *j);
|
||||||
int journal_access_check_and_warn(sd_journal *j, bool quiet, bool want_other_users);
|
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);
|
c = memchr(data, '=', length);
|
||||||
if (!c)
|
if (!c)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field.");
|
||||||
"Invalid field.");
|
|
||||||
fieldlen = 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);
|
r = field_set_test(output_fields, data, fieldlen);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -798,6 +800,7 @@ static int output_export(
|
|||||||
sd_id128_to_string(boot_id, sid));
|
sd_id128_to_string(boot_id, sid));
|
||||||
|
|
||||||
JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
|
JOURNAL_FOREACH_DATA_RETVAL(j, data, length, r) {
|
||||||
|
size_t fieldlen;
|
||||||
const char *c;
|
const char *c;
|
||||||
|
|
||||||
/* We already printed the boot id from the data in the header, hence let's suppress it here */
|
/* 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);
|
c = memchr(data, '=', length);
|
||||||
if (!c)
|
if (!c)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid field.");
|
||||||
"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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (!r)
|
if (!r)
|
||||||
@ -820,11 +826,11 @@ static int output_export(
|
|||||||
else {
|
else {
|
||||||
uint64_t le64;
|
uint64_t le64;
|
||||||
|
|
||||||
fwrite(data, c - (const char*) data, 1, f);
|
fwrite(data, fieldlen, 1, f);
|
||||||
fputc('\n', f);
|
fputc('\n', f);
|
||||||
le64 = htole64(length - (c - (const char*) data) - 1);
|
le64 = htole64(length - fieldlen - 1);
|
||||||
fwrite(&le64, sizeof(le64), 1, f);
|
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);
|
fputc('\n', f);
|
||||||
@ -961,6 +967,7 @@ static int update_json_data_split(
|
|||||||
const void *data,
|
const void *data,
|
||||||
size_t size) {
|
size_t size) {
|
||||||
|
|
||||||
|
size_t fieldlen;
|
||||||
const char *eq;
|
const char *eq;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
@ -974,14 +981,15 @@ static int update_json_data_split(
|
|||||||
if (!eq)
|
if (!eq)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (eq == data)
|
fieldlen = eq - (const char*) data;
|
||||||
return 0;
|
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))
|
if (output_fields && !set_contains(output_fields, name))
|
||||||
return 0;
|
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(
|
static int output_json(
|
||||||
|
@ -1,12 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||||
|
|
||||||
#include <net/ethernet.h>
|
|
||||||
#include <linux/nl80211.h>
|
|
||||||
|
|
||||||
#include "sd-bus.h"
|
|
||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "netlink-util.h"
|
|
||||||
#include "wifi-util.h"
|
#include "wifi-util.h"
|
||||||
|
|
||||||
int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftype, char **ssid) {
|
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)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to request information about wifi interface %d: %m", ifindex);
|
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;
|
goto nodata;
|
||||||
|
}
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(reply);
|
r = sd_netlink_message_get_errno(reply);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -62,8 +58,8 @@ int wifi_get_interface(sd_netlink *genl, int ifindex, enum nl80211_iftype *iftyp
|
|||||||
if (ssid) {
|
if (ssid) {
|
||||||
r = sd_netlink_message_read_string_strdup(reply, NL80211_ATTR_SSID, ssid);
|
r = sd_netlink_message_read_string_strdup(reply, NL80211_ATTR_SSID, ssid);
|
||||||
if (r == -ENODATA)
|
if (r == -ENODATA)
|
||||||
goto nodata;
|
*ssid = NULL;
|
||||||
if (r < 0)
|
else if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to get NL80211_ATTR_SSID attribute: %m");
|
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);
|
r = sd_netlink_call(genl, m, 0, &reply);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_debug_errno(r, "Failed to request information about wifi station: %m");
|
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;
|
goto nodata;
|
||||||
|
}
|
||||||
|
|
||||||
r = sd_netlink_message_get_errno(reply);
|
r = sd_netlink_message_get_errno(reply);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <linux/nl80211.h>
|
#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_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);
|
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
|
/* 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. */
|
* 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);
|
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)
|
if (r == -ERFKILL)
|
||||||
return log_error_errno(r, "Unit '%s' masked, cannot edit.", *name);
|
return log_error_errno(r, "Unit '%s' masked, cannot edit.", *name);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
if (r == 0) {
|
if (!path) {
|
||||||
assert(!path);
|
|
||||||
|
|
||||||
if (!arg_force) {
|
if (!arg_force) {
|
||||||
log_info("Run 'systemctl edit%s --force --full %s' to create a new unit.",
|
log_info("Run 'systemctl edit%s --force --full %s' to create a new unit.",
|
||||||
arg_scope == UNIT_FILE_GLOBAL ? " --global" :
|
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",
|
arg_full ? NULL : ".d/override.conf",
|
||||||
NULL, &new_path, &tmp_path);
|
NULL, &new_path, &tmp_path);
|
||||||
} else {
|
} else {
|
||||||
assert(path);
|
|
||||||
|
|
||||||
unit_name = basename(path);
|
unit_name = basename(path);
|
||||||
/* We follow unit aliases, but we need to propagate the instance */
|
/* We follow unit aliases, but we need to propagate the instance */
|
||||||
if (unit_name_is_valid(*name, UNIT_NAME_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)
|
if (r < 0)
|
||||||
return bus_log_parse_error(r);
|
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;
|
enabled = true;
|
||||||
|
|
||||||
if (!arg_quiet) {
|
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);
|
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);
|
r = sd_bus_message_append_strv(m, copy);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -139,21 +145,30 @@ int import_environment(int argc, char *argv[], void *userdata) {
|
|||||||
STRV_FOREACH(a, strv_skip(argv, 1)) {
|
STRV_FOREACH(a, strv_skip(argv, 1)) {
|
||||||
|
|
||||||
if (!env_name_is_valid(*a))
|
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) {
|
STRV_FOREACH(b, environ) {
|
||||||
const char *eq;
|
const char *eq;
|
||||||
|
|
||||||
eq = startswith(*b, *a);
|
eq = startswith(*b, *a);
|
||||||
if (eq && *eq == '=') {
|
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);
|
r = sd_bus_message_append(m, "s", *b);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return bus_log_create_error(r);
|
return bus_log_create_error(r);
|
||||||
|
|
||||||
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
log_notice("Environment variable $%s not set, ignoring.", *a);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sd_bus_message_close_container(m);
|
r = sd_bus_message_close_container(m);
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include "hexdecoct.h"
|
#include "hexdecoct.h"
|
||||||
#include "hostname-util.h"
|
#include "hostname-util.h"
|
||||||
#include "in-addr-util.h"
|
#include "in-addr-util.h"
|
||||||
#include "journal-util.h"
|
#include "journal-file.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "locale-util.h"
|
#include "locale-util.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
|
@ -179,7 +179,7 @@ int sd_dhcp_client_set_mud_url(
|
|||||||
const char *mudurl);
|
const char *mudurl);
|
||||||
int sd_dhcp_client_set_user_class(
|
int sd_dhcp_client_set_user_class(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
const char* const *user_class);
|
char * const *user_class);
|
||||||
int sd_dhcp_client_get_lease(
|
int sd_dhcp_client_get_lease(
|
||||||
sd_dhcp_client *client,
|
sd_dhcp_client *client,
|
||||||
sd_dhcp_lease **ret);
|
sd_dhcp_lease **ret);
|
||||||
|
@ -133,10 +133,10 @@ int sd_dhcp6_client_set_request_mud_url(
|
|||||||
const char *mudurl);
|
const char *mudurl);
|
||||||
int sd_dhcp6_client_set_request_user_class(
|
int sd_dhcp6_client_set_request_user_class(
|
||||||
sd_dhcp6_client *client,
|
sd_dhcp6_client *client,
|
||||||
char** user_class);
|
char * const *user_class);
|
||||||
int sd_dhcp6_client_set_request_vendor_class(
|
int sd_dhcp6_client_set_request_vendor_class(
|
||||||
sd_dhcp6_client *client,
|
sd_dhcp6_client *client,
|
||||||
char** vendor_class);
|
char * const *vendor_class);
|
||||||
int sd_dhcp6_client_set_prefix_delegation_hint(
|
int sd_dhcp6_client_set_prefix_delegation_hint(
|
||||||
sd_dhcp6_client *client,
|
sd_dhcp6_client *client,
|
||||||
uint8_t prefixlen,
|
uint8_t prefixlen,
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
#include "main-func.h"
|
#include "main-func.h"
|
||||||
#include "mount-util.h"
|
#include "mount-util.h"
|
||||||
|
#include "nscd-flush.h"
|
||||||
#include "pager.h"
|
#include "pager.h"
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "pretty-print.h"
|
#include "pretty-print.h"
|
||||||
@ -798,6 +799,9 @@ static int write_files(void) {
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
group_tmp = mfree(group_tmp);
|
group_tmp = mfree(group_tmp);
|
||||||
|
|
||||||
|
if (!arg_root && !arg_image)
|
||||||
|
(void) nscd_flush_cache(STRV_MAKE("group"));
|
||||||
}
|
}
|
||||||
if (gshadow) {
|
if (gshadow) {
|
||||||
r = rename_and_apply_smack_floor_label(gshadow_tmp, gshadow_path);
|
r = rename_and_apply_smack_floor_label(gshadow_tmp, gshadow_path);
|
||||||
@ -813,6 +817,9 @@ static int write_files(void) {
|
|||||||
return r;
|
return r;
|
||||||
|
|
||||||
passwd_tmp = mfree(passwd_tmp);
|
passwd_tmp = mfree(passwd_tmp);
|
||||||
|
|
||||||
|
if (!arg_root && !arg_image)
|
||||||
|
(void) nscd_flush_cache(STRV_MAKE("passwd"));
|
||||||
}
|
}
|
||||||
if (shadow) {
|
if (shadow) {
|
||||||
r = rename_and_apply_smack_floor_label(shadow_tmp, shadow_path);
|
r = rename_and_apply_smack_floor_label(shadow_tmp, shadow_path);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "bpf-program.h"
|
#include "bpf-program.h"
|
||||||
#include "load-fragment.h"
|
#include "load-fragment.h"
|
||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
|
#include "memory-util.h"
|
||||||
#include "rm-rf.h"
|
#include "rm-rf.h"
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
@ -77,11 +78,10 @@ int main(int argc, char *argv[]) {
|
|||||||
assert(r >= 0);
|
assert(r >= 0);
|
||||||
|
|
||||||
if (test_custom_filter) {
|
if (test_custom_filter) {
|
||||||
attr = (union bpf_attr) {
|
zero(attr);
|
||||||
.pathname = PTR_TO_UINT64(test_prog),
|
attr.pathname = PTR_TO_UINT64(test_prog);
|
||||||
.bpf_fd = p->kernel_fd,
|
attr.bpf_fd = p->kernel_fd;
|
||||||
.file_flags = 0,
|
attr.file_flags = 0;
|
||||||
};
|
|
||||||
|
|
||||||
(void) unlink(test_prog);
|
(void) unlink(test_prog);
|
||||||
|
|
||||||
|
@ -265,6 +265,7 @@ static void test_env_clean(void) {
|
|||||||
"another=one",
|
"another=one",
|
||||||
"another=final one",
|
"another=final one",
|
||||||
"CRLF=\r\n",
|
"CRLF=\r\n",
|
||||||
|
"LESS_TERMCAP_mb=\x1b[01;31m",
|
||||||
"BASH_FUNC_foo%%=() { echo foo\n}");
|
"BASH_FUNC_foo%%=() { echo foo\n}");
|
||||||
assert_se(e);
|
assert_se(e);
|
||||||
assert_se(!strv_env_is_valid(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[3], "abcd=äöüß"));
|
||||||
assert_se(streq(e[4], "xyz=xyz\n"));
|
assert_se(streq(e[4], "xyz=xyz\n"));
|
||||||
assert_se(streq(e[5], "another=final one"));
|
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) {
|
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("printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
|
||||||
assert_se(env_value_is_valid("tab\tcharacter"));
|
assert_se(env_value_is_valid("tab\tcharacter"));
|
||||||
assert_se(env_value_is_valid("new\nline"));
|
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("Show this?\rNope. Show that!"));
|
||||||
assert_se(!env_value_is_valid("new DOS\r\nline"));
|
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) {
|
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);
|
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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
test_setup_logging(LOG_DEBUG);
|
test_setup_logging(LOG_DEBUG);
|
||||||
|
|
||||||
@ -279,6 +310,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
test_mnt_id();
|
test_mnt_id();
|
||||||
test_path_is_mount_point();
|
test_path_is_mount_point();
|
||||||
|
test_fd_is_mount_point();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include "alloc-util.h"
|
#include "alloc-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "mountpoint-util.h"
|
|
||||||
#include "path-util.h"
|
#include "path-util.h"
|
||||||
#include "rm-rf.h"
|
#include "rm-rf.h"
|
||||||
#include "stat-util.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) {
|
static void test_path(void) {
|
||||||
_cleanup_close_ int fd = -1;
|
|
||||||
|
|
||||||
log_info("/* %s */", __func__);
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
test_path_compare("/goo", "/goo", 0);
|
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("/aa///file..."), "file..."));
|
||||||
assert_se(streq(basename("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/bbb////ccc", "aaa/bbb/ccc", "aaa/bbb/ccc");
|
||||||
test_path_simplify("//aaa/.////ccc", "/aaa/./ccc", "/aaa/ccc");
|
test_path_simplify("//aaa/.////ccc", "/aaa/./ccc", "/aaa/ccc");
|
||||||
test_path_simplify("///", "/", "/");
|
test_path_simplify("///", "/", "/");
|
||||||
|
@ -150,6 +150,83 @@ static void test_set_ensure_consume(void) {
|
|||||||
assert_se(set_size(m) == 2);
|
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[]) {
|
int main(int argc, const char *argv[]) {
|
||||||
test_set_steal_first();
|
test_set_steal_first();
|
||||||
test_set_free_with_destructor();
|
test_set_free_with_destructor();
|
||||||
@ -160,6 +237,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
test_set_ensure_allocated();
|
test_set_ensure_allocated();
|
||||||
test_set_ensure_put();
|
test_set_ensure_put();
|
||||||
test_set_ensure_consume();
|
test_set_ensure_consume();
|
||||||
|
test_set_strjoin();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ static void test_fgetxattrat_fake(void) {
|
|||||||
assert_se(touch(x) >= 0);
|
assert_se(touch(x) >= 0);
|
||||||
|
|
||||||
r = setxattr(x, "user.foo", "bar", 3, 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;
|
goto cleanup;
|
||||||
assert_se(r >= 0);
|
assert_se(r >= 0);
|
||||||
|
|
||||||
@ -42,7 +42,8 @@ static void test_fgetxattrat_fake(void) {
|
|||||||
safe_close(fd);
|
safe_close(fd);
|
||||||
fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
|
fd = open("/", O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY);
|
||||||
assert_se(fd >= 0);
|
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:
|
cleanup:
|
||||||
assert_se(unlink(x) >= 0);
|
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");
|
log_debug_errno(r, "Failed to get hardware clock, ignoring: %m");
|
||||||
else {
|
else {
|
||||||
/* And set the system clock with this */
|
/* 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)
|
if (clock_settime(CLOCK_REALTIME, &ts) < 0)
|
||||||
log_debug_errno(errno, "Failed to update system clock, ignoring: %m");
|
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 */
|
/* manage "stack of names" with possibly specified device priorities */
|
||||||
static int link_update(sd_device *dev, const char *slink, bool add) {
|
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];
|
char name_enc[PATH_MAX];
|
||||||
const char *id_filename;
|
const char *id_filename;
|
||||||
int i, r, retries;
|
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;
|
retries = sd_device_get_is_initialized(dev) > 0 ? LINK_UPDATE_MAX_RETRIES : 1;
|
||||||
|
|
||||||
for (i = 0; i < retries; i++) {
|
for (i = 0; i < retries; i++) {
|
||||||
|
_cleanup_free_ char *target = NULL;
|
||||||
struct stat st1 = {}, st2 = {};
|
struct stat st1 = {}, st2 = {};
|
||||||
|
|
||||||
r = stat(dirname, &st1);
|
r = stat(dirname, &st1);
|
||||||
|
@ -3,7 +3,11 @@ set -e
|
|||||||
|
|
||||||
TEST_DESCRIPTION="test MUMAPolicy= and NUMAMask= options"
|
TEST_DESCRIPTION="test MUMAPolicy= and NUMAMask= options"
|
||||||
TEST_NO_NSPAWN=1
|
TEST_NO_NSPAWN=1
|
||||||
QEMU_OPTIONS="-numa node,nodeid=0"
|
|
||||||
. $TEST_BASE_DIR/test-functions
|
. $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
|
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
|
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
|
# Return 0 if QEMU did run (then you must check the result state/logs for actual
|
||||||
# success), or 1 if QEMU is not available.
|
# success), or 1 if QEMU is not available.
|
||||||
run_qemu() {
|
run_qemu() {
|
||||||
|
@ -18,6 +18,11 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
shlex_join = e
|
shlex_join = e
|
||||||
|
|
||||||
|
try:
|
||||||
|
from shlex import quote as shlex_quote
|
||||||
|
except ImportError as e:
|
||||||
|
shlex_quote = e
|
||||||
|
|
||||||
class NoCommand(Exception):
|
class NoCommand(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -186,10 +191,13 @@ def subst_output(document, programlisting, stats):
|
|||||||
interface = programlisting.get('interface')
|
interface = programlisting.get('interface')
|
||||||
|
|
||||||
argv = [f'{opts.build_dir}/{executable}', f'--bus-introspect={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:
|
try:
|
||||||
out = subprocess.check_output(argv, text=True)
|
out = subprocess.check_output(argv, universal_newlines=True)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print(f'{executable} not found, ignoring', file=sys.stderr)
|
print(f'{executable} not found, ignoring', file=sys.stderr)
|
||||||
return
|
return
|
||||||
@ -296,7 +304,7 @@ def parse_args():
|
|||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
opts = parse_args()
|
opts = parse_args()
|
||||||
|
|
||||||
for item in (etree, shlex_join):
|
for item in (etree, shlex_quote):
|
||||||
if isinstance(item, Exception):
|
if isinstance(item, Exception):
|
||||||
print(item, file=sys.stderr)
|
print(item, file=sys.stderr)
|
||||||
exit(77 if opts.test else 1)
|
exit(77 if opts.test else 1)
|
||||||
@ -308,7 +316,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
# Let's print all statistics at the end
|
# Let's print all statistics at the end
|
||||||
mlen = max(len(page) for page in stats)
|
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)
|
total = 'total', dict(stats=total, outdated=False)
|
||||||
outdated = []
|
outdated = []
|
||||||
for page, info in sorted(stats.items()) + [total]:
|
for page, info in sorted(stats.items()) + [total]:
|
||||||
|
Loading…
Reference in New Issue
Block a user