Merge pull request #29748 from poettering/tgtmode
Storage target mode, inspired by "target disk mode" á la MacOS, but with NVMe-TCP
This commit is contained in:
@@ -379,6 +379,15 @@ CHANGES WITH 255 in spe:
|
||||
* Options and verbs in man pages are now tagged with the version they
|
||||
were first introduced in.
|
||||
|
||||
* A new component "systemd-storagetm" has been added, which exposes all
|
||||
local block devices as NVMe-TCP devices, fully automatically. It's
|
||||
hooked into a new target unit storage-target-mode.target that is
|
||||
suppsoed to be booted into via
|
||||
rd.systemd.unit=storage-target-mode.target on the kernel command
|
||||
line. This is intended to be used for installers and debugging to
|
||||
quickly get access to the local disk. It's inspired by MacOS "target
|
||||
disk mode".
|
||||
|
||||
Contributions from: 김인수, Abderrahim Kitouni, Adam Williamson,
|
||||
Alexandre Peixoto Ferreira, Alex Hudspith, Alvin Alvarado,
|
||||
André Paiusco, Antonio Alvarez Feijoo, Anton Lundin,
|
||||
|
||||
@@ -175,18 +175,18 @@ Features:
|
||||
* systemd-repart: add support for formatting dm-crypt + dm-integrity file
|
||||
systems.
|
||||
|
||||
* homed: add small tool that exposes a homed home dir via nvme-over-tcp (just a
|
||||
bunch of sysfs writes). Then, teach homed/pam_systemd_homed with a user name
|
||||
such as lennart%nvmettcp_192.168.100.77_8787_nqn to log in from any linux
|
||||
host with the same home dir. Similar maybe for nbd, iscsi? this should then
|
||||
first ask for the local root pw, to authenticate that logging in like this is
|
||||
ok, and would then be followed by another password prompt asking for the
|
||||
user's own password. Also, do something similar for CIFS: if you log in via
|
||||
* homed: use systemd-storagetm to expose home dirs via nvme-tcp. Then,
|
||||
teach homed/pam_systemd_homed with a user name such as
|
||||
lennart%nvme_tcp_192.168.100.77_8787 to log in from any linux host with the
|
||||
same home dir. Similar maybe for nbd, iscsi? this should then first ask for
|
||||
the local root pw, to authenticate that logging in like this is ok, and would
|
||||
then be followed by another password prompt asking for the user's own
|
||||
password. Also, do something similar for CIFS: if you log in via
|
||||
lennart%cifs-someserver_someshare, then set up the homed dir for it
|
||||
automatically. The PAM module should update the user name used for login to the
|
||||
short version once it set up the user. Some care should be taken, so that the
|
||||
long version can be still be resolved via NSS afterwards, to deal with PAM
|
||||
clients that do not support PAM sessions where PAM_USER changes half-way.
|
||||
automatically. The PAM module should update the user name used for login to
|
||||
the short version once it set up the user. Some care should be taken, so that
|
||||
the long version can be still be resolved via NSS afterwards, to deal with
|
||||
PAM clients that do not support PAM sessions where PAM_USER changes half-way.
|
||||
|
||||
* redefine /var/lib/extensions/ as the dir one can place all three of sysext,
|
||||
confext as well is multi-modal DDIs that qualify as both. Then introduce
|
||||
|
||||
@@ -1045,6 +1045,7 @@ manpages = [
|
||||
['systemd-socket-proxyd', '8', [], ''],
|
||||
['systemd-soft-reboot.service', '8', [], ''],
|
||||
['systemd-stdio-bridge', '1', [], ''],
|
||||
['systemd-storagetm.service', '8', ['systemd-storagetm'], 'ENABLE_STORAGETM'],
|
||||
['systemd-stub',
|
||||
'7',
|
||||
['linuxaa64.efi.stub', 'linuxia32.efi.stub', 'linuxx64.efi.stub', 'sd-stub'],
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--*-nxml-*-->
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
|
||||
<refentry id="systemd-storagetm.service" conditional='ENABLE_STORAGETM'
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<refentryinfo>
|
||||
<title>systemd-storagetm.service</title>
|
||||
<productname>systemd</productname>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>systemd-storagetm.service</refentrytitle>
|
||||
<manvolnum>8</manvolnum>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>systemd-storagetm.service</refname>
|
||||
<refname>systemd-storagetm</refname>
|
||||
<refpurpose>Exposes all local block devices as NVMe-TCP mass storage devices</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<para><filename>systemd-storagetm.service</filename></para>
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>/usr/lib/systemd/systemd-storagetm</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="opt"><replaceable>DEVICE</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para><filename>systemd-storagetm.service</filename> is a service that exposes all local block devices as
|
||||
NVMe-TCP mass storage devices. Its primary use-case is to be invoked by the
|
||||
<filename>storage-target-mode.target</filename> unit that can be booted into.</para>
|
||||
|
||||
<para>Warning: the NVMe disks are currently exposed without authentication or encryption, in read/write
|
||||
mode. This means network peers may read from and write to the device without any restrictions. This
|
||||
functionality should hence only be used in a local setup.</para>
|
||||
|
||||
<para>Note that to function properly networking must be configured too. The recommended mechanism to boot
|
||||
into a storage target mode is by adding <literal>rd.systemd.unit=storage-target-mode.target
|
||||
ip=link-local</literal> on the kernel command line. Note that <literal>ip=link-local</literal> only
|
||||
configures link-local IP, i.e. IPv4LL and IPv6LL, which means non-routable addresses. This is done for
|
||||
security reasons, so that only systems on the local link can access the devices. Use
|
||||
<literal>ip=dhcp</literal> to assign routable addresses too. For further details see
|
||||
<citerefentry><refentrytitle>systemd-network-generator.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
||||
|
||||
<para>Unless the <option>--all</option> switch is used expects one or more block devices or regular files to expose
|
||||
via NVMe-TCP as argument.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Options</title>
|
||||
|
||||
<para>The following options are understood:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>--nqn=</option></term>
|
||||
<listitem><para>Takes a string. If specified configures the NVMe Qualified Name to use for the
|
||||
exposed NVMe-TCP mass storage devices. The NQN should follow the syntax described in <ulink
|
||||
url="https://nvmexpress.org/wp-content/uploads/NVM-Express-Base-Specification-2.0c-2022.10.04-Ratified.pdf">NVM
|
||||
Express Base Specification 2.0c</ulink>, section 4.5 "NVMe Qualified Names". Note that the NQN
|
||||
specified here will be suffixed with a dot and the the block device name before it is exposed on the
|
||||
NVMe target. If not specified defaults to
|
||||
<literal>nqn.2023-10.io.systemd:storagetm.<replaceable>ID</replaceable></literal>, where ID is
|
||||
replaced by a 128bit ID derived from
|
||||
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--all</option></term>
|
||||
<term><option>-a</option></term>
|
||||
|
||||
<listitem><para>If specified exposes all local block devices via NVMe-TCP, current and future
|
||||
(i.e. it watches block devices come and go and updates the NVMe-TCP list as needed). Note that by
|
||||
default any block devices that originate on the same block device as the block device backing the
|
||||
current root file system are excluded. If the switch is specified twice this safety mechanism is
|
||||
disabled.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v255"/></listitem>
|
||||
</varlistentry>
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
<para>
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||
<citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
||||
@@ -83,6 +83,7 @@
|
||||
<filename>sockets.target</filename>,
|
||||
<filename>soft-reboot.target</filename>,
|
||||
<filename>sound.target</filename>,
|
||||
<filename>storage-target-mode.target</filename>,
|
||||
<filename>suspend.target</filename>,
|
||||
<filename>swap.target</filename>,
|
||||
<filename>sysinit.target</filename>,
|
||||
@@ -767,6 +768,18 @@
|
||||
<xi:include href="version-info.xml" xpointer="v254"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>storage-target-mode.target</filename></term>
|
||||
<listitem>
|
||||
<para>A special target unit that can be booted into that selects the "Storage Target Mode" for
|
||||
the OS. In this mode all local storage disks are exposed to external systems as block
|
||||
devices. This invokes
|
||||
<citerefentry><refentrytitle>systemd-storagetm.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
|
||||
which exposes all local disks as NVMe-TCP devices for access over the network. It might as well
|
||||
invoke other services too that make local disks available via other mechanisms.</para>
|
||||
<xi:include href="version-info.xml" xpointer="v255"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><filename>suspend.target</filename></term>
|
||||
<listitem>
|
||||
|
||||
+5
-1
@@ -1533,6 +1533,8 @@ have = get_option('sysupdate').require(
|
||||
error_message : 'fdisk and openssl required').allowed()
|
||||
conf.set10('ENABLE_SYSUPDATE', have)
|
||||
|
||||
conf.set10('ENABLE_STORAGETM', get_option('storagetm'))
|
||||
|
||||
have = get_option('importd').require(
|
||||
conf.get('HAVE_LIBCURL') == 1 and
|
||||
conf.get('HAVE_OPENSSL_OR_GCRYPT') == 1 and
|
||||
@@ -2196,10 +2198,11 @@ subdir('src/systemctl')
|
||||
subdir('src/sysupdate')
|
||||
subdir('src/sysusers')
|
||||
subdir('src/sysv-generator')
|
||||
subdir('src/storagetm')
|
||||
subdir('src/timedate')
|
||||
subdir('src/timesync')
|
||||
subdir('src/tpm2-setup')
|
||||
subdir('src/tmpfiles')
|
||||
subdir('src/tpm2-setup')
|
||||
subdir('src/tty-ask-password-agent')
|
||||
subdir('src/update-done')
|
||||
subdir('src/update-utmp')
|
||||
@@ -2793,6 +2796,7 @@ foreach tuple : [
|
||||
['systemd-analyze', conf.get('ENABLE_ANALYZE') == 1],
|
||||
['sysupdate'],
|
||||
['sysusers'],
|
||||
['storagetm'],
|
||||
['timedated'],
|
||||
['timesyncd'],
|
||||
['tmpfiles'],
|
||||
|
||||
@@ -158,6 +158,8 @@ option('quotacheck', type : 'boolean',
|
||||
description : 'support for the quotacheck tools')
|
||||
option('sysusers', type : 'boolean',
|
||||
description : 'support for the sysusers configuration')
|
||||
option('storagetm', type : 'boolean',
|
||||
description : 'support for Storage Target Mode')
|
||||
option('tmpfiles', type : 'boolean',
|
||||
description : 'support for tmpfiles.d')
|
||||
option('importd', type : 'feature', deprecated : { 'true' : 'enabled', 'false' : 'disabled' },
|
||||
|
||||
@@ -988,3 +988,11 @@ const char *accmode_to_string(int flags) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
char *format_proc_pid_fd_path(char buf[static PROC_PID_FD_PATH_MAX], pid_t pid, int fd) {
|
||||
assert(buf);
|
||||
assert(fd >= 0);
|
||||
assert(pid >= 0);
|
||||
assert_se(snprintf_ok(buf, PROC_PID_FD_PATH_MAX, "/proc/" PID_FMT "/fd/%i", pid == 0 ? getpid_cached() : pid, fd));
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -131,6 +131,16 @@ static inline char *format_proc_fd_path(char buf[static PROC_FD_PATH_MAX], int f
|
||||
#define FORMAT_PROC_FD_PATH(fd) \
|
||||
format_proc_fd_path((char[PROC_FD_PATH_MAX]) {}, (fd))
|
||||
|
||||
/* The maximum length a buffer for a /proc/<pid>/fd/<fd> path needs */
|
||||
#define PROC_PID_FD_PATH_MAX \
|
||||
(STRLEN("/proc//fd/") + DECIMAL_STR_MAX(pid_t) + DECIMAL_STR_MAX(int))
|
||||
|
||||
char *format_proc_pid_fd_path(char buf[static PROC_PID_FD_PATH_MAX], pid_t pid, int fd);
|
||||
|
||||
/* Kinda the same as FORMAT_PROC_FD_PATH(), but goes by PID rather than "self" symlink */
|
||||
#define FORMAT_PROC_PID_FD_PATH(pid, fd) \
|
||||
format_proc_pid_fd_path((char[PROC_PID_FD_PATH_MAX]) {}, (pid), (fd))
|
||||
|
||||
const char *accmode_to_string(int flags);
|
||||
|
||||
/* Like ASSERT_PTR, but for fds */
|
||||
|
||||
@@ -134,6 +134,8 @@ const char *special_glyph_full(SpecialGlyph code, bool force_utf) {
|
||||
[SPECIAL_GLYPH_SPARKLES] = u8"✨",
|
||||
[SPECIAL_GLYPH_LOW_BATTERY] = u8"🪫",
|
||||
[SPECIAL_GLYPH_WARNING_SIGN] = u8"⚠️",
|
||||
[SPECIAL_GLYPH_COMPUTER_DISK] = u8"💽",
|
||||
[SPECIAL_GLYPH_WORLD] = u8"🌍",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ typedef enum SpecialGlyph {
|
||||
SPECIAL_GLYPH_SPARKLES,
|
||||
SPECIAL_GLYPH_LOW_BATTERY,
|
||||
SPECIAL_GLYPH_WARNING_SIGN,
|
||||
SPECIAL_GLYPH_COMPUTER_DISK,
|
||||
SPECIAL_GLYPH_WORLD,
|
||||
_SPECIAL_GLYPH_MAX,
|
||||
_SPECIAL_GLYPH_INVALID = -EINVAL,
|
||||
} SpecialGlyph;
|
||||
|
||||
@@ -2,10 +2,12 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "fd-util.h"
|
||||
@@ -14,6 +16,7 @@
|
||||
#include "macro.h"
|
||||
#include "missing_fcntl.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
|
||||
int make_lock_file_at(int dir_fd, const char *p, int operation, LockFile *ret) {
|
||||
_cleanup_close_ int fd = -EBADF, dfd = -EBADF;
|
||||
@@ -186,3 +189,89 @@ int lock_generic(int fd, LockType type, int operation) {
|
||||
assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeout) {
|
||||
_cleanup_(sigkill_waitp) pid_t pid = 0;
|
||||
int r;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
/* A version of lock_generic(), but with a time-out. We do this in a child process, since the kernel
|
||||
* APIs natively don't support a timeout. We set a SIGALRM timer that will kill the child after the
|
||||
* timeout is hit. Returns -ETIMEDOUT if the time-out is hit, and 0 on success.
|
||||
*
|
||||
* This only works for BSD and UNPOSIX locks, as only those are fd-bound, and hence can be acquired
|
||||
* from any process that has access to the fd. POSIX locks OTOH are process-bound, and hence if we'd
|
||||
* acquire them in a child process they'd remain unlocked in the parent. */
|
||||
|
||||
if (type == LOCK_NONE)
|
||||
return 0;
|
||||
if (!IN_SET(type, LOCK_BSD, LOCK_UNPOSIX)) /* Not for POSIX locks, see above. */
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* First, try without forking anything off */
|
||||
r = lock_generic(fd, type, operation | (timeout == USEC_INFINITY ? 0 : LOCK_NB));
|
||||
if (r != -EAGAIN || timeout == 0 || FLAGS_SET(operation, LOCK_NB))
|
||||
return r;
|
||||
|
||||
/* If that didn't work, try with a child */
|
||||
|
||||
r = safe_fork("(sd-flock)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to flock block device in child process: %m");
|
||||
if (r == 0) {
|
||||
struct sigevent sev = {
|
||||
.sigev_notify = SIGEV_SIGNAL,
|
||||
.sigev_signo = SIGALRM,
|
||||
};
|
||||
timer_t id = 0;
|
||||
|
||||
if (timer_create(CLOCK_MONOTONIC, &sev, &id) < 0) {
|
||||
log_error_errno(errno, "Failed to allocate CLOCK_MONOTONIC timer: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct itimerspec its = {};
|
||||
timespec_store(&its.it_value, timeout);
|
||||
|
||||
if (timer_settime(id, /* flags= */ 0, &its, NULL) < 0) {
|
||||
log_error_errno(errno, "Failed to start CLOCK_MONOTONIC timer: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (lock_generic(fd, type, operation) < 0) {
|
||||
log_error_errno(errno, "Unable to get an exclusive lock on the device: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
siginfo_t status;
|
||||
r = wait_for_terminate(pid, &status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
TAKE_PID(pid);
|
||||
|
||||
switch (status.si_code) {
|
||||
|
||||
case CLD_EXITED:
|
||||
if (status.si_status != EXIT_SUCCESS)
|
||||
return -EPROTO;
|
||||
|
||||
return 0;
|
||||
|
||||
case CLD_KILLED:
|
||||
if (status.si_status == SIGALRM)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
_fallthrough_;
|
||||
|
||||
case CLD_DUMPED:
|
||||
return -EPROTO;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,3 +41,5 @@ typedef enum LockType {
|
||||
} LockType;
|
||||
|
||||
int lock_generic(int fd, LockType type, int operation);
|
||||
|
||||
int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeout);
|
||||
|
||||
@@ -273,6 +273,7 @@ libbasic = static_library(
|
||||
include_directories : basic_includes,
|
||||
dependencies : [libcap,
|
||||
libm,
|
||||
librt,
|
||||
threads,
|
||||
userspace],
|
||||
c_args : ['-fvisibility=default'],
|
||||
|
||||
@@ -219,7 +219,7 @@ int userns_acquire(const char *uid_map, const char *gid_map) {
|
||||
* and then kills the process again. This way we have a userns fd that is not bound to any
|
||||
* process. We can use that for file system mounts and similar. */
|
||||
|
||||
r = safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_NEW_USERNS, &pid);
|
||||
r = safe_fork("(sd-mkuserns)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_NEW_USERNS, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
|
||||
@@ -1380,6 +1380,12 @@ pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata) {
|
||||
return pid;
|
||||
}
|
||||
|
||||
static int fork_flags_to_signal(ForkFlags flags) {
|
||||
return (flags & FORK_DEATHSIG_SIGTERM) ? SIGTERM :
|
||||
(flags & FORK_DEATHSIG_SIGINT) ? SIGINT :
|
||||
SIGKILL;
|
||||
}
|
||||
|
||||
int safe_fork_full(
|
||||
const char *name,
|
||||
const int stdio_fds[3],
|
||||
@@ -1409,9 +1415,10 @@ int safe_fork_full(
|
||||
fflush(stderr); /* This one shouldn't be necessary, stderr should be unbuffered anyway, but let's better be safe than sorry */
|
||||
}
|
||||
|
||||
if (flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG)) {
|
||||
/* We temporarily block all signals, so that the new child has them blocked initially. This way, we can
|
||||
* be sure that SIGTERMs are not lost we might send to the child. */
|
||||
if (flags & (FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT)) {
|
||||
/* We temporarily block all signals, so that the new child has them blocked initially. This
|
||||
* way, we can be sure that SIGTERMs are not lost we might send to the child. (Note that for
|
||||
* FORK_DEATHSIG_SIGKILL we don't bother, since it cannot be blocked anyway.) */
|
||||
|
||||
assert_se(sigfillset(&ss) >= 0);
|
||||
block_signals = block_all = true;
|
||||
@@ -1512,8 +1519,8 @@ int safe_fork_full(
|
||||
r, "Failed to rename process, ignoring: %m");
|
||||
}
|
||||
|
||||
if (flags & (FORK_DEATHSIG|FORK_DEATHSIG_SIGINT))
|
||||
if (prctl(PR_SET_PDEATHSIG, (flags & FORK_DEATHSIG_SIGINT) ? SIGINT : SIGTERM) < 0) {
|
||||
if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGKILL))
|
||||
if (prctl(PR_SET_PDEATHSIG, fork_flags_to_signal(flags)) < 0) {
|
||||
log_full_errno(prio, errno, "Failed to set death signal: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
@@ -1538,7 +1545,7 @@ int safe_fork_full(
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FORK_DEATHSIG) {
|
||||
if (flags & (FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL|FORK_DEATHSIG_SIGINT)) {
|
||||
pid_t ppid;
|
||||
/* Let's see if the parent PID is still the one we started from? If not, then the parent
|
||||
* already died by the time we set PR_SET_PDEATHSIG, hence let's emulate the effect */
|
||||
@@ -1547,8 +1554,9 @@ int safe_fork_full(
|
||||
if (ppid == 0)
|
||||
/* Parent is in a different PID namespace. */;
|
||||
else if (ppid != original_pid) {
|
||||
log_debug("Parent died early, raising SIGTERM.");
|
||||
(void) raise(SIGTERM);
|
||||
int sig = fork_flags_to_signal(flags);
|
||||
log_debug("Parent died early, raising %s.", signal_to_string(sig));
|
||||
(void) raise(sig);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
@@ -1664,7 +1672,7 @@ int namespace_fork(
|
||||
r = safe_fork_full(outer_name,
|
||||
NULL,
|
||||
except_fds, n_except_fds,
|
||||
(flags|FORK_DEATHSIG) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
|
||||
(flags|FORK_DEATHSIG_SIGINT|FORK_DEATHSIG_SIGTERM|FORK_DEATHSIG_SIGKILL) & ~(FORK_REOPEN_LOG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE), ret_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
+16
-15
@@ -160,22 +160,23 @@ pid_t clone_with_nested_stack(int (*fn)(void *), int flags, void *userdata);
|
||||
typedef enum ForkFlags {
|
||||
FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
|
||||
FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
|
||||
FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child to SIGTERM */
|
||||
FORK_DEATHSIG_SIGTERM = 1 << 2, /* Set PR_DEATHSIG in the child to SIGTERM */
|
||||
FORK_DEATHSIG_SIGINT = 1 << 3, /* Set PR_DEATHSIG in the child to SIGINT */
|
||||
FORK_REARRANGE_STDIO = 1 << 4, /* Connect 0,1,2 to specified fds or /dev/null */
|
||||
FORK_REOPEN_LOG = 1 << 5, /* Reopen log connection */
|
||||
FORK_LOG = 1 << 6, /* Log above LOG_DEBUG log level about failures */
|
||||
FORK_WAIT = 1 << 7, /* Wait until child exited */
|
||||
FORK_NEW_MOUNTNS = 1 << 8, /* Run child in its own mount namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
|
||||
FORK_MOUNTNS_SLAVE = 1 << 9, /* Make child's mount namespace MS_SLAVE */
|
||||
FORK_PRIVATE_TMP = 1 << 10, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */
|
||||
FORK_RLIMIT_NOFILE_SAFE = 1 << 11, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
|
||||
FORK_STDOUT_TO_STDERR = 1 << 12, /* Make stdout a copy of stderr */
|
||||
FORK_FLUSH_STDIO = 1 << 13, /* fflush() stdout (and stderr) before forking */
|
||||
FORK_NEW_USERNS = 1 << 14, /* Run child in its own user namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
|
||||
FORK_CLOEXEC_OFF = 1 << 15, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */
|
||||
FORK_KEEP_NOTIFY_SOCKET = 1 << 16, /* Unless this specified, $NOTIFY_SOCKET will be unset. */
|
||||
FORK_DETACH = 1 << 17, /* Double fork if needed to ensure PID1/subreaper is parent */
|
||||
FORK_DEATHSIG_SIGKILL = 1 << 4, /* Set PR_DEATHSIG in the child to SIGKILL */
|
||||
FORK_REARRANGE_STDIO = 1 << 5, /* Connect 0,1,2 to specified fds or /dev/null */
|
||||
FORK_REOPEN_LOG = 1 << 6, /* Reopen log connection */
|
||||
FORK_LOG = 1 << 7, /* Log above LOG_DEBUG log level about failures */
|
||||
FORK_WAIT = 1 << 8, /* Wait until child exited */
|
||||
FORK_NEW_MOUNTNS = 1 << 9, /* Run child in its own mount namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
|
||||
FORK_MOUNTNS_SLAVE = 1 << 10, /* Make child's mount namespace MS_SLAVE */
|
||||
FORK_PRIVATE_TMP = 1 << 11, /* Mount new /tmp/ in the child (combine with FORK_NEW_MOUNTNS!) */
|
||||
FORK_RLIMIT_NOFILE_SAFE = 1 << 12, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
|
||||
FORK_STDOUT_TO_STDERR = 1 << 13, /* Make stdout a copy of stderr */
|
||||
FORK_FLUSH_STDIO = 1 << 14, /* fflush() stdout (and stderr) before forking */
|
||||
FORK_NEW_USERNS = 1 << 15, /* Run child in its own user namespace 💣 DO NOT USE IN THREADED PROGRAMS! 💣 */
|
||||
FORK_CLOEXEC_OFF = 1 << 16, /* In the child: turn off O_CLOEXEC on all fds in except_fds[] */
|
||||
FORK_KEEP_NOTIFY_SOCKET = 1 << 17, /* Unless this specified, $NOTIFY_SOCKET will be unset. */
|
||||
FORK_DETACH = 1 << 18, /* Double fork if needed to ensure PID1/subreaper is parent */
|
||||
} ForkFlags;
|
||||
|
||||
int safe_fork_full(
|
||||
|
||||
@@ -1204,7 +1204,7 @@ int openpt_allocate_in_namespace(pid_t pid, int flags, char **ret_slave) {
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
|
||||
return -errno;
|
||||
|
||||
r = namespace_fork("(sd-openptns)", "(sd-openpt)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
r = namespace_fork("(sd-openptns)", "(sd-openpt)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
|
||||
pidnsfd, mntnsfd, -1, usernsfd, rootfd, &child);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -1255,7 +1255,7 @@ int open_terminal_in_namespace(pid_t pid, const char *name, int mode) {
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
|
||||
return -errno;
|
||||
|
||||
r = namespace_fork("(sd-terminalns)", "(sd-terminal)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
r = namespace_fork("(sd-terminalns)", "(sd-terminal)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
|
||||
pidnsfd, mntnsfd, -1, usernsfd, rootfd, &child);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1044,7 +1044,7 @@ int parse_timestamp(const char *t, usec_t *ret) {
|
||||
if (shared == MAP_FAILED)
|
||||
return negative_errno();
|
||||
|
||||
r = safe_fork("(sd-timestamp)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(sd-timestamp)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_WAIT, NULL);
|
||||
if (r < 0) {
|
||||
(void) munmap(shared, sizeof *shared);
|
||||
return r;
|
||||
|
||||
@@ -930,7 +930,7 @@ int exec_setup_credentials(
|
||||
if (r < 0 && r != -EEXIST)
|
||||
return r;
|
||||
|
||||
r = safe_fork("(sd-mkdcreds)", FORK_DEATHSIG|FORK_WAIT|FORK_NEW_MOUNTNS, NULL);
|
||||
r = safe_fork("(sd-mkdcreds)", FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_NEW_MOUNTNS, NULL);
|
||||
if (r < 0) {
|
||||
_cleanup_(rmdir_and_freep) char *u = NULL; /* remove the temporary workspace if we can */
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
@@ -2136,7 +2136,7 @@ static int setup_private_users(uid_t ouid, gid_t ogid, uid_t uid, gid_t gid) {
|
||||
if (pipe2(errno_pipe, O_CLOEXEC) < 0)
|
||||
return -errno;
|
||||
|
||||
r = safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &pid);
|
||||
r = safe_fork("(sd-userns)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
+1
-1
@@ -5426,7 +5426,7 @@ int unit_fork_helper_process(Unit *u, const char *name, PidRef *ret) {
|
||||
|
||||
(void) unit_realize_cgroup(u);
|
||||
|
||||
r = safe_fork(name, FORK_REOPEN_LOG|FORK_DEATHSIG, &pid);
|
||||
r = safe_fork(name, FORK_REOPEN_LOG|FORK_DEATHSIG_SIGTERM, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) {
|
||||
|
||||
@@ -1443,7 +1443,7 @@ static int forward_coredump_to_container(Context *context) {
|
||||
return log_debug_errno(r, "Failed to join namespaces of PID " PID_FMT ": %m", pid);
|
||||
|
||||
r = namespace_fork("(sd-coredumpns)", "(sd-coredump)", NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM,
|
||||
pidnsfd, mntnsfd, netnsfd, usernsfd, rootfd, &child);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to fork into namespaces of PID " PID_FMT ": %m", pid);
|
||||
|
||||
@@ -1253,7 +1253,7 @@ static int run_debug(int argc, char **argv, void *userdata) {
|
||||
|
||||
fork_name = strjoina("(", debugger_call[0], ")");
|
||||
|
||||
r = safe_fork(fork_name, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_FLUSH_STDIO, &pid);
|
||||
r = safe_fork(fork_name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_FLUSH_STDIO, &pid);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
if (r == 0) {
|
||||
|
||||
+1
-1
@@ -168,7 +168,7 @@ static int found_override(const char *top, const char *bottom) {
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
r = safe_fork("(diff)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
r = safe_fork("(diff)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
+1
-1
@@ -339,7 +339,7 @@ static int run(int argc, char *argv[]) {
|
||||
pipe(progress_pipe) < 0)
|
||||
return log_error_errno(errno, "pipe(): %m");
|
||||
|
||||
r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
|
||||
r = safe_fork("(fsck)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
+1
-1
@@ -2025,7 +2025,7 @@ static int with_home(int argc, char *argv[], void *userdata) {
|
||||
if (r < 0)
|
||||
return bus_log_parse_error(r);
|
||||
|
||||
r = safe_fork("(with)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REOPEN_LOG, &pid);
|
||||
r = safe_fork("(with)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE|FORK_REOPEN_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -1184,7 +1184,7 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord
|
||||
r = safe_fork_full("(sd-homework)",
|
||||
(int[]) { stdin_fd, stdout_fd, STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG, &pid);
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
@@ -2080,7 +2080,7 @@ int home_killall(Home *h) {
|
||||
|
||||
/* Let's kill everything matching the specified UID */
|
||||
r = safe_fork("(sd-killer)",
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG|FORK_REOPEN_LOG,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_WAIT|FORK_LOG|FORK_REOPEN_LOG,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -91,7 +91,7 @@ int home_setup_cifs(
|
||||
if (!strextend_with_separator(&options, ",", h->cifs_extra_mount_options))
|
||||
return log_oom();
|
||||
|
||||
r = safe_fork("(mount)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR, &mount_pid);
|
||||
r = safe_fork("(mount)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR, &mount_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -314,7 +314,7 @@ int home_setup_fscrypt(
|
||||
|
||||
if (uid_is_valid(h->uid)) {
|
||||
r = safe_fork("(sd-addkey)",
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_REOPEN_LOG,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_REOPEN_LOG,
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed install encryption key in user's keyring: %m");
|
||||
|
||||
@@ -228,7 +228,7 @@ static int run_fsck(const char *node, const char *fstype) {
|
||||
}
|
||||
|
||||
r = safe_fork("(fsck)",
|
||||
FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
|
||||
FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
|
||||
&fsck_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -2596,7 +2596,7 @@ static int ext4_offline_resize_fs(
|
||||
|
||||
/* resize2fs requires that the file system is force checked first, do so. */
|
||||
r = safe_fork("(e2fsck)",
|
||||
FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
|
||||
FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
|
||||
&fsck_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -2628,7 +2628,7 @@ static int ext4_offline_resize_fs(
|
||||
|
||||
/* Resize the thing */
|
||||
r = safe_fork("(e2resize)",
|
||||
FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
|
||||
FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS,
|
||||
&resize_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -39,7 +39,7 @@ int import_fork_tar_x(const char *path, pid_t *ret) {
|
||||
r = safe_fork_full("(tar)",
|
||||
(int[]) { pipefd[0], -EBADF, STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
@@ -108,7 +108,7 @@ int import_fork_tar_c(const char *path, pid_t *ret) {
|
||||
r = safe_fork_full("(tar)",
|
||||
(int[]) { -EBADF, pipefd[1], STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -369,7 +369,7 @@ static int transfer_start(Transfer *t) {
|
||||
r = safe_fork_full("(sd-transfer)",
|
||||
(int[]) { t->stdin_fd, t->stdout_fd < 0 ? pipefd[1] : t->stdout_fd, pipefd[1] },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO, &t->pid);
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO, &t->pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -417,7 +417,7 @@ static int verify_gpg(
|
||||
r = safe_fork_full("(gpg)",
|
||||
(int[]) { gpg_pipe[0], -EBADF, STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -91,7 +91,7 @@ static int spawn_child(const char* child, char** argv) {
|
||||
r = safe_fork_full("(remote)",
|
||||
(int[]) {STDIN_FILENO, fd[1], STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &child_pid);
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &child_pid);
|
||||
if (r < 0) {
|
||||
safe_close_pair(fd);
|
||||
return r;
|
||||
|
||||
@@ -51,7 +51,7 @@ int bus_container_connect_socket(sd_bus *b) {
|
||||
if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, pair) < 0)
|
||||
return log_debug_errno(errno, "Failed to create a socket pair: %m");
|
||||
|
||||
r = namespace_fork("(sd-buscntrns)", "(sd-buscntr)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
r = namespace_fork("(sd-buscntrns)", "(sd-buscntr)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
|
||||
pidnsfd, mntnsfd, -1, usernsfd, rootfd, &child);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to create namespace for (sd-buscntr): %m");
|
||||
|
||||
@@ -761,6 +761,12 @@ int sd_netlink_detach_event(sd_netlink *nl) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
sd_event* sd_netlink_get_event(sd_netlink *nl) {
|
||||
assert_return(nl, NULL);
|
||||
|
||||
return nl->event;
|
||||
}
|
||||
|
||||
int netlink_add_match_internal(
|
||||
sd_netlink *nl,
|
||||
sd_netlink_slot **ret_slot,
|
||||
|
||||
+1
-1
@@ -300,7 +300,7 @@ static int run(int argc, char *argv[]) {
|
||||
if (!arguments)
|
||||
return log_oom();
|
||||
|
||||
r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
r = safe_fork("(inhibit)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -136,7 +136,7 @@ static int brightness_writer_fork(BrightnessWriter *w) {
|
||||
assert(w->child == 0);
|
||||
assert(!w->child_event_source);
|
||||
|
||||
r = safe_fork("(sd-bright)", FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &w->child);
|
||||
r = safe_fork("(sd-bright)", FORK_DEATHSIG_SIGKILL|FORK_REARRANGE_STDIO|FORK_CLOSE_ALL_FDS|FORK_LOG|FORK_REOPEN_LOG, &w->child);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -248,7 +248,7 @@ int bus_machine_method_get_addresses(sd_bus_message *message, void *userdata, sd
|
||||
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
|
||||
return -errno;
|
||||
|
||||
r = namespace_fork("(sd-addrns)", "(sd-addr)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
r = namespace_fork("(sd-addrns)", "(sd-addr)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
|
||||
-1, -1, netns_fd, -1, -1, &child);
|
||||
if (r < 0)
|
||||
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
|
||||
@@ -382,7 +382,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
|
||||
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, pair) < 0)
|
||||
return -errno;
|
||||
|
||||
r = namespace_fork("(sd-osrelns)", "(sd-osrel)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
r = namespace_fork("(sd-osrelns)", "(sd-osrel)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
|
||||
pidns_fd, mntns_fd, -1, -1, root_fd,
|
||||
&child);
|
||||
if (r < 0)
|
||||
@@ -1103,7 +1103,7 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
|
||||
return -errno;
|
||||
|
||||
r = namespace_fork("(sd-openrootns)", "(sd-openroot)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
r = namespace_fork("(sd-openrootns)", "(sd-openroot)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
|
||||
-1, mntns_fd, -1, -1, root_fd, &child);
|
||||
if (r < 0)
|
||||
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
|
||||
|
||||
@@ -30,7 +30,7 @@ static int spawn_getent(const char *database, const char *key, pid_t *rpid) {
|
||||
|
||||
r = safe_fork_full("(getent)",
|
||||
(int[]) { -EBADF, pipe_fds[1], -EBADF }, NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
&pid);
|
||||
if (r < 0) {
|
||||
safe_close_pair(pipe_fds);
|
||||
|
||||
+1
-1
@@ -5276,7 +5276,7 @@ static int run_container(
|
||||
if (arg_private_network) {
|
||||
/* Move network interfaces back to the parent network namespace. We use `safe_fork`
|
||||
* to avoid having to move the parent to the child network namespace. */
|
||||
r = safe_fork(NULL, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG, NULL);
|
||||
r = safe_fork(NULL, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -4673,7 +4673,7 @@ static int partition_populate_filesystem(Context *context, Partition *p, const c
|
||||
* appear in the host namespace. Hence we fork a child that has its own file system namespace and
|
||||
* detached mount propagation. */
|
||||
|
||||
r = safe_fork("(sd-copy)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL);
|
||||
r = safe_fork("(sd-copy)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -411,7 +411,7 @@ static int portable_extract_by_path(
|
||||
if (socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, seq) < 0)
|
||||
return log_debug_errno(errno, "Failed to allocated SOCK_SEQPACKET socket: %m");
|
||||
|
||||
r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_LOG, &child);
|
||||
r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE|FORK_LOG, &child);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -79,7 +79,7 @@ static int run(int argc, char *argv[]) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_fork("(quotacheck)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_WAIT|FORK_LOG, NULL);
|
||||
r = safe_fork("(quotacheck)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_WAIT|FORK_LOG, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -51,7 +51,7 @@ static int do_remount(const char *path, bool force_rw, Hashmap **pids) {
|
||||
log_debug("Remounting %s...", path);
|
||||
|
||||
r = safe_fork(force_rw ? "(remount-rw)" : "(remount)",
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -151,7 +151,7 @@ static void *tls_dns_server(void *p) {
|
||||
r = safe_fork_full("(test-resolved-stream-tls-openssl)",
|
||||
(int[]) { fd_tls, fd_tls, STDOUT_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_REOPEN_LOG,
|
||||
&openssl_pid);
|
||||
assert_se(r >= 0);
|
||||
if (r == 0) {
|
||||
@@ -336,7 +336,7 @@ static void try_isolate_network(void) {
|
||||
/* First test if CLONE_NEWUSER/CLONE_NEWNET can actually work for us, i.e. we can open the namespaces
|
||||
* and then still access the build dir we are run from. We do that in a child process since it's
|
||||
* nasty if we have to go back from the namespace once we entered it and realized it cannot work. */
|
||||
r = safe_fork("(usernstest)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(usernstest)", FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT, NULL);
|
||||
if (r == 0) { /* child */
|
||||
_cleanup_free_ char *rt = NULL, *d = NULL;
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ int block_device_get_whole_disk(sd_device *dev, sd_device **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int block_device_get_originating(sd_device *dev, sd_device **ret) {
|
||||
int block_device_get_originating(sd_device *dev, sd_device **ret) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *first_found = NULL;
|
||||
const char *suffix;
|
||||
dev_t devnum = 0; /* avoid false maybe-uninitialized warning */
|
||||
|
||||
@@ -27,6 +27,7 @@ int block_device_new_from_path(const char *path, BlockDeviceLookupFlag flag, sd_
|
||||
|
||||
int block_device_is_whole_disk(sd_device *dev);
|
||||
int block_device_get_whole_disk(sd_device *dev, sd_device **ret);
|
||||
int block_device_get_originating(sd_device *dev, sd_device **ret);
|
||||
|
||||
int block_get_whole_disk(dev_t d, dev_t *ret);
|
||||
int block_get_originating(dev_t d, dev_t *ret);
|
||||
|
||||
@@ -1401,7 +1401,7 @@ int calendar_spec_next_usec(const CalendarSpec *spec, usec_t usec, usec_t *ret_n
|
||||
if (shared == MAP_FAILED)
|
||||
return negative_errno();
|
||||
|
||||
r = safe_fork("(sd-calendar)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(sd-calendar)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_WAIT, NULL);
|
||||
if (r < 0) {
|
||||
(void) munmap(shared, sizeof *shared);
|
||||
return r;
|
||||
|
||||
@@ -1718,7 +1718,7 @@ static int run_fsck(int node_fd, const char *fstype) {
|
||||
"(fsck)",
|
||||
NULL,
|
||||
&node_fd, 1, /* Leave the node fd open */
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_CLOEXEC_OFF,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_CLOEXEC_OFF,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to fork off fsck: %m");
|
||||
@@ -3410,7 +3410,7 @@ int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, &child);
|
||||
r = safe_fork("(sd-dissect)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, &child);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -270,7 +270,7 @@ static int run_editor(const EditFileContext *context) {
|
||||
|
||||
assert(context);
|
||||
|
||||
r = safe_fork("(editor)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(editor)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG|FORK_WAIT, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) { /* Child */
|
||||
|
||||
@@ -45,7 +45,7 @@ static int do_spawn(const char *path, char *argv[], int stdout_fd, pid_t *pid, b
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = safe_fork("(direxec)", FORK_DEATHSIG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &_pid);
|
||||
r = safe_fork("(direxec)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE, &_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
@@ -250,7 +250,7 @@ int execute_strv(
|
||||
* them to finish. Optionally a timeout is applied. If a file with the same name
|
||||
* exists in more than one directory, the earliest one wins. */
|
||||
|
||||
r = safe_fork("(sd-executor)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &executor_pid);
|
||||
r = safe_fork("(sd-executor)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &executor_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
@@ -541,7 +541,7 @@ int fork_agent(const char *name, const int except[], size_t n_except, pid_t *ret
|
||||
NULL,
|
||||
except,
|
||||
n_except,
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_REOPEN_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
ret_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -1692,7 +1692,7 @@ static int get_boot_id_for_machine(const char *machine, sd_id128_t *boot_id) {
|
||||
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
|
||||
return -errno;
|
||||
|
||||
r = namespace_fork("(sd-bootidns)", "(sd-bootid)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
r = namespace_fork("(sd-bootidns)", "(sd-bootid)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGKILL,
|
||||
pidnsfd, mntnsfd, -1, -1, rootfd, &child);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -155,7 +155,7 @@ static int do_mcopy(const char *node, const char *root) {
|
||||
if (strv_extend(&argv, "::") < 0)
|
||||
return log_oom();
|
||||
|
||||
r = safe_fork("(mcopy)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS, NULL);
|
||||
r = safe_fork("(mcopy)", FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_STDOUT_TO_STDERR|FORK_CLOSE_ALL_FDS, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
@@ -336,7 +336,7 @@ int make_filesystem(
|
||||
_cleanup_(unlink_and_freep) char *protofile = NULL;
|
||||
char vol_id[CONST_MAX(SD_ID128_UUID_STRING_MAX, 8U + 1U)] = {};
|
||||
int stdio_fds[3] = { -EBADF, STDERR_FILENO, STDERR_FILENO};
|
||||
ForkFlags flags = FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|
|
||||
ForkFlags flags = FORK_RESET_SIGNALS|FORK_RLIMIT_NOFILE_SAFE|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|
|
||||
FORK_CLOSE_ALL_FDS|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG;
|
||||
int r;
|
||||
|
||||
|
||||
@@ -981,7 +981,7 @@ static int mount_in_namespace_legacy(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = namespace_fork("(sd-bindmnt)", "(sd-bindmnt-inner)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
r = namespace_fork("(sd-bindmnt)", "(sd-bindmnt-inner)", NULL, 0, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM,
|
||||
pidns_fd, mntns_fd, -1, -1, root_fd, &child);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
@@ -1184,7 +1184,7 @@ static int mount_in_namespace(
|
||||
"(sd-bindmnt-inner)",
|
||||
/* except_fds= */ NULL,
|
||||
/* n_except_fds= */ 0,
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG,
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM,
|
||||
pidns_fd,
|
||||
mntns_fd,
|
||||
/* netns_fd= */ -1,
|
||||
|
||||
+1
-1
@@ -316,7 +316,7 @@ int show_man_page(const char *desc, bool null_stdio) {
|
||||
} else
|
||||
args[1] = desc;
|
||||
|
||||
r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_REARRANGE_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|(null_stdio ? FORK_REARRANGE_STDIO : 0)|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -452,7 +452,7 @@ int varlink_connect_exec(Varlink **ret, const char *_command, char **_argv) {
|
||||
/* stdio_fds= */ NULL,
|
||||
/* except_fds= */ (int[]) { pair[1] },
|
||||
/* n_except_fds= */ 1,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to spawn process: %m");
|
||||
|
||||
@@ -223,7 +223,7 @@ static int fork_and_exec_process(const char *child, char **argv, int fd) {
|
||||
return log_oom();
|
||||
|
||||
r = safe_fork("(activate)",
|
||||
FORK_RESET_SIGNALS | FORK_DEATHSIG | FORK_RLIMIT_NOFILE_SAFE | FORK_LOG,
|
||||
FORK_RESET_SIGNALS | FORK_DEATHSIG_SIGTERM | FORK_RLIMIT_NOFILE_SAFE | FORK_LOG,
|
||||
&child_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
executables += [
|
||||
libexec_template + {
|
||||
'name' : 'systemd-storagetm',
|
||||
'conditions' : [
|
||||
'ENABLE_STORAGETM',
|
||||
],
|
||||
'sources' : files('storagetm.c'),
|
||||
},
|
||||
]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,7 +70,7 @@ static int fork_wait(const char* const cmdline[]) {
|
||||
pid_t pid;
|
||||
int r;
|
||||
|
||||
r = safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
r = safe_fork("(sulogin)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
+1
-1
@@ -973,7 +973,7 @@ static int merge(ImageClass image_class,
|
||||
pid_t pid;
|
||||
int r;
|
||||
|
||||
r = safe_fork("(sd-merge)", FORK_DEATHSIG|FORK_LOG|FORK_NEW_MOUNTNS, &pid);
|
||||
r = safe_fork("(sd-merge)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_NEW_MOUNTNS, &pid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to fork off child: %m");
|
||||
if (r == 0) {
|
||||
|
||||
@@ -84,7 +84,7 @@ static int load_kexec_kernel(void) {
|
||||
if (arg_dry_run)
|
||||
return 0;
|
||||
|
||||
r = safe_fork("(kexec)", FORK_WAIT|FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
r = safe_fork("(kexec)", FORK_WAIT|FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -210,7 +210,7 @@ int enable_sysv_units(const char *verb, char **args) {
|
||||
if (!arg_quiet)
|
||||
log_info("Executing: %s", l);
|
||||
|
||||
j = safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
j = safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
if (j < 0)
|
||||
return j;
|
||||
if (j == 0) {
|
||||
|
||||
@@ -67,6 +67,7 @@ int sd_netlink_add_match(sd_netlink *nl, sd_netlink_slot **ret_slot, uint16_t ma
|
||||
|
||||
int sd_netlink_attach_event(sd_netlink *nl, sd_event *e, int64_t priority);
|
||||
int sd_netlink_detach_event(sd_netlink *nl);
|
||||
sd_event* sd_netlink_get_event(sd_netlink *nl);
|
||||
int sd_netlink_attach_filter(sd_netlink *nl, size_t len, const struct sock_filter *filter);
|
||||
|
||||
/* Message construction */
|
||||
|
||||
@@ -292,7 +292,7 @@ static int download_manifest(
|
||||
r = safe_fork_full("(sd-pull)",
|
||||
(int[]) { -EBADF, pfd[1], STDERR_FILENO },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -793,7 +793,7 @@ static int run_helper(
|
||||
assert(path);
|
||||
assert(cmdline);
|
||||
|
||||
r = safe_fork(name, FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork(name, FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -30,7 +30,7 @@ TEST(asynchronous_close) {
|
||||
assert_se(fcntl(fd, F_GETFD) == -1);
|
||||
assert_se(errno == EBADF);
|
||||
|
||||
r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGKILL|FORK_LOG|FORK_WAIT, NULL);
|
||||
assert(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -63,7 +63,7 @@ TEST(asynchronous_rm_rf) {
|
||||
/* Do this once more, form a subreaper. Which is nice, because we can watch the async child even
|
||||
* though detached */
|
||||
|
||||
r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(subreaper)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
|
||||
@@ -254,7 +254,7 @@ static void test_capability_get_ambient(void) {
|
||||
|
||||
assert_se(capability_get_ambient(&c) >= 0);
|
||||
|
||||
r = safe_fork("(getambient)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG, NULL);
|
||||
r = safe_fork("(getambient)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
|
||||
@@ -115,7 +115,7 @@ TEST(copy_data_fd) {
|
||||
|
||||
assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0, sfd) >= 0);
|
||||
|
||||
r = safe_fork("(sd-pipe)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pid);
|
||||
r = safe_fork("(sd-pipe)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_LOG, &pid);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
|
||||
@@ -475,7 +475,7 @@ TEST(setenv_systemd_exec_pid) {
|
||||
TEST(getenv_steal_erase) {
|
||||
int r;
|
||||
|
||||
r = safe_fork("(sd-getenvstealerase)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(sd-getenvstealerase)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
if (r == 0) {
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ static int find_libraries(const char *exec, char ***ret) {
|
||||
r = safe_fork_full("(spawn-ldd)",
|
||||
(int[]) { -EBADF, outpipe[1], errpipe[1] },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG, &pid);
|
||||
assert_se(r >= 0);
|
||||
if (r == 0) {
|
||||
execlp("ldd", "ldd", exec, NULL);
|
||||
@@ -1299,7 +1299,7 @@ static int prepare_ns(const char *process_name) {
|
||||
r = safe_fork(process_name,
|
||||
FORK_RESET_SIGNALS |
|
||||
FORK_CLOSE_ALL_FDS |
|
||||
FORK_DEATHSIG |
|
||||
FORK_DEATHSIG_SIGTERM |
|
||||
FORK_WAIT |
|
||||
FORK_REOPEN_LOG |
|
||||
FORK_LOG |
|
||||
|
||||
@@ -337,7 +337,7 @@ TEST(close_all_fds) {
|
||||
* with /proc/ overmounted, and once with the combination of both. This should trigger all fallbacks
|
||||
* in the close_range_all() function. */
|
||||
|
||||
r = safe_fork("(caf-plain)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(caf-plain)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
if (r == 0) {
|
||||
test_close_all_fds_inner();
|
||||
_exit(EXIT_SUCCESS);
|
||||
@@ -347,7 +347,7 @@ TEST(close_all_fds) {
|
||||
if (geteuid() != 0)
|
||||
return (void) log_tests_skipped("Lacking privileges for test with close_range() blocked and /proc/ overmounted");
|
||||
|
||||
r = safe_fork("(caf-noproc)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL);
|
||||
r = safe_fork("(caf-noproc)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL);
|
||||
if (r == 0) {
|
||||
r = mount_nofollow_verbose(LOG_WARNING, "tmpfs", "/proc", "tmpfs", 0, NULL);
|
||||
if (r < 0)
|
||||
@@ -361,7 +361,7 @@ TEST(close_all_fds) {
|
||||
if (!is_seccomp_available())
|
||||
return (void) log_tests_skipped("Seccomp not available");
|
||||
|
||||
r = safe_fork("(caf-seccomp)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(caf-seccomp)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
if (r == 0) {
|
||||
r = seccomp_prohibit_close_range();
|
||||
if (r < 0)
|
||||
@@ -373,7 +373,7 @@ TEST(close_all_fds) {
|
||||
}
|
||||
assert_se(r >= 0);
|
||||
|
||||
r = safe_fork("(caf-scnp)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL);
|
||||
r = safe_fork("(caf-scnp)", FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, NULL);
|
||||
if (r == 0) {
|
||||
r = seccomp_prohibit_close_range();
|
||||
if (r < 0)
|
||||
|
||||
@@ -969,7 +969,7 @@ TEST(read_full_file_socket) {
|
||||
/* Bind the *client* socket to some randomized name, to verify that this works correctly. */
|
||||
assert_se(asprintf(&clientname, "@%" PRIx64 "/test-bindname", random_u64()) >= 0);
|
||||
|
||||
r = safe_fork("(server)", FORK_DEATHSIG|FORK_LOG, &pid);
|
||||
r = safe_fork("(server)", FORK_DEATHSIG_SIGTERM|FORK_LOG, &pid);
|
||||
assert_se(r >= 0);
|
||||
if (r == 0) {
|
||||
union sockaddr_union peer = {};
|
||||
|
||||
@@ -82,7 +82,7 @@ TEST(keymaps) {
|
||||
|
||||
#define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x))
|
||||
TEST(dump_special_glyphs) {
|
||||
assert_cc(SPECIAL_GLYPH_WARNING_SIGN + 1 == _SPECIAL_GLYPH_MAX);
|
||||
assert_cc(SPECIAL_GLYPH_WORLD + 1 == _SPECIAL_GLYPH_MAX);
|
||||
|
||||
log_info("is_locale_utf8: %s", yes_no(is_locale_utf8()));
|
||||
|
||||
@@ -125,6 +125,8 @@ TEST(dump_special_glyphs) {
|
||||
dump_glyph(SPECIAL_GLYPH_SPARKLES);
|
||||
dump_glyph(SPECIAL_GLYPH_LOW_BATTERY);
|
||||
dump_glyph(SPECIAL_GLYPH_WARNING_SIGN);
|
||||
dump_glyph(SPECIAL_GLYPH_COMPUTER_DISK);
|
||||
dump_glyph(SPECIAL_GLYPH_WORLD);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
||||
|
||||
@@ -35,4 +35,31 @@ TEST(make_lock_file) {
|
||||
assert_se(make_lock_file("lock", LOCK_EX|LOCK_NB, &lock2) == -EBUSY);
|
||||
}
|
||||
|
||||
static void test_lock_generic_with_timeout_for_type(LockType type) {
|
||||
_cleanup_(rm_rf_physical_and_freep) char *t = NULL;
|
||||
_cleanup_close_ int tfd = -EBADF, tfd2 = -EBADF;
|
||||
|
||||
tfd = mkdtemp_open(NULL, 0, &t);
|
||||
assert_se(tfd >= 0);
|
||||
|
||||
tfd2 = fd_reopen(tfd, O_CLOEXEC|O_DIRECTORY);
|
||||
assert_se(tfd2 >= 0);
|
||||
|
||||
assert_se(lock_generic(tfd, LOCK_BSD, LOCK_EX) >= 0);
|
||||
assert_se(lock_generic(tfd2, LOCK_BSD, LOCK_EX|LOCK_NB) == -EWOULDBLOCK);
|
||||
|
||||
usec_t start = now(CLOCK_MONOTONIC);
|
||||
assert_se(lock_generic_with_timeout(tfd2, LOCK_BSD, LOCK_EX, 200 * USEC_PER_MSEC) == -ETIMEDOUT);
|
||||
assert_se(usec_sub_unsigned(now(CLOCK_MONOTONIC), start) >= 200 * USEC_PER_MSEC);
|
||||
|
||||
assert_se(lock_generic(tfd, LOCK_BSD, LOCK_UN) >= 0);
|
||||
assert_se(lock_generic_with_timeout(tfd2, LOCK_BSD, LOCK_EX, 200 * USEC_PER_MSEC) == 0);
|
||||
assert_se(lock_generic(tfd, LOCK_BSD, LOCK_EX|LOCK_NB) == -EWOULDBLOCK);
|
||||
}
|
||||
|
||||
TEST(lock_generic_with_timeout) {
|
||||
test_lock_generic_with_timeout_for_type(LOCK_BSD);
|
||||
test_lock_generic_with_timeout_for_type(LOCK_UNPOSIX);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_INFO);
|
||||
|
||||
@@ -226,7 +226,7 @@ TEST(real_pressure) {
|
||||
|
||||
assert_se(pipe2(pipe_fd, O_CLOEXEC) >= 0);
|
||||
|
||||
r = safe_fork("(eat-memory)", FORK_RESET_SIGNALS|FORK_DEATHSIG, &pid);
|
||||
r = safe_fork("(eat-memory)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM, &pid);
|
||||
assert_se(r >= 0);
|
||||
if (r == 0) {
|
||||
real_pressure_eat_memory(pipe_fd[0]);
|
||||
|
||||
@@ -80,7 +80,7 @@ TEST(mkdir_p_safe) {
|
||||
p = mfree(p);
|
||||
assert_se(p = path_join(tmp, "zero-mode/should-fail-to-create-child"));
|
||||
assert_se(mkdir_parents_safe(tmp, p, 0000, UID_INVALID, GID_INVALID, 0) >= 0);
|
||||
r = safe_fork("(test-mkdir-no-cap)", FORK_DEATHSIG | FORK_WAIT | FORK_LOG, NULL);
|
||||
r = safe_fork("(test-mkdir-no-cap)", FORK_DEATHSIG_SIGTERM | FORK_WAIT | FORK_LOG, NULL);
|
||||
if (r == 0) {
|
||||
(void) capability_bounding_set_drop(0, /* right_now = */ true);
|
||||
assert_se(mkdir_p_safe(tmp, p, 0000, UID_INVALID, GID_INVALID, 0) == -EACCES);
|
||||
|
||||
@@ -280,7 +280,7 @@ TEST(make_mount_switch_root) {
|
||||
r = safe_fork("(switch-root)",
|
||||
FORK_RESET_SIGNALS |
|
||||
FORK_CLOSE_ALL_FDS |
|
||||
FORK_DEATHSIG |
|
||||
FORK_DEATHSIG_SIGTERM |
|
||||
FORK_WAIT |
|
||||
FORK_REOPEN_LOG |
|
||||
FORK_LOG |
|
||||
@@ -332,7 +332,7 @@ TEST(umount_recursive) {
|
||||
r = safe_fork("(umount-rec)",
|
||||
FORK_RESET_SIGNALS |
|
||||
FORK_CLOSE_ALL_FDS |
|
||||
FORK_DEATHSIG |
|
||||
FORK_DEATHSIG_SIGTERM |
|
||||
FORK_WAIT |
|
||||
FORK_REOPEN_LOG |
|
||||
FORK_LOG |
|
||||
@@ -406,7 +406,7 @@ TEST(fd_make_mount_point) {
|
||||
r = safe_fork("(make_mount-point)",
|
||||
FORK_RESET_SIGNALS |
|
||||
FORK_CLOSE_ALL_FDS |
|
||||
FORK_DEATHSIG |
|
||||
FORK_DEATHSIG_SIGTERM |
|
||||
FORK_WAIT |
|
||||
FORK_REOPEN_LOG |
|
||||
FORK_LOG |
|
||||
|
||||
@@ -634,7 +634,7 @@ TEST(safe_fork) {
|
||||
|
||||
BLOCK_SIGNALS(SIGCHLD);
|
||||
|
||||
r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &pid);
|
||||
r = safe_fork("(test-child)", FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_REOPEN_LOG, &pid);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -701,7 +701,7 @@ TEST(setpriority_closest) {
|
||||
int r;
|
||||
|
||||
r = safe_fork("(test-setprio)",
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_WAIT|FORK_LOG, NULL);
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_WAIT|FORK_LOG, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -855,7 +855,7 @@ TEST(get_process_threads) {
|
||||
int r;
|
||||
|
||||
/* Run this test in a child, so that we can guarantee there's exactly one thread around in the child */
|
||||
r = safe_fork("(nthreads)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_REOPEN_LOG|FORK_WAIT|FORK_LOG, NULL);
|
||||
r = safe_fork("(nthreads)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_WAIT|FORK_LOG, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
|
||||
@@ -93,7 +93,7 @@ TEST(rm_rf_chmod) {
|
||||
/* This test only works unpriv (as only then the access mask for the owning user matters),
|
||||
* hence drop privs here */
|
||||
|
||||
r = safe_fork("(setresuid)", FORK_DEATHSIG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(setresuid)", FORK_DEATHSIG_SIGTERM|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
|
||||
@@ -158,7 +158,7 @@ TEST(in_addr_is_multicast) {
|
||||
TEST(getpeercred_getpeergroups) {
|
||||
int r;
|
||||
|
||||
r = safe_fork("(getpeercred)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(getpeercred)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -228,7 +228,7 @@ TEST(passfd_read) {
|
||||
|
||||
assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
|
||||
|
||||
r = safe_fork("(passfd_read)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(passfd_read)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -270,7 +270,7 @@ TEST(passfd_contents_read) {
|
||||
|
||||
assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
|
||||
|
||||
r = safe_fork("(passfd_contents_read)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(passfd_contents_read)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -322,7 +322,7 @@ TEST(pass_many_fds_contents_read) {
|
||||
|
||||
assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
|
||||
|
||||
r = safe_fork("(passfd_contents_read)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(passfd_contents_read)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -382,7 +382,7 @@ TEST(receive_nopassfd) {
|
||||
|
||||
assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
|
||||
|
||||
r = safe_fork("(receive_nopassfd)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(receive_nopassfd)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -418,7 +418,7 @@ TEST(send_nodata_nofd) {
|
||||
|
||||
assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
|
||||
|
||||
r = safe_fork("(send_nodata_nofd)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(send_nodata_nofd)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
@@ -451,7 +451,7 @@ TEST(send_emptydata) {
|
||||
|
||||
assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) >= 0);
|
||||
|
||||
r = safe_fork("(send_emptydata)", FORK_DEATHSIG|FORK_LOG|FORK_WAIT, NULL);
|
||||
r = safe_fork("(send_emptydata)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
|
||||
assert_se(r >= 0);
|
||||
|
||||
if (r == 0) {
|
||||
|
||||
@@ -381,7 +381,7 @@ static int worker_spawn(Manager *manager, Event *event) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Worker: Failed to enable receiving of device: %m");
|
||||
|
||||
r = safe_fork("(udev-worker)", FORK_DEATHSIG, &pid);
|
||||
r = safe_fork("(udev-worker)", FORK_DEATHSIG_SIGTERM, &pid);
|
||||
if (r < 0) {
|
||||
event->state = EVENT_QUEUED;
|
||||
return log_error_errno(r, "Failed to fork() worker: %m");
|
||||
|
||||
@@ -280,7 +280,7 @@ int udev_event_spawn(
|
||||
r = safe_fork_full("(spawn)",
|
||||
(int[]) { -EBADF, outpipe[WRITE_END], errpipe[WRITE_END] },
|
||||
NULL, 0,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
FORK_RESET_SIGNALS|FORK_CLOSE_ALL_FDS|FORK_DEATHSIG_SIGTERM|FORK_REARRANGE_STDIO|FORK_LOG|FORK_RLIMIT_NOFILE_SAFE,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return log_device_error_errno(event->dev, r,
|
||||
|
||||
+14
-73
@@ -10,6 +10,7 @@
|
||||
#include "device-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fdset.h"
|
||||
#include "lock-util.h"
|
||||
#include "main-func.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
@@ -194,91 +195,31 @@ static int lock_device(
|
||||
if (!S_ISBLK(st.st_mode) || st.st_rdev != devno)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Path '%s' no longer refers to specified block device %u:%u: %m", path, major(devno), minor(devno));
|
||||
|
||||
if (flock(fd, LOCK_EX|LOCK_NB) < 0) {
|
||||
|
||||
if (errno != EAGAIN)
|
||||
return log_error_errno(errno, "Failed to lock device '%s': %m", path);
|
||||
r = lock_generic(fd, LOCK_BSD, LOCK_EX|LOCK_NB);
|
||||
if (r < 0) {
|
||||
if (r != -EAGAIN)
|
||||
return log_error_errno(r, "Failed to lock device '%s': %m", path);
|
||||
|
||||
if (deadline == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EBUSY), "Device '%s' is currently locked.", path);
|
||||
|
||||
if (deadline == USEC_INFINITY) {
|
||||
|
||||
log_info("Device '%s' is currently locked, waiting%s", path, special_glyph(SPECIAL_GLYPH_ELLIPSIS));
|
||||
|
||||
if (flock(fd, LOCK_EX) < 0)
|
||||
return log_error_errno(errno, "Failed to lock device '%s': %m", path);
|
||||
|
||||
r = lock_generic(fd, LOCK_BSD, LOCK_EX);
|
||||
} else {
|
||||
_cleanup_(sigkill_waitp) pid_t flock_pid = 0;
|
||||
|
||||
/* flock() doesn't support a time-out. Let's fake one then. The traditional way to do
|
||||
* this is via alarm()/setitimer()/timer_create(), but that's racy, given that the
|
||||
* SIGALRM might already fire between the alarm() and the flock() in which case the
|
||||
* flock() is never cancelled and we lock up (this is a short time window, but with
|
||||
* short timeouts on a loaded machine we might run into it, who knows?). Let's
|
||||
* instead do the lock out-of-process: fork off a child that does the locking, and
|
||||
* that we'll wait on and kill if it takes too long. */
|
||||
usec_t left = usec_sub_unsigned(deadline, now(CLOCK_MONOTONIC));
|
||||
|
||||
log_info("Device '%s' is currently locked, waiting %s%s",
|
||||
path, FORMAT_TIMESPAN(usec_sub_unsigned(deadline, now(CLOCK_MONOTONIC)), 0),
|
||||
path, FORMAT_TIMESPAN(left, 0),
|
||||
special_glyph(SPECIAL_GLYPH_ELLIPSIS));
|
||||
|
||||
BLOCK_SIGNALS(SIGCHLD);
|
||||
|
||||
r = safe_fork("(timed-flock)", FORK_DEATHSIG|FORK_LOG, &flock_pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
/* Child */
|
||||
|
||||
if (flock(fd, LOCK_EX) < 0) {
|
||||
log_error_errno(errno, "Failed to lock device '%s': %m", path);
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
siginfo_t si;
|
||||
sigset_t ss;
|
||||
usec_t n;
|
||||
|
||||
assert_se(sigemptyset(&ss) >= 0);
|
||||
assert_se(sigaddset(&ss, SIGCHLD) >= 0);
|
||||
|
||||
n = now(CLOCK_MONOTONIC);
|
||||
if (n >= deadline)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ETIMEDOUT), "Timeout reached.");
|
||||
|
||||
r = sigtimedwait(&ss, NULL, TIMESPEC_STORE(deadline - n));
|
||||
if (r < 0) {
|
||||
if (errno != EAGAIN)
|
||||
return log_error_errno(errno, "Failed to wait for SIGCHLD: %m");
|
||||
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ETIMEDOUT), "Timeout reached.");
|
||||
}
|
||||
|
||||
assert(r == SIGCHLD);
|
||||
|
||||
zero(si);
|
||||
|
||||
if (waitid(P_PID, flock_pid, &si, WEXITED|WNOHANG|WNOWAIT) < 0)
|
||||
return log_error_errno(errno, "Failed to wait for child: %m");
|
||||
|
||||
if (si.si_pid != 0) {
|
||||
assert(si.si_pid == flock_pid);
|
||||
|
||||
if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EPROTO), "Unexpected exit status of file lock child.");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
log_debug("Got SIGCHLD for other child, continuing.");
|
||||
}
|
||||
r = lock_generic_with_timeout(fd, LOCK_BSD, LOCK_EX, left);
|
||||
if (r == -ETIMEDOUT)
|
||||
return log_error_errno(r, "Timeout reached.");
|
||||
}
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to lock device '%s': %m", path);
|
||||
}
|
||||
|
||||
log_debug("Successfully locked %s (%u:%u)%s", path, major(devno), minor(devno), special_glyph(SPECIAL_GLYPH_ELLIPSIS));
|
||||
@@ -349,7 +290,7 @@ int lock_main(int argc, char *argv[], void *userdata) {
|
||||
/* Ignore SIGINT and allow the forked process to receive it */
|
||||
(void) ignore_signals(SIGINT);
|
||||
|
||||
r = safe_fork("(lock)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
r = safe_fork("(lock)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_CLOSE_ALL_FDS|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) {
|
||||
|
||||
@@ -149,7 +149,7 @@ static int start_one_worker(Manager *m) {
|
||||
"(sd-worker)",
|
||||
/* stdio_fds= */ NULL,
|
||||
&m->listen_fd, 1,
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_REOPEN_LOG|FORK_LOG|FORK_CLOSE_ALL_FDS,
|
||||
FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_REOPEN_LOG|FORK_LOG|FORK_CLOSE_ALL_FDS,
|
||||
&pid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to fork new worker child: %m");
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../TEST-01-BASIC/Makefile
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
set -e
|
||||
|
||||
TEST_DESCRIPTION="test storagetm"
|
||||
|
||||
TEST_NO_NSPAWN=1
|
||||
|
||||
# shellcheck source=test/test-functions
|
||||
. "${TEST_BASE_DIR:?}/test-functions"
|
||||
|
||||
test_require_bin nvme
|
||||
|
||||
modprobe -nv nvmet-tcp || exit 0
|
||||
|
||||
test_append_files() {
|
||||
inst_binary nvme
|
||||
|
||||
instmods "=nvme"
|
||||
instmods configfs
|
||||
|
||||
generate_module_dependencies
|
||||
}
|
||||
|
||||
do_test "$@"
|
||||
@@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Unit]
|
||||
Description=TEST-84-STORAGETM
|
||||
After=multi-user.target
|
||||
|
||||
[Service]
|
||||
ExecStartPre=rm -f /failed /testok
|
||||
ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh
|
||||
Type=oneshot
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
modprobe -v nvmet-tcp
|
||||
modprobe -v nvme-tcp
|
||||
|
||||
systemctl start sys-kernel-config.mount
|
||||
|
||||
dd if=/dev/urandom of=/var/tmp/storagetm.test bs=1024 count=10240
|
||||
|
||||
systemd-run -u teststoragetm.service -p Type=notify /usr/lib/systemd/systemd-storagetm /var/tmp/storagetm.test --nqn=quux
|
||||
|
||||
nvme connect-all -t tcp -a 127.0.0.1 -s 16858 --hostid="$(cat /proc/sys/kernel/random/uuid)"
|
||||
|
||||
dd if=/dev/nvme1n1 bs=1024 | cmp /var/tmp/storagetm.test -
|
||||
|
||||
nvme disconnect --device=nvme1
|
||||
|
||||
systemctl stop teststoragetm.service
|
||||
|
||||
rm /var/tmp/storagetm.test
|
||||
|
||||
touch /testok
|
||||
@@ -559,6 +559,14 @@ units = [
|
||||
'conditions' : ['ENABLE_SYSUSERS'],
|
||||
'symlinks' : ['sysinit.target.wants/'],
|
||||
},
|
||||
{
|
||||
'file' : 'systemd-storagetm.service.in',
|
||||
'conditions' : ['ENABLE_STORAGETM'],
|
||||
},
|
||||
{
|
||||
'file' : 'storage-target-mode.target',
|
||||
'conditions' : ['ENABLE_STORAGETM'],
|
||||
},
|
||||
{
|
||||
'file' : 'systemd-time-wait-sync.service.in',
|
||||
'conditions' : ['ENABLE_TIMESYNCD'],
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
[Unit]
|
||||
Description=Storage Target Mode
|
||||
Documentation=man:systemd.special(7)
|
||||
Wants=systemd-storagetm.service systemd-udevd.service systemd-udev-trigger.service systemd-networkd.service systemd-network-generator.service systemd-journald.socket systemd-journald-dev-log.socket
|
||||
Conflicts=rescue.service rescue.target
|
||||
After=systemd-storagetm.service systemd-udevd.service systemd-udev-trigger.service systemd-networkd.service systemd-network-generator.service systemd-journald.socket systemd-journald-dev-log.socket rescue.service rescue.target
|
||||
AllowIsolate=yes
|
||||
@@ -0,0 +1,27 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# This file is part of systemd.
|
||||
#
|
||||
# systemd is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
[Unit]
|
||||
Description=Storage Target Mode (NVMe-TCP)
|
||||
Documentation=man:systemd-storagetm.service(8)
|
||||
ConditionVirtualization=!container
|
||||
DefaultDependencies=no
|
||||
Wants=modprobe@nvmet_tcp.service modprobe@thunderbolt_net.service sys-kernel-config.mount
|
||||
After=modprobe@nvmet_tcp.service modprobe@thunderbolt_net.service sys-kernel-config.mount
|
||||
Conflicts=shutdown.target
|
||||
Before=shutdown.target
|
||||
FailureAction=reboot
|
||||
SuccessAction=reboot
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
RemainAfterExit=yes
|
||||
StandardInput=tty
|
||||
StandardOutput=tty
|
||||
ExecStart={{LIBEXECDIR}}/systemd-storagetm --all
|
||||
Reference in New Issue
Block a user