There are multiple ways to encode ANSI ST, and we generally prefer ESC \
for it, for reasons explained in terminal-util.h. Hence, let's actually
follow this rule in the terminal reset logic, and use the ANSI_ST macro.
This will change the byte sequence generated (as it means we use ESC \
rather than BEL), but it doesn't change behaviour, as the two sequences
should be equivalent.
Follow-up for 3d97db8f3c
terminal_reset_ansi_req() would try to put terminal in nonblocking
mode temporarily again, hence just avoid the back and forth
and reset nonblocking as last step.
We drop the optimization for verify_sigchld as the
check differs based on the options passed and the
extra syscalls are certainly not going to matter
compared to the cost of forking a child process.
Fixes#40166
This adds 11 commits with minor preparatory commits for PR #39621. That
PR has tests that cover all this, even if this one doesn't, but the bits
added here are relatively minor.
Let's accept O_NONBLOCK on image fds. It's usually wise to open block
device with O_NONBLOCK as it means that drivers with removable media
won't block until a medium is inserted. Otherwise it has no effect. It
also has no effect when opening regular files. Since block devices and
raw devices are the only two things we accept in mountfsd, it's hence
safe to allow it.
So far we expected the client to access the access mode themselves, and
set a restrictive 0700 server-side.
However, in some scenarios it's handy if the inode is created
server-side already with the right mode, in particular when the client
doesn't do anything with the dir just yet, and just needs it to be there
with the right mode. If it has to adjust the mode client-side it might
otherwise need to fork something off, join the selected userns, adjust
the mode, and kill the child off again.
Let's move this from user-record.c into generic code and let's beef it
up a bit: allow parsing octal strings. This is particular relevant given
json_variant_new_stat() generates the mode in that format, and we
probably should be able to parse our own fields (even though we
currently don't do that for the data from json_variant_new_stat()).
This introduces RECURSE_DIR_UNLINK + RECURSE_DIR_UNLINK_GRACEFUL as new
return values for recurse_dir() callbacks. If either is returned the
inode currently processed will be removed and iteration continues with
the next item.
This is useful to have in the recurse_dir() mechanism itself (rather
than implement in the callback itself), due to ordering: we want to pin
the inodes via an fd while calling the callbacks, but we have to close
it before removal of the inodes. By moving this into the recurse_dir()
infra, we can implement this easily.
Allow CPUSchedulingPolicy to be set to "ext". SCHED_EXT is a new
scheduling policy in Linux v6.12 that allows processes to be scheduled
using custom BPF schedulers instead of the default in-kernel ones.
Selectively setting the SCHED_EXT policy is useful for systems running
in "partial mode" where not all processes are run using a custom
scheduler.
Fallback to SCHED_OTHER and print an error message for systems where
SCHED_EXT isn't available.
Let's make sure we don't define the same clang-tidy
test multiple times by deduplicating sources beforehand.
We end up with the same sources in a few cases because
e.g. we reuse the same fuzz-main.c for each fuzz target.
We watch for WEXITED via pidfd instead of signalfd, so no need to insist
on blocking SIGCHLD anymore if we're only watching for WEXITED.
This also removes SIGCHLD blocking tree-wide where it's not required
anymore.
Now that sd-event doesn't insist on blocking
SIGCHLD anymore when watching for process exit,
let's stop blocking SIGCHLD tree-wide where not
required anymore.
Note that we still have to block SIGCHLD so that
we can be certain the process is not reaped before
we get the pidfd to it. safe_fork() and friends are
used in libsystemd where we don't control how the
SIGCHLD signal is configured. Specifically, kernel
autoreaping could be enabled which is why we have
to block SIGCHLD until we get the pidfd so that the
kernel cannot autoreap the process before we get
the pidfd.
First, don't require blocking SIGCHLD for WEXITED. We watch for WEXITED
via pidfd instead of signalfd, so no need to insist on blocking SIGCHLD
anymore if we're only watching for WEXITED.
Second, do a proper check to see if the kernel autoreaping logic is
enabled. That has nothing to do with SIGCHLD being blocked for the current
thread or not. Instead, the kernel autoreaping logic is enabled either if
the disposition is set to SIG_IGN or if the SA_NOCLDWAIT flag is enabled.
* Specifying all 3 of FORK_DEATHSIG_SIG{KILL,TERM,INT} for
the middle man makes zero sense. Use SIGKILL only.
* Make sure operations on except_fds work sensibly - close/pack/
de-ocloexecify fds only in the second level, so that the namespace
fds remain usable across first safe_fork().
* Fire FORK_NEW_*NS after attaching to the desired namespaces,
not already in the outer process.
* Insist on PDEATHSIG being enabled to ensure propagation of killing.
* Suppress more redundant flags.
Loading images is, generally speaking, the slowest part of sd-executor
when spawning a service. This is due to multiple factors. dm-verity is
obviously a big part of the cost, but dissecting in general via libblkid
also can take a lot of time, due to probing the images and their
filesystems.
A performance test doing service restarts in a row shows these
results, ran on a production system (low power and slow ARM64 SOC) with
a real production service, show the following service interruption
intervals:
```
Count | P50 (ms) | P90 (ms) | P95 (ms) | P99 (ms) | P99.9 (ms)
507 | 1,532 | 1,726 | 2,548 | 4,112 | 4,592
```
One iteration is 507 restarts in this case, but this has ran hundreds
of times and the results are always in line within margin of error.
This also holds true for metrics from live systems, same numbers.
Between 1.0s and 1.2s can be attributed by profiling to the time needed
for the service code itself to start up and sd_notify, the rest is spent
inside systemd's code.
This means there is currently a tradeoff for services - either use
secure
images, or make restarting fast. Downtime of services is a very
important
metric, as for many cases this directly translates to outages, total or
partial (blackouot or greyout).
In order to facilitate using secure images without downsides, skip the
slow dissect steps (probing, loop devices, etc) when the configured
image is a single filesystem dm-verity image with a policy that pins it
to a single filesystem, and an already existing and open dm-verity
device
can be found and reused.
This allows orchestrators to pre-open images on download, before
restarting
services, to minimize downtimes.