Compare commits
23 Commits
9463d23311
...
84e6603899
Author | SHA1 | Date |
---|---|---|
Michal Sekletar | 84e6603899 | |
Marius Hoch | ff831e7c50 | |
Daan De Meyer | 81af8f998e | |
chenjiayi | 4fc8a63f9e | |
Jason Yundt | dfb3155419 | |
Daan De Meyer | fc5037e7d7 | |
Yu Watanabe | 13f6ec7ce7 | |
Yu Watanabe | 6e1816ef16 | |
Michal Sekletar | 15a932e452 | |
Michal Sekletar | dbd9d5c2bf | |
Michal Sekletar | 9a2c1187df | |
Michal Sekletar | c650603902 | |
Michal Sekletar | ed81a358e1 | |
Michal Sekletar | 8b22bf9ac3 | |
Michal Sekletar | 5b9bff7114 | |
Michal Sekletar | 84e3e4f6ec | |
Michal Sekletar | 4b8f07937a | |
Michal Sekletar | e35768d4ef | |
Michal Sekletar | ddf6298935 | |
Michal Sekletar | 5348e7d0c8 | |
Michal Sekletar | 75c5dfed33 | |
Michal Sekletar | 0e95abfb39 | |
Michal Sekletar | be528e9678 |
|
@ -760,8 +760,9 @@ sensor:modalias:i2c:bmc150_accel:dmi:*:svnLENOVO:*:pvrLenovoYoga300-11IBR:*
|
||||||
sensor:modalias:acpi:ACCL0001*:dmi:*:svnLENOVO:pn60072:pvr851*:*
|
sensor:modalias:acpi:ACCL0001*:dmi:*:svnLENOVO:pn60072:pvr851*:*
|
||||||
ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1
|
ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1
|
||||||
|
|
||||||
# IdeaPad Duet 3 10IGL5 (82AT)
|
# IdeaPad Duet 3 10IGL5 (82AT) and 10IGL5-LTE (82HK)
|
||||||
sensor:modalias:acpi:SMO8B30*:dmi:*:svnLENOVO*:pn82AT:*
|
sensor:modalias:acpi:SMO8B30*:dmi:*:svnLENOVO*:pn82AT:*
|
||||||
|
sensor:modalias:acpi:SMO8B30*:dmi:*:svnLENOVO*:pn82HK:*
|
||||||
ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1
|
ACCEL_MOUNT_MATRIX=0, 1, 0; -1, 0, 0; 0, 0, 1
|
||||||
|
|
||||||
#########################################
|
#########################################
|
||||||
|
|
|
@ -110,14 +110,14 @@
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>AccessContainer=</varname></term>
|
<term><varname>EnterNamespace=</varname></term>
|
||||||
|
|
||||||
<listitem><para>Controls whether <command>systemd-coredump</command> will attempt to use the mount tree of
|
<listitem><para>Controls whether <command>systemd-coredump</command> will attempt to use the mount tree of
|
||||||
a process that crashed within a container. Access to the container's filesystem might be necessary to generate
|
a process that crashed in PID namespace. Access to the namespace's mount tree might be necessary to generate
|
||||||
a fully symbolized backtrace. If set to <literal>yes</literal>, then <command>systemd-coredump</command> will
|
a fully symbolized backtrace. If set to <literal>yes</literal>, then <command>systemd-coredump</command> will
|
||||||
obtain the mount tree from corresponding mount namespace and will try to generate the stack trace using the
|
obtain the mount tree from corresponding mount namespace and will try to generate the stack trace using the
|
||||||
binary and libraries from the mount namespace. Note that the coredump of the containerized process might
|
binary and libraries from the mount namespace. Note that the coredump of the namespaced process might
|
||||||
still be saved in <filename>/var/lib/systemd/coredump/</filename> even if <varname>AccessContainer=</varname>
|
still be saved in <filename>/var/lib/systemd/coredump/</filename> even if <varname>EnterNamespace=</varname>
|
||||||
is set to <literal>no</literal>. Defaults to <literal>no</literal>.</para>
|
is set to <literal>no</literal>. Defaults to <literal>no</literal>.</para>
|
||||||
|
|
||||||
<xi:include href="version-info.xml" xpointer="v257"/>
|
<xi:include href="version-info.xml" xpointer="v257"/>
|
||||||
|
|
|
@ -593,8 +593,6 @@ node /org/freedesktop/systemd1 {
|
||||||
|
|
||||||
<!--method GetJobBefore is not documented!-->
|
<!--method GetJobBefore is not documented!-->
|
||||||
|
|
||||||
<!--method SetShowStatus is not documented!-->
|
|
||||||
|
|
||||||
<!--method ListUnitsFiltered is not documented!-->
|
<!--method ListUnitsFiltered is not documented!-->
|
||||||
|
|
||||||
<!--method ListUnitsByPatterns is not documented!-->
|
<!--method ListUnitsByPatterns is not documented!-->
|
||||||
|
@ -673,8 +671,6 @@ node /org/freedesktop/systemd1 {
|
||||||
|
|
||||||
<!--property ConfirmSpawn is not documented!-->
|
<!--property ConfirmSpawn is not documented!-->
|
||||||
|
|
||||||
<!--property ShowStatus is not documented!-->
|
|
||||||
|
|
||||||
<!--property DefaultStandardOutput is not documented!-->
|
<!--property DefaultStandardOutput is not documented!-->
|
||||||
|
|
||||||
<!--property DefaultStandardError is not documented!-->
|
<!--property DefaultStandardError is not documented!-->
|
||||||
|
@ -1362,6 +1358,24 @@ node /org/freedesktop/systemd1 {
|
||||||
|
|
||||||
<para><function>ResetFailedUnit()</function> resets the "failed" state of a specific unit.</para>
|
<para><function>ResetFailedUnit()</function> resets the "failed" state of a specific unit.</para>
|
||||||
|
|
||||||
|
<para><function>SetShowStatus()</function> configures the display of status messages during bootup and
|
||||||
|
shutdown. The <varname>mode</varname> parameter can be set to any value that's valid for the
|
||||||
|
<varname>systemd.show_status</varname> kernel parameter. For more information about
|
||||||
|
<varname>systemd.show_status</varname>, see
|
||||||
|
<citerefentry project="man-pages"><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
|
||||||
|
The <varname>mode</varname> parameter can also be set to an empty string. When <varname>mode</varname>
|
||||||
|
is set to an empty string, <function>SetShowStatus()</function> will reset
|
||||||
|
<varname>ShowStatus</varname> back to its original value. You can use
|
||||||
|
<function>SetShowStatus()</function> create a service that does something like this:
|
||||||
|
<orderedlist>
|
||||||
|
<listitem><para>Send a D-Bus message that will turn off status messages.</para></listitem>
|
||||||
|
<listitem><para>Block until a reply to that message is received.</para></listitem>
|
||||||
|
<listitem><para>Print multiples lines without being interrupted by status messages.</para></listitem>
|
||||||
|
<listitem><para>Send a D-Bus message that will reset <varname>ShowStatus</varname> back to its
|
||||||
|
original value.</para></listitem>
|
||||||
|
</orderedlist>
|
||||||
|
</para>
|
||||||
|
|
||||||
<para><function>ResetFailed()</function> resets the "failed" state of all units.</para>
|
<para><function>ResetFailed()</function> resets the "failed" state of all units.</para>
|
||||||
|
|
||||||
<para><function>ListUnits()</function> returns an array of all currently loaded units. Note that
|
<para><function>ListUnits()</function> returns an array of all currently loaded units. Note that
|
||||||
|
@ -1788,6 +1802,12 @@ node /org/freedesktop/systemd1 {
|
||||||
<para><varname>Environment</varname> encodes the environment block passed to all executed services. It
|
<para><varname>Environment</varname> encodes the environment block passed to all executed services. It
|
||||||
may be altered with bus calls such as <function>SetEnvironment()</function> (see above).</para>
|
may be altered with bus calls such as <function>SetEnvironment()</function> (see above).</para>
|
||||||
|
|
||||||
|
<para><varname>ShowStatus</varname> encodes systemd's current policy for displaying status messages
|
||||||
|
during bootup and shutdown. Its value can be any valid value for the
|
||||||
|
<varname>systemd.show_status</varname> kernel parameter (see
|
||||||
|
<citerefentry project="man-pages"><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>).
|
||||||
|
It may be altered using <function>SetShowStatus()</function> (see above).</para>
|
||||||
|
|
||||||
<para><varname>UnitPath</varname> encodes the currently active unit file search path. It is an array of
|
<para><varname>UnitPath</varname> encodes the currently active unit file search path. It is an array of
|
||||||
file system paths encoded as strings.</para>
|
file system paths encoded as strings.</para>
|
||||||
|
|
||||||
|
|
|
@ -483,18 +483,18 @@
|
||||||
<term><varname>ExcludeFiles=</varname></term>
|
<term><varname>ExcludeFiles=</varname></term>
|
||||||
<term><varname>ExcludeFilesTarget=</varname></term>
|
<term><varname>ExcludeFilesTarget=</varname></term>
|
||||||
|
|
||||||
<listitem><para>Takes an absolute file system path referring to a source file or directory on the
|
<listitem><para>Takes one or more absolute paths, separated by whitespace, each referring to a
|
||||||
host. This setting may be used to exclude files or directories from the host from being copied into
|
source file or directory on the host. This setting may be used to exclude files or directories from
|
||||||
the file system when <varname>CopyFiles=</varname> is used. This option may be used multiple times to
|
the host from being copied into the file system when <varname>CopyFiles=</varname> is used. This
|
||||||
exclude multiple files or directories from host from being copied into the newly formatted file
|
option may be used multiple times to exclude multiple files or directories from host from being
|
||||||
system.</para>
|
copied into the newly formatted file system.</para>
|
||||||
|
|
||||||
<para>If the path is a directory and ends with <literal>/</literal>, only the directory's
|
<para>If the path is a directory and ends with <literal>/</literal>, only the directory's
|
||||||
contents are excluded but not the directory itself. If the path is a directory and does not end with
|
contents are excluded but not the directory itself. If the path is a directory and does not end with
|
||||||
<literal>/</literal>, both the directory and its contents are excluded.</para>
|
<literal>/</literal>, both the directory and its contents are excluded.</para>
|
||||||
|
|
||||||
<para><varname>ExcludeFilesTarget=</varname> is like <varname>ExcludeFiles=</varname> except that
|
<para><varname>ExcludeFilesTarget=</varname> is like <varname>ExcludeFiles=</varname> except that
|
||||||
instead of excluding the path on the host from being copied into the partition, we exclude any files
|
instead of excluding the path on the host from being copied into the partition, it exclude any files
|
||||||
and directories from being copied into the given path in the partition.</para>
|
and directories from being copied into the given path in the partition.</para>
|
||||||
|
|
||||||
<para>When
|
<para>When
|
||||||
|
|
|
@ -3001,7 +3001,12 @@ SystemCallErrorNumber=EPERM</programlisting>
|
||||||
|
|
||||||
<para><option>tty</option> connects standard output to a tty (as configured via <varname>TTYPath=</varname>,
|
<para><option>tty</option> connects standard output to a tty (as configured via <varname>TTYPath=</varname>,
|
||||||
see below). If the TTY is used for output only, the executed process will not become the controlling process of
|
see below). If the TTY is used for output only, the executed process will not become the controlling process of
|
||||||
the terminal, and will not fail or wait for other processes to release the terminal.</para>
|
the terminal, and will not fail or wait for other processes to release the terminal. Note: if a unit
|
||||||
|
tries to print multiple lines to a TTY during bootup or shutdown, then there's a chance that those
|
||||||
|
lines will be broken up by status messages. <function>SetShowStatus()</function> can be used to
|
||||||
|
prevent this problem. See
|
||||||
|
<citerefentry project="man-pages"><refentrytitle>org.freedesktop.systemd1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
|
for details.</para>
|
||||||
|
|
||||||
<para><option>journal</option> connects standard output with the journal, which is accessible via
|
<para><option>journal</option> connects standard output with the journal, which is accessible via
|
||||||
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. Note
|
<citerefentry><refentrytitle>journalctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. Note
|
||||||
|
|
|
@ -568,7 +568,11 @@
|
||||||
<listitem><para>Enables display of status messages on the
|
<listitem><para>Enables display of status messages on the
|
||||||
console, as controlled via
|
console, as controlled via
|
||||||
<varname>systemd.show_status=1</varname> on the kernel command
|
<varname>systemd.show_status=1</varname> on the kernel command
|
||||||
line.</para></listitem>
|
line.</para>
|
||||||
|
<para>You may want to use <function>SetShowStatus()</function> instead of
|
||||||
|
<constant>SIGRTMIN+20</constant> in order to prevent race conditions. See
|
||||||
|
<citerefentry project="man-pages"><refentrytitle>org.freedesktop.systemd1</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
@ -579,7 +583,11 @@
|
||||||
controlled via
|
controlled via
|
||||||
<varname>systemd.show_status=0</varname>
|
<varname>systemd.show_status=0</varname>
|
||||||
on the kernel command
|
on the kernel command
|
||||||
line.</para></listitem>
|
line.</para>
|
||||||
|
<para>You may want to use <function>SetShowStatus()</function> instead of
|
||||||
|
<constant>SIGRTMIN+21</constant> in order to prevent race conditions. See
|
||||||
|
<citerefentry project="man-pages"><refentrytitle>org.freedesktop.systemd1</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||||
|
</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "analyze.h"
|
#include "analyze.h"
|
||||||
#include "analyze-inspect-elf.h"
|
#include "analyze-inspect-elf.h"
|
||||||
|
#include "chase.h"
|
||||||
#include "elf-util.h"
|
#include "elf-util.h"
|
||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
|
@ -19,23 +20,13 @@ static int analyze_elf(char **filenames, sd_json_format_flags_t json_flags) {
|
||||||
STRV_FOREACH(filename, filenames) {
|
STRV_FOREACH(filename, filenames) {
|
||||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *package_metadata = NULL;
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *package_metadata = NULL;
|
||||||
_cleanup_(table_unrefp) Table *t = NULL;
|
_cleanup_(table_unrefp) Table *t = NULL;
|
||||||
_cleanup_free_ char *abspath = NULL, *path = NULL, *stacktrace = NULL;
|
_cleanup_free_ char *abspath = NULL, *stacktrace = NULL;
|
||||||
_cleanup_close_ int fd = -EBADF;
|
_cleanup_close_ int fd = -EBADF;
|
||||||
bool coredump = false;
|
bool coredump = false;
|
||||||
|
|
||||||
r = path_make_absolute_cwd(*filename, &abspath);
|
fd = chase_and_open(*filename, arg_root, CHASE_PREFIX_ROOT, O_RDONLY|O_CLOEXEC, &abspath);
|
||||||
if (r < 0)
|
|
||||||
return log_error_errno(r, "Could not make an absolute path out of \"%s\": %m", *filename);
|
|
||||||
|
|
||||||
path = path_join(empty_to_root(arg_root), abspath);
|
|
||||||
if (!path)
|
|
||||||
return log_oom();
|
|
||||||
|
|
||||||
path_simplify(path);
|
|
||||||
|
|
||||||
fd = RET_NERRNO(open(path, O_RDONLY|O_CLOEXEC));
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return log_error_errno(fd, "Could not open \"%s\": %m", path);
|
return log_error_errno(fd, "Could not open \"%s\": %m", *filename);
|
||||||
|
|
||||||
r = parse_elf_object(fd, abspath, arg_root, /* fork_disable_dump= */false, &stacktrace, &package_metadata);
|
r = parse_elf_object(fd, abspath, arg_root, /* fork_disable_dump= */false, &stacktrace, &package_metadata);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -65,7 +56,7 @@ static int analyze_elf(char **filenames, sd_json_format_flags_t json_flags) {
|
||||||
* metadata is parsed recursively in core files, so there might be
|
* metadata is parsed recursively in core files, so there might be
|
||||||
* multiple modules. */
|
* multiple modules. */
|
||||||
if (STR_IN_SET(module_name, "elfType", "elfArchitecture")) {
|
if (STR_IN_SET(module_name, "elfType", "elfArchitecture")) {
|
||||||
if (streq(module_name, "elfType") && streq("coredump", sd_json_variant_string(module_json)))
|
if (streq(module_name, "elfType") && streq(sd_json_variant_string(module_json), "coredump"))
|
||||||
coredump = true;
|
coredump = true;
|
||||||
|
|
||||||
r = table_add_many(
|
r = table_add_many(
|
||||||
|
|
|
@ -4169,7 +4169,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
||||||
* detect when the cgroup becomes empty. Note that the control process is always
|
* detect when the cgroup becomes empty. Note that the control process is always
|
||||||
* our child so it's pointless to watch all other processes. */
|
* our child so it's pointless to watch all other processes. */
|
||||||
if (!control_pid_good(s))
|
if (!control_pid_good(s))
|
||||||
if (!s->main_pid_known || s->main_pid_alien)
|
if (!s->main_pid_known || s->main_pid_alien || unit_cgroup_delegate(u))
|
||||||
(void) unit_enqueue_rewatch_pids(u);
|
(void) unit_enqueue_rewatch_pids(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,15 @@
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/statvfs.h>
|
#include <sys/statvfs.h>
|
||||||
#include <sys/auxv.h>
|
#include <sys/auxv.h>
|
||||||
#include <sys/xattr.h>
|
#include <sys/xattr.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#if WANT_LINUX_FS_H
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sd-daemon.h"
|
#include "sd-daemon.h"
|
||||||
#include "sd-journal.h"
|
#include "sd-journal.h"
|
||||||
|
@ -86,6 +90,8 @@
|
||||||
* size. See DATA_SIZE_MAX in journal-importer.h. */
|
* size. See DATA_SIZE_MAX in journal-importer.h. */
|
||||||
assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX);
|
assert_cc(JOURNAL_SIZE_MAX <= DATA_SIZE_MAX);
|
||||||
|
|
||||||
|
#define MOUNT_TREE_ROOT "/run/systemd/mount-rootfs"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/* We use these as array indexes for our process metadata cache.
|
/* We use these as array indexes for our process metadata cache.
|
||||||
*
|
*
|
||||||
|
@ -167,7 +173,7 @@ static uint64_t arg_external_size_max = EXTERNAL_SIZE_MAX;
|
||||||
static uint64_t arg_journal_size_max = JOURNAL_SIZE_MAX;
|
static uint64_t arg_journal_size_max = JOURNAL_SIZE_MAX;
|
||||||
static uint64_t arg_keep_free = UINT64_MAX;
|
static uint64_t arg_keep_free = UINT64_MAX;
|
||||||
static uint64_t arg_max_use = UINT64_MAX;
|
static uint64_t arg_max_use = UINT64_MAX;
|
||||||
static bool arg_access_container = false;
|
static bool arg_enter_namespace = false;
|
||||||
|
|
||||||
static int parse_config(void) {
|
static int parse_config(void) {
|
||||||
static const ConfigTableItem items[] = {
|
static const ConfigTableItem items[] = {
|
||||||
|
@ -179,9 +185,9 @@ static int parse_config(void) {
|
||||||
{ "Coredump", "KeepFree", config_parse_iec_uint64, 0, &arg_keep_free },
|
{ "Coredump", "KeepFree", config_parse_iec_uint64, 0, &arg_keep_free },
|
||||||
{ "Coredump", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use },
|
{ "Coredump", "MaxUse", config_parse_iec_uint64, 0, &arg_max_use },
|
||||||
#if HAVE_DWFL_SET_SYSROOT
|
#if HAVE_DWFL_SET_SYSROOT
|
||||||
{ "Coredump", "AccessContainer", config_parse_bool, 0, &arg_access_container },
|
{ "Coredump", "EnterNamespace", config_parse_bool, 0, &arg_enter_namespace },
|
||||||
#else
|
#else
|
||||||
{ "Coredump", "AccessContainer", config_parse_warn_compat, DISABLED_CONFIGURATION, 0 },
|
{ "Coredump", "EnterNamespace", config_parse_warn_compat, DISABLED_CONFIGURATION, 0 },
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
@ -782,30 +788,32 @@ static int change_uid_gid(const Context *context) {
|
||||||
return drop_privileges(uid, gid, 0);
|
return drop_privileges(uid, gid, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_container_mount_tree(int mount_tree_fd, char **container_root) {
|
static int attach_mount_tree(int mount_tree_fd) {
|
||||||
_cleanup_free_ char *root = NULL;
|
_cleanup_free_ char *root = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(mount_tree_fd >= 0);
|
assert(mount_tree_fd >= 0);
|
||||||
assert(container_root);
|
|
||||||
|
|
||||||
r = unshare(CLONE_NEWNS);
|
r = detach_mount_namespace();
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_warning_errno(errno, "Failed to unshare mount namespace: %m");
|
return log_warning_errno(r, "Failed to detach mount namespace: %m");
|
||||||
|
|
||||||
r = mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL);
|
r = mkdir_label(MOUNT_TREE_ROOT, 0555);
|
||||||
|
if (r < 0 && r != -EEXIST)
|
||||||
|
return log_warning_errno(r, "Failed to create directory: %m");
|
||||||
|
|
||||||
|
r = mount_setattr(mount_tree_fd, "", AT_EMPTY_PATH,
|
||||||
|
&(struct mount_attr) {
|
||||||
|
.attr_set = MOUNT_ATTR_RDONLY|MOUNT_ATTR_NOSUID|MOUNT_ATTR_NODEV|MOUNT_ATTR_NOEXEC,
|
||||||
|
.propagation = MS_SLAVE,
|
||||||
|
}, sizeof(struct mount_attr));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_warning_errno(errno, "Failed to disable mount propagation: %m");
|
return log_warning_errno(r, "Failed to change properties mount tree: %m");
|
||||||
|
|
||||||
r = mkdtemp_malloc("/tmp/systemd-coredump-root-XXXXXX", &root);
|
r = move_mount(mount_tree_fd, "", -EBADF, MOUNT_TREE_ROOT, MOVE_MOUNT_F_EMPTY_PATH);
|
||||||
if (r < 0)
|
|
||||||
return log_warning_errno(r, "Failed to create temporary directory: %m");
|
|
||||||
|
|
||||||
r = move_mount(mount_tree_fd, "", -EBADF, root, MOVE_MOUNT_F_EMPTY_PATH);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_warning_errno(errno, "Failed to move mount tree: %m");
|
return log_warning_errno(errno, "Failed to move mount tree: %m");
|
||||||
|
|
||||||
*container_root = TAKE_PTR(root);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -817,10 +825,8 @@ static int submit_coredump(
|
||||||
|
|
||||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *json_metadata = NULL;
|
_cleanup_(sd_json_variant_unrefp) sd_json_variant *json_metadata = NULL;
|
||||||
_cleanup_close_ int coredump_fd = -EBADF, coredump_node_fd = -EBADF;
|
_cleanup_close_ int coredump_fd = -EBADF, coredump_node_fd = -EBADF;
|
||||||
_cleanup_free_ char *filename = NULL, *coredump_data = NULL;
|
_cleanup_free_ char *filename = NULL, *coredump_data = NULL, *stacktrace = NULL;
|
||||||
_cleanup_free_ char *stacktrace = NULL;
|
const char *module_name, *root = MOUNT_TREE_ROOT;
|
||||||
_cleanup_free_ char *root = NULL;
|
|
||||||
const char *module_name;
|
|
||||||
uint64_t coredump_size = UINT64_MAX, coredump_compressed_size = UINT64_MAX;
|
uint64_t coredump_size = UINT64_MAX, coredump_compressed_size = UINT64_MAX;
|
||||||
bool truncated = false, written = false;
|
bool truncated = false, written = false;
|
||||||
sd_json_variant *module_json;
|
sd_json_variant *module_json;
|
||||||
|
@ -856,10 +862,10 @@ static int submit_coredump(
|
||||||
(void) coredump_vacuum(coredump_node_fd >= 0 ? coredump_node_fd : coredump_fd, arg_keep_free, arg_max_use);
|
(void) coredump_vacuum(coredump_node_fd >= 0 ? coredump_node_fd : coredump_fd, arg_keep_free, arg_max_use);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mount_tree_fd >= 0 && arg_access_container) {
|
if (mount_tree_fd >= 0) {
|
||||||
r = setup_container_mount_tree(mount_tree_fd, &root);
|
r = attach_mount_tree(mount_tree_fd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to setup container mount tree, ignoring: %m");
|
root = "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now, let's drop privileges to become the user who owns the segfaulted process and allocate the
|
/* Now, let's drop privileges to become the user who owns the segfaulted process and allocate the
|
||||||
|
@ -869,6 +875,7 @@ static int submit_coredump(
|
||||||
r = change_uid_gid(context);
|
r = change_uid_gid(context);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to drop privileges: %m");
|
return log_error_errno(r, "Failed to drop privileges: %m");
|
||||||
|
|
||||||
if (written) {
|
if (written) {
|
||||||
/* Try to get a stack trace if we can */
|
/* Try to get a stack trace if we can */
|
||||||
if (coredump_size > arg_process_size_max)
|
if (coredump_size > arg_process_size_max)
|
||||||
|
@ -1109,18 +1116,43 @@ static int process_socket(int fd) {
|
||||||
/* We have all FDs we need let's take a shortcut here. */
|
/* We have all FDs we need let's take a shortcut here. */
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
struct cmsghdr *cmsg;
|
||||||
|
unsigned n_fds = 0;
|
||||||
|
|
||||||
found = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int)));
|
found = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int)));
|
||||||
if (found)
|
if (first && found) {
|
||||||
|
/* This is the first message that carries file descriptors, maybe there will be
|
||||||
|
* one more that actually contains array of two descriptors. */
|
||||||
|
assert(input_fd < 0);
|
||||||
|
|
||||||
input_fd = *CMSG_TYPED_DATA(found, int);
|
input_fd = *CMSG_TYPED_DATA(found, int);
|
||||||
}
|
|
||||||
|
|
||||||
/* This is the first message that carries file descriptors, maybe there will be one more that actually contains array of descriptors. */
|
|
||||||
if (first) {
|
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
} else if (first && !found) {
|
||||||
|
/* This is the first message of zero length and it has no file descriptor,
|
||||||
|
* this is the protocol violation so let's bail out. */
|
||||||
|
cmsg_close_all(&mh);
|
||||||
|
r = log_error_errno(SYNTHETIC_ERRNO(EBADMSG),
|
||||||
|
"Received zero length message with no file descriptor.");
|
||||||
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is second iteration and we didn't find array of two FDs, hence we either
|
||||||
|
* have no FDs which is OK and we can break or we have some other number of FDs
|
||||||
|
* and somebody is playing games with us. So let's check for that. */
|
||||||
|
CMSG_FOREACH(cmsg, &mh)
|
||||||
|
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS)
|
||||||
|
n_fds++;
|
||||||
|
|
||||||
|
if (n_fds == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
cmsg_close_all(&mh);
|
||||||
|
r = log_error_errno(SYNTHETIC_ERRNO(EBADMSG),
|
||||||
|
"Received '%u' unexpected file descriptors.", n_fds);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
cmsg_close_all(&mh);
|
cmsg_close_all(&mh);
|
||||||
|
|
||||||
|
@ -1627,42 +1659,59 @@ static int forward_coredump_to_container(Context *context) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gather_pid_mount_tree_fd(const Context *context) {
|
static int gather_pid_mount_tree_fd(const Context *context, int *ret_fd) {
|
||||||
_cleanup_close_ int mntns_fd = -EBADF, root_fd = -EBADF;
|
_cleanup_close_ int mntns_fd = -EBADF, root_fd = -EBADF;
|
||||||
_cleanup_close_pair_ int pair[2] = EBADF_PAIR;
|
_cleanup_close_pair_ int pair[2] = EBADF_PAIR;
|
||||||
int fd = -EBADF, r;
|
int fd = -EBADF, r;
|
||||||
pid_t child;
|
|
||||||
|
|
||||||
assert(context);
|
assert(context);
|
||||||
|
assert(ret_fd);
|
||||||
|
|
||||||
/* Don't bother preparing environment if we can't pass it to libdwfl. */
|
/* Don't bother preparing environment if we can't pass it to libdwfl. */
|
||||||
#if !HAVE_DWFL_SET_SYSROOT
|
#if !HAVE_DWFL_SET_SYSROOT
|
||||||
return -EBADF;
|
r = 0;
|
||||||
|
goto finish;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!arg_access_container)
|
if (!arg_enter_namespace) {
|
||||||
return -EBADF;
|
r = 0;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, pair) < 0)
|
if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, pair) < 0) {
|
||||||
return log_error_errno(errno, "Failed to create socket pair: %m");
|
r = log_error_errno(errno, "Failed to create socket pair: %m");
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
r = namespace_open(context->pid, NULL, &mntns_fd, NULL, NULL, &root_fd);
|
r = namespace_open(context->pid, NULL, &mntns_fd, NULL, NULL, &root_fd);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
return log_error_errno(r, "Failed to open mount namespace of crashing process: %m");
|
log_error_errno(r, "Failed to open mount namespace of crashing process: %m");
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
r = namespace_fork("(sd-mount-tree-ns)", "(sd-mount-tree)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, -1, mntns_fd, -1, -1, root_fd, &child);
|
r = namespace_fork("(sd-mount-tree-ns)",
|
||||||
|
"(sd-mount-tree)",
|
||||||
|
/* except_fds= */ NULL,
|
||||||
|
/* n_except_fds= */ 0,
|
||||||
|
FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT,
|
||||||
|
/* pidns_fd= */ -EBADF,
|
||||||
|
mntns_fd,
|
||||||
|
/* netns_fd= */ -EBADF,
|
||||||
|
/* userns_fd= */ -EBADF,
|
||||||
|
root_fd,
|
||||||
|
NULL);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to fork(): %m");
|
goto finish;
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
pair[0] = safe_close(pair[0]);
|
pair[0] = safe_close(pair[0]);
|
||||||
|
|
||||||
r = open_tree(-EBADF, "/", AT_NO_AUTOMOUNT | AT_RECURSIVE | AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE);
|
fd = open_tree(-EBADF, "/", AT_NO_AUTOMOUNT | AT_RECURSIVE | AT_SYMLINK_NOFOLLOW | OPEN_TREE_CLOEXEC | OPEN_TREE_CLONE);
|
||||||
if (r < 0) {
|
if (fd < 0) {
|
||||||
log_error_errno(errno, "Failed to clone mount tree: %m");
|
log_error_errno(errno, "Failed to clone mount tree: %m");
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = send_one_fd(pair[1], r, 0);
|
r = send_one_fd(pair[1], fd, 0);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_error_errno(r, "Failed to send mount tree to parent: %m");
|
log_error_errno(r, "Failed to send mount tree to parent: %m");
|
||||||
_exit(EXIT_FAILURE);
|
_exit(EXIT_FAILURE);
|
||||||
|
@ -1673,17 +1722,17 @@ static int gather_pid_mount_tree_fd(const Context *context) {
|
||||||
|
|
||||||
pair[1] = safe_close(pair[1]);
|
pair[1] = safe_close(pair[1]);
|
||||||
|
|
||||||
r = wait_for_terminate_and_check("(sd-mount-tree-ns)", child, 0);
|
r = receive_one_fd(pair[0], MSG_DONTWAIT);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
return log_error_errno(r, "Failed to wait for child: %m");
|
log_error_errno(r, "Failed to receive mount tree: %m");
|
||||||
if (r != EXIT_SUCCESS)
|
goto finish;
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ECHILD), "Child died abnormally.");
|
}
|
||||||
|
|
||||||
fd = receive_one_fd(pair[0], MSG_DONTWAIT);
|
fd = r;
|
||||||
if (fd < 0)
|
r = 0;
|
||||||
return log_error_errno(fd, "Failed to receive mount tree: %m");
|
finish:
|
||||||
|
*ret_fd = TAKE_FD(fd);
|
||||||
return fd;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int process_kernel(int argc, char* argv[]) {
|
static int process_kernel(int argc, char* argv[]) {
|
||||||
|
@ -1735,11 +1784,9 @@ static int process_kernel(int argc, char* argv[]) {
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
r = gather_pid_mount_tree_fd(&context);
|
r = gather_pid_mount_tree_fd(&context, &mount_tree_fd);
|
||||||
if (r < 0 && r != -EBADF)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Failed to access the mount tree of a container, ignoring: %m");
|
log_warning_errno(r, "Failed to access the mount tree of a container, ignoring: %m");
|
||||||
else
|
|
||||||
mount_tree_fd = r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this is PID 1 disable coredump collection, we'll unlikely be able to process
|
/* If this is PID 1 disable coredump collection, we'll unlikely be able to process
|
||||||
|
|
|
@ -25,4 +25,4 @@
|
||||||
#JournalSizeMax=767M
|
#JournalSizeMax=767M
|
||||||
#MaxUse=
|
#MaxUse=
|
||||||
#KeepFree=
|
#KeepFree=
|
||||||
#AccessContainer=no
|
#EnterNamespace=no
|
||||||
|
|
|
@ -404,15 +404,16 @@ static int context_set_path_strv(Context *c, char* const* strv, const char *sour
|
||||||
|
|
||||||
static int context_set_plugins(Context *c, const char *s, const char *source) {
|
static int context_set_plugins(Context *c, const char *s, const char *source) {
|
||||||
_cleanup_strv_free_ char **v = NULL;
|
_cleanup_strv_free_ char **v = NULL;
|
||||||
|
int r;
|
||||||
|
|
||||||
assert(c);
|
assert(c);
|
||||||
|
|
||||||
if (c->plugins || !s)
|
if (c->plugins || !s)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
v = strv_split(s, NULL);
|
r = strv_split_full(&v, s, NULL, EXTRACT_UNQUOTE);
|
||||||
if (!v)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_error_errno(r, "Failed to parse plugin paths from %s: %m", source);
|
||||||
|
|
||||||
return context_set_path_strv(c, v, source, "plugins", &c->plugins);
|
return context_set_path_strv(c, v, source, "plugins", &c->plugins);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,13 @@ echo 'DTBDTBDTBDTB' >"$D/sources/subdir/whatever.dtb"
|
||||||
|
|
||||||
export KERNEL_INSTALL_CONF_ROOT="$D/sources"
|
export KERNEL_INSTALL_CONF_ROOT="$D/sources"
|
||||||
# We "install" multiple plugins, but control which ones will be active via install.conf.
|
# We "install" multiple plugins, but control which ones will be active via install.conf.
|
||||||
export KERNEL_INSTALL_PLUGINS="${ukify_install} ${loaderentry_install} ${uki_copy_install}"
|
KERNEL_INSTALL_PLUGINS="'${loaderentry_install}' '${uki_copy_install}'"
|
||||||
|
if [[ -n "$ukify_install" ]]; then
|
||||||
|
# shellcheck disable=SC2089
|
||||||
|
KERNEL_INSTALL_PLUGINS="'${ukify_install}' $KERNEL_INSTALL_PLUGINS"
|
||||||
|
fi
|
||||||
|
# shellcheck disable=SC2090
|
||||||
|
export KERNEL_INSTALL_PLUGINS
|
||||||
export BOOT_ROOT="$D/boot"
|
export BOOT_ROOT="$D/boot"
|
||||||
export BOOT_MNT="$D/boot"
|
export BOOT_MNT="$D/boot"
|
||||||
export MACHINE_ID='3e0484f3634a418b8e6a39e8828b03e3'
|
export MACHINE_ID='3e0484f3634a418b8e6a39e8828b03e3'
|
||||||
|
|
|
@ -1742,8 +1742,9 @@ static int config_parse_exclude_files(
|
||||||
const char *rvalue,
|
const char *rvalue,
|
||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
_cleanup_free_ char *resolved = NULL;
|
|
||||||
char ***exclude_files = ASSERT_PTR(data);
|
char ***exclude_files = ASSERT_PTR(data);
|
||||||
|
const char *p = ASSERT_PTR(rvalue);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (isempty(rvalue)) {
|
if (isempty(rvalue)) {
|
||||||
|
@ -1751,10 +1752,23 @@ static int config_parse_exclude_files(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = specifier_printf(rvalue, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved);
|
for (;;) {
|
||||||
|
_cleanup_free_ char *word = NULL, *resolved = NULL;
|
||||||
|
|
||||||
|
r = extract_first_word(&p, &word, NULL, EXTRACT_UNQUOTE);
|
||||||
|
if (r == -ENOMEM)
|
||||||
|
return log_oom();
|
||||||
|
if (r < 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (r == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = specifier_printf(word, PATH_MAX-1, system_and_tmp_specifier_table, arg_root, NULL, &resolved);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to expand specifiers in ExcludeFiles= path, ignoring: %s", rvalue);
|
"Failed to expand specifiers in %s path, ignoring: %s", lvalue, word);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1764,6 +1778,7 @@ static int config_parse_exclude_files(
|
||||||
|
|
||||||
if (strv_consume(exclude_files, TAKE_PTR(resolved)) < 0)
|
if (strv_consume(exclude_files, TAKE_PTR(resolved)) < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ _unused_ static void test_compress_stream(const char *compression,
|
||||||
ASSERT_OK(compress(src, dst, -1, &uncompressed_size));
|
ASSERT_OK(compress(src, dst, -1, &uncompressed_size));
|
||||||
|
|
||||||
if (cat) {
|
if (cat) {
|
||||||
assert_se(asprintf(&cmd, "%s %s | diff %s -", cat, pattern, srcfile) > 0);
|
assert_se(asprintf(&cmd, "%s %s | diff '%s' -", cat, pattern, srcfile) > 0);
|
||||||
assert_se(system(cmd) == 0);
|
assert_se(system(cmd) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ _unused_ static void test_compress_stream(const char *compression,
|
||||||
r = decompress(dst, dst2, st.st_size);
|
r = decompress(dst, dst2, st.st_size);
|
||||||
assert_se(r == 0);
|
assert_se(r == 0);
|
||||||
|
|
||||||
assert_se(asprintf(&cmd2, "diff %s %s", srcfile, pattern2) > 0);
|
assert_se(asprintf(&cmd2, "diff '%s' %s", srcfile, pattern2) > 0);
|
||||||
assert_se(system(cmd2) == 0);
|
assert_se(system(cmd2) == 0);
|
||||||
|
|
||||||
log_debug("/* test faulty decompression */");
|
log_debug("/* test faulty decompression */");
|
||||||
|
|
|
@ -52,7 +52,8 @@ static void test_event_spawn_self(const char *self, const char *arg, bool with_p
|
||||||
|
|
||||||
log_debug("/* %s(%s, %s) */", __func__, arg, yes_no(with_pidfd));
|
log_debug("/* %s(%s, %s) */", __func__, arg, yes_no(with_pidfd));
|
||||||
|
|
||||||
assert_se(cmd = strjoin(self, " ", arg));
|
/* 'self' may contain spaces, hence needs to be quoted. */
|
||||||
|
assert_se(cmd = strjoin("'", self, "' ", arg));
|
||||||
|
|
||||||
test_event_spawn_core(with_pidfd, cmd, result_buf, BUF_SIZE);
|
test_event_spawn_core(with_pidfd, cmd, result_buf, BUF_SIZE);
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ test_append_files() {
|
||||||
instmods vmw_vsock_virtio_transport
|
instmods vmw_vsock_virtio_transport
|
||||||
instmods vsock_loopback
|
instmods vsock_loopback
|
||||||
instmods vmw_vsock_vmci_transport
|
instmods vmw_vsock_vmci_transport
|
||||||
|
inst_binary gcc
|
||||||
generate_module_dependencies
|
generate_module_dependencies
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,32 +4,32 @@ set -e
|
||||||
|
|
||||||
ANALYZE="${1:-systemd-analyze}"
|
ANALYZE="${1:-systemd-analyze}"
|
||||||
|
|
||||||
$ANALYZE compare-versions 1 lt 2
|
"$ANALYZE" compare-versions 1 lt 2
|
||||||
$ANALYZE compare-versions 1 '<' 2
|
"$ANALYZE" compare-versions 1 '<' 2
|
||||||
$ANALYZE compare-versions 1 le 2
|
"$ANALYZE" compare-versions 1 le 2
|
||||||
$ANALYZE compare-versions 1 '<=' 2
|
"$ANALYZE" compare-versions 1 '<=' 2
|
||||||
$ANALYZE compare-versions 1 ne 2
|
"$ANALYZE" compare-versions 1 ne 2
|
||||||
$ANALYZE compare-versions 1 '!=' 2
|
"$ANALYZE" compare-versions 1 '!=' 2
|
||||||
( ! $ANALYZE compare-versions 1 ge 2 )
|
( ! "$ANALYZE" compare-versions 1 ge 2 )
|
||||||
( ! $ANALYZE compare-versions 1 '>=' 2 )
|
( ! "$ANALYZE" compare-versions 1 '>=' 2 )
|
||||||
( ! $ANALYZE compare-versions 1 eq 2 )
|
( ! "$ANALYZE" compare-versions 1 eq 2 )
|
||||||
( ! $ANALYZE compare-versions 1 '==' 2 )
|
( ! "$ANALYZE" compare-versions 1 '==' 2 )
|
||||||
( ! $ANALYZE compare-versions 1 gt 2 )
|
( ! "$ANALYZE" compare-versions 1 gt 2 )
|
||||||
( ! $ANALYZE compare-versions 1 '>' 2 )
|
( ! "$ANALYZE" compare-versions 1 '>' 2 )
|
||||||
|
|
||||||
test "$($ANALYZE compare-versions 1 2)" = '1 < 2'
|
test "$("$ANALYZE" compare-versions 1 2)" = '1 < 2'
|
||||||
test "$($ANALYZE compare-versions 2 2)" = '2 == 2'
|
test "$("$ANALYZE" compare-versions 2 2)" = '2 == 2'
|
||||||
test "$($ANALYZE compare-versions 2 1)" = '2 > 1'
|
test "$("$ANALYZE" compare-versions 2 1)" = '2 > 1'
|
||||||
test "$($ANALYZE compare-versions '' '')" = "'' == ''"
|
test "$("$ANALYZE" compare-versions '' '')" = "'' == ''"
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
|
|
||||||
$ANALYZE compare-versions 1 2; ret1=$?
|
"$ANALYZE" compare-versions 1 2; ret1=$?
|
||||||
$ANALYZE compare-versions 2 2; ret2=$?
|
"$ANALYZE" compare-versions 2 2; ret2=$?
|
||||||
$ANALYZE compare-versions 2 1; ret3=$?
|
"$ANALYZE" compare-versions 2 1; ret3=$?
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
test $ret1 == 12
|
test "$ret1" == 12
|
||||||
test $ret2 == 0
|
test "$ret2" == 0
|
||||||
test $ret3 == 11
|
test "$ret3" == 11
|
||||||
|
|
|
@ -44,9 +44,9 @@ test_one() (
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "${input##*/}" =~ \.fstab\.input ]]; then
|
if [[ "${input##*/}" =~ \.fstab\.input ]]; then
|
||||||
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD="$initrd" SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$input" SYSTEMD_SYSROOT_FSTAB="/dev/null" $generator "$out" "$out" "$out"
|
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD="$initrd" SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=yes root=fstab" SYSTEMD_FSTAB="$input" SYSTEMD_SYSROOT_FSTAB="/dev/null" "$generator" "$out" "$out" "$out"
|
||||||
else
|
else
|
||||||
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD="$initrd" SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$input")" $generator "$out" "$out" "$out"
|
SYSTEMD_LOG_LEVEL=debug SYSTEMD_IN_INITRD="$initrd" SYSTEMD_SYSFS_CHECK=no SYSTEMD_PROC_CMDLINE="fstab=no $(cat "$input")" "$generator" "$out" "$out" "$out"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The option x-systemd.growfs creates symlink to system's systemd-growfs@.service in .mount.wants directory.
|
# The option x-systemd.growfs creates symlink to system's systemd-growfs@.service in .mount.wants directory.
|
||||||
|
|
|
@ -53,7 +53,7 @@ for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||||
echo "*** Running $f"
|
echo "*** Running $f"
|
||||||
prepare_testdir "${f%.input}"
|
prepare_testdir "${f%.input}"
|
||||||
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
||||||
$SYSUSERS --root="$TESTDIR"
|
"$SYSUSERS" --root="$TESTDIR"
|
||||||
|
|
||||||
compare "${f%.*}" ""
|
compare "${f%.*}" ""
|
||||||
done
|
done
|
||||||
|
@ -62,7 +62,7 @@ for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||||
echo "*** Running $f on stdin"
|
echo "*** Running $f on stdin"
|
||||||
prepare_testdir "${f%.input}"
|
prepare_testdir "${f%.input}"
|
||||||
touch "$TESTDIR/etc/sysusers.d/test.conf"
|
touch "$TESTDIR/etc/sysusers.d/test.conf"
|
||||||
$SYSUSERS --root="$TESTDIR" - <"$f"
|
"$SYSUSERS" --root="$TESTDIR" - <"$f"
|
||||||
|
|
||||||
compare "${f%.*}" "on stdin"
|
compare "${f%.*}" "on stdin"
|
||||||
done
|
done
|
||||||
|
@ -72,9 +72,9 @@ for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||||
prepare_testdir "${f%.input}"
|
prepare_testdir "${f%.input}"
|
||||||
touch "$TESTDIR/etc/sysusers.d/test.conf"
|
touch "$TESTDIR/etc/sysusers.d/test.conf"
|
||||||
# this overrides test.conf which is masked on disk
|
# this overrides test.conf which is masked on disk
|
||||||
$SYSUSERS --root="$TESTDIR" --replace=/etc/sysusers.d/test.conf - <"$f"
|
"$SYSUSERS" --root="$TESTDIR" --replace=/etc/sysusers.d/test.conf - <"$f"
|
||||||
# this should be ignored
|
# this should be ignored
|
||||||
$SYSUSERS --root="$TESTDIR" --replace=/usr/lib/sysusers.d/test.conf - <"$SOURCE/test-1.input"
|
"$SYSUSERS" --root="$TESTDIR" --replace=/usr/lib/sysusers.d/test.conf - <"$SOURCE/test-1.input"
|
||||||
|
|
||||||
compare "${f%.*}" "on stdin with --replace"
|
compare "${f%.*}" "on stdin with --replace"
|
||||||
done
|
done
|
||||||
|
@ -84,7 +84,7 @@ echo "*** Testing --inline"
|
||||||
prepare_testdir "$SOURCE/inline"
|
prepare_testdir "$SOURCE/inline"
|
||||||
# copy a random file to make sure it is ignored
|
# copy a random file to make sure it is ignored
|
||||||
cp "$f" "$TESTDIR/etc/sysusers.d/confuse.conf"
|
cp "$f" "$TESTDIR/etc/sysusers.d/confuse.conf"
|
||||||
$SYSUSERS --root="$TESTDIR" --inline \
|
"$SYSUSERS" --root="$TESTDIR" --inline \
|
||||||
"u u1 222 - - /bin/zsh" \
|
"u u1 222 - - /bin/zsh" \
|
||||||
"g g1 111"
|
"g g1 111"
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ echo "*** Testing --inline with --replace"
|
||||||
prepare_testdir "$SOURCE/inline"
|
prepare_testdir "$SOURCE/inline"
|
||||||
# copy a random file to make sure it is ignored
|
# copy a random file to make sure it is ignored
|
||||||
cp "$f" "$TESTDIR/etc/sysusers.d/confuse.conf"
|
cp "$f" "$TESTDIR/etc/sysusers.d/confuse.conf"
|
||||||
$SYSUSERS --root="$TESTDIR" \
|
"$SYSUSERS" --root="$TESTDIR" \
|
||||||
--inline \
|
--inline \
|
||||||
--replace=/etc/sysusers.d/confuse.conf \
|
--replace=/etc/sysusers.d/confuse.conf \
|
||||||
"u u1 222 - - /bin/zsh" \
|
"u u1 222 - - /bin/zsh" \
|
||||||
|
@ -105,7 +105,7 @@ compare "$SOURCE/inline" "(--inline --replace=…)"
|
||||||
|
|
||||||
echo "*** Testing --inline with no /etc"
|
echo "*** Testing --inline with no /etc"
|
||||||
rm -rf "${TESTDIR:?}/etc"
|
rm -rf "${TESTDIR:?}/etc"
|
||||||
$SYSUSERS --root="$TESTDIR" --inline \
|
"$SYSUSERS" --root="$TESTDIR" --inline \
|
||||||
"u u1 222 - - /bin/zsh" \
|
"u u1 222 - - /bin/zsh" \
|
||||||
"g g1 111"
|
"g g1 111"
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||||
echo "*** Running $f (with login.defs)"
|
echo "*** Running $f (with login.defs)"
|
||||||
prepare_testdir "${f%.input}"
|
prepare_testdir "${f%.input}"
|
||||||
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
||||||
$SYSUSERS --root="$TESTDIR"
|
"$SYSUSERS" --root="$TESTDIR"
|
||||||
|
|
||||||
# shellcheck disable=SC2050
|
# shellcheck disable=SC2050
|
||||||
[ @ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES@ = 1 ] && bound=555 || bound=$system_guid_max
|
[ @ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES@ = 1 ] && bound=555 || bound=$system_guid_max
|
||||||
|
@ -152,7 +152,7 @@ for f in $(find "$SOURCE"/test-*.input | sort -V); do
|
||||||
echo "*** Running $f (with login.defs symlinked)"
|
echo "*** Running $f (with login.defs symlinked)"
|
||||||
prepare_testdir "${f%.input}"
|
prepare_testdir "${f%.input}"
|
||||||
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
||||||
$SYSUSERS --root="$TESTDIR"
|
"$SYSUSERS" --root="$TESTDIR"
|
||||||
|
|
||||||
# shellcheck disable=SC2050
|
# shellcheck disable=SC2050
|
||||||
[ @ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES@ = 1 ] && bound=555 || bound=$system_guid_max
|
[ @ENABLE_COMPAT_MUTABLE_UID_BOUNDARIES@ = 1 ] && bound=555 || bound=$system_guid_max
|
||||||
|
@ -166,7 +166,7 @@ for f in $(find "$SOURCE"/unhappy-*.input | sort -V); do
|
||||||
echo "*** Running test $f"
|
echo "*** Running test $f"
|
||||||
prepare_testdir "${f%.input}"
|
prepare_testdir "${f%.input}"
|
||||||
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
cp "$f" "$TESTDIR/usr/lib/sysusers.d/test.conf"
|
||||||
SYSTEMD_LOG_LEVEL=info $SYSUSERS --root="$TESTDIR" 2>&1 | tail -n1 | sed -r 's/^[^:]+:[^:]+://' >"$TESTDIR/err"
|
SYSTEMD_LOG_LEVEL=info "$SYSUSERS" --root="$TESTDIR" 2>&1 | tail -n1 | sed -r 's/^[^:]+:[^:]+://' >"$TESTDIR/err"
|
||||||
if ! diff -u "$TESTDIR/err" "${f%.*}.expected-err"; then
|
if ! diff -u "$TESTDIR/err" "${f%.*}.expected-err"; then
|
||||||
echo >&2 "**** Unexpected error output for $f"
|
echo >&2 "**** Unexpected error output for $f"
|
||||||
cat >&2 "$TESTDIR/err"
|
cat >&2 "$TESTDIR/err"
|
||||||
|
|
|
@ -8,13 +8,15 @@ set -o pipefail
|
||||||
|
|
||||||
# Make sure the binary name fits into 15 characters
|
# Make sure the binary name fits into 15 characters
|
||||||
CORE_TEST_BIN="/tmp/test-dump"
|
CORE_TEST_BIN="/tmp/test-dump"
|
||||||
|
CORE_STACKTRACE_TEST_BIN="/tmp/test-stacktrace-dump"
|
||||||
|
MAKE_STACKTRACE_DUMP="/tmp/make-stacktrace-dump"
|
||||||
CORE_TEST_UNPRIV_BIN="/tmp/test-usr-dump"
|
CORE_TEST_UNPRIV_BIN="/tmp/test-usr-dump"
|
||||||
MAKE_DUMP_SCRIPT="/tmp/make-dump"
|
MAKE_DUMP_SCRIPT="/tmp/make-dump"
|
||||||
# Unset $PAGER so we don't have to use --no-pager everywhere
|
# Unset $PAGER so we don't have to use --no-pager everywhere
|
||||||
export PAGER=
|
export PAGER=
|
||||||
|
|
||||||
at_exit() {
|
at_exit() {
|
||||||
rm -fv -- "$CORE_TEST_BIN" "$CORE_TEST_UNPRIV_BIN" "$MAKE_DUMP_SCRIPT"
|
rm -fv -- "$CORE_TEST_BIN" "$CORE_TEST_UNPRIV_BIN" "$MAKE_DUMP_SCRIPT" "$MAKE_STACKTRACE_DUMP"
|
||||||
}
|
}
|
||||||
|
|
||||||
trap at_exit EXIT
|
trap at_exit EXIT
|
||||||
|
@ -225,3 +227,32 @@ systemd-run -t --property CoredumpFilter=default ls /tmp
|
||||||
(! coredumpctl dump --output=/dev/null --output=/dev/null "$CORE_TEST_BIN")
|
(! coredumpctl dump --output=/dev/null --output=/dev/null "$CORE_TEST_BIN")
|
||||||
(! coredumpctl debug --debugger=/bin/false)
|
(! coredumpctl debug --debugger=/bin/false)
|
||||||
(! coredumpctl debug --debugger=/bin/true --debugger-arguments='"')
|
(! coredumpctl debug --debugger=/bin/true --debugger-arguments='"')
|
||||||
|
|
||||||
|
# Test for EnterNamespace= feature
|
||||||
|
if pkgconf --atleast-version 0.192 libdw ; then
|
||||||
|
# dwfl_set_sysroot() is supported only in libdw-0.192 or newer.
|
||||||
|
cat > "$MAKE_STACKTRACE_DUMP" <<END
|
||||||
|
#!/bin/bash
|
||||||
|
mount -t tmpfs tmpfs /tmp
|
||||||
|
gcc -xc -O0 -g -o $CORE_STACKTRACE_TEST_BIN - <<EOF
|
||||||
|
void baz(void) { int *x = 0; *x = 42; }
|
||||||
|
void bar(void) { baz(); }
|
||||||
|
void foo(void) { bar(); }
|
||||||
|
int main(void) { foo(); return 0;}
|
||||||
|
EOF
|
||||||
|
$CORE_STACKTRACE_TEST_BIN
|
||||||
|
END
|
||||||
|
chmod +x "$MAKE_STACKTRACE_DUMP"
|
||||||
|
|
||||||
|
mkdir -p /run/systemd/coredump.conf.d/
|
||||||
|
printf '[Coredump]\nEnterNamespace=no' >/run/systemd/coredump.conf.d/99-enter-namespace.conf
|
||||||
|
|
||||||
|
unshare --pid --fork --mount-proc --mount --uts --ipc --net /bin/bash -c "$MAKE_STACKTRACE_DUMP" || :
|
||||||
|
coredumpctl -1 info "$CORE_STACKTRACE_TEST_BIN" | grep -zvqE 'baz.*bar.*foo'
|
||||||
|
|
||||||
|
printf '[Coredump]\nEnterNamespace=yes' >/run/systemd/coredump.conf.d/99-enter-namespace.conf
|
||||||
|
unshare --pid --fork --mount-proc --mount --uts --ipc --net /bin/bash -c "$MAKE_STACKTRACE_DUMP" || :
|
||||||
|
coredumpctl -1 info "$CORE_STACKTRACE_TEST_BIN" | grep -zqE 'baz.*bar.*foo'
|
||||||
|
else
|
||||||
|
echo "libdw doesn't not support setting sysroot, skipping EnterNamespace= test"
|
||||||
|
fi
|
||||||
|
|
Loading…
Reference in New Issue