We make assumptions about the comm name we set via PR_SET_NAME: that it
would reflect the process name, but that's only the case for the main
thread. Moreover, we cache the mmap() region without locking.
Let's hence be safe rather than sorry and support all this only in the
main thread.
It's a relatively small wrapper around safe_fork() now, hence let's move
it over, and make its signature even more alike. Also, set a different
process name for the polkit and askpw agents.
This adds a new safe_fork() wrapper around fork() and makes use of it
everywhere. The new wrapper does a couple of things we previously did
manually and separately in a safer, more correct and automatic way:
1. Optionally resets signal handlers/mask in the child
2. Sets a name on all processes we fork off right after forking off (and
the patch assigns useful names for all processes we fork off now,
following a systematic naming scheme: always enclosed in () – in order
to indicate that these are not proper, exec()ed processes, but only
forked off children, and if the process is long-running with only our
own code, without execve()'ing something else, it gets am "sd-" prefix.)
3. Optionally closes all file descriptors in the child
4. Optionally sets a PR_SET_DEATHSIG to SIGTERM in the child, in a safe
way so that the parent dying before this happens being handled
safely.
5. Optionally reopens the logs
6. Optionally connects stdin/stdout/stderr to /dev/null
7. Debug logs about the forked off processes.
Ultimately, O_CLOEXEC should be off in fd 0, 1, 2, but when we open
/dev/null here it's unlikely to be < 0, and after dupping the fd to 0,
1, 2 we turn off O_CLOEXEC explicitly anyway.
Unless we know that what we are about to open will return 0, 1 or 2 we
should always set O_CLOEXEC in order to be safe to other threads forking
of subprocesses at the wrong moment.
Just a minor tweak, making sure we execute as much as we can of the
funciton, but return the first error instead of the last we encounter.
This is usuelly how we do things when we have functions that continue on
the first error, so let's do it like that here too.
Let's fork off sync() ina process instead of a thread, as a safety
measure. This is beneficial to ensure that the original process can exit
without having to wait for the sync() to finish (note that the kernel
will delay process termination until all threads finished their
syscalls). In case of hanging NFS this increases the chance that PID 1
can safely transition to the "systemd-shutdown" process as the sync() is
initiated early on but definitely not waited for.
This makes things a bit easier to read I think, and also makes sure we
always use the _unlikely_ wrapper around it, which so far we used
sometimes and other times we didn't. Let's clean that up.
Followup to previous commit. Suggested by @poettering.
Reindented the `verbs[]` tables to match the apparent previous
whitespace rules (indent to one flag, allow multiple flags to overflow?).
A lot of code references the `running_in_chroot()` function; while
I didn't dig I'm pretty certain this arose to deal with situations
like RPM package builds in `mock` - there we don't want the `%post`s
to `systemctl start` for example.
And actually this exact same use case arises for
[rpm-ostree](https://github.com/projectatomic/rpm-ostree/)
where we implement offline upgrades by default; the `%post`s are
always run in a new chroot using [bwrap](https://github.com/projectatomic/bubblewrap).
And here's the problem: bwrap creates proper mount roots, so it
passes `running_in_chroot()`, and then if a script tries to do
`systemctl start` we get:
`System has not been booted with systemd as init system (PID 1)`
but that's an *error*, unlike the `running_in_chroot()` case where we ignore.
Further complicating things is there are real world RPM packages
like `glusterfs` which end up invoking `systemctl start`.
A while ago, the `SYSTEMD_IGNORE_CHROOT` environment variable was
added for the inverse case of running in a chroot, but still wanting
to use systemd as PID 1 (presumably some broken initramfs setups?).
Let's introduce a `SYSTEMD_OFFLINE` environment variable for cases like
mock/rpm-ostree so we can force on the "ignore everything except preset" logic.
This way we'll still not start services even if mock switches to use nspawn or
bwrap or something else that isn't a chroot.
We also cleanly supercede the `SYSTEMD_IGNORE_CHROOT=1` which is now spelled
`SYSTEMD_OFFLINE=0`. (Suggested by @poettering)
Also I made things slightly nicer here and we now print the ignored operation.
Remount, and subsequent umount, attempts can hang for inaccessible network
based mount points. This can leave a system in a hard hang state that
requires a hard reset in order to recover. This change moves the remount,
and umount attempts into separate child processes. The remount and umount
operations will block for up to 90 seconds (DEFAULT_TIMEOUT_USEC). Should
those waits fail, the parent will issue a SIGKILL to the child and continue
with the shutdown efforts.
In addition, instead of only reporting some additional errors on the final
attempt, failures are reported as they occur.
These helper calls are potentially called often, and allocate FILE*
objects internally for a very short period of time, let's turn off
locking for them too.
Let's replace usage of fputc_unlocked() and friends by __fsetlocking(f,
FSETLOCKING_BYCALLER). This turns off locking for the entire FILE*,
instead of doing individual per-call decision whether to use normal
calls or _unlocked() calls.
This has various benefits:
1. It's easier to read and easier not to forget
2. It's more comprehensive, as fprintf() and friends are covered too
(as these functions have no _unlocked() counterpart)
3. Philosophically, it's a bit more correct, because it's more a
property of the file handle really whether we ever pass it on to another
thread, not of the operations we then apply to it.
This patch reworks all pieces of codes that so far used fxyz_unlocked()
calls to use __fsetlocking() instead. It also reworks all places that
use open_memstream(), i.e. use stdio FILE* for string manipulations.
Note that this in some way a revert of 4b61c87511.
fputs() writes only first 2048 bytes and fails
to write to /proc when values are larger than that.
This patch adds a new flag to WriteStringFileFlags
that make it possible to disable the buffer under
specific cases.
This commit updates networkd behavior to check if the hostname option
received via DHCP is too long for Linux limit, and in case shorten it.
An overlong hostname will be truncated to the first dot or to
`HOST_MAX_LEN`, whatever comes earlier.
Add a new option `--network-namespace-path` to systemd-nspawn to allow
users to specify an arbitrary network namespace, e.g. `/run/netns/foo`.
Then systemd-nspawn will open the netns file, pass the fd to
outer_child, and enter the namespace represented by the fd before
running inner_child.
```
$ sudo ip netns add foo
$ mount | grep /run/netns/foo
nsfs on /run/netns/foo type nsfs (rw)
...
$ sudo systemd-nspawn -D /srv/fc27 --network-namespace-path=/run/netns/foo \
/bin/readlink -f /proc/self/ns/net
/proc/1/ns/net:[4026532009]
```
Note that the option `--network-namespace-path=` cannot be used together
with other network-related options such as `--private-network` so that
the options do not conflict with each other.
Fixes https://github.com/systemd/systemd/issues/7361
Using strlen() to declare a buffer results in a variable-length array,
even if the compiler likely optimizes it to be a compile time constant.
When building with -Wvla, certain versions of gcc complain about such
buffers. Compiling with -Wvla has the advantage of preventing variably
length array, which defeat static asserts that are implemented by
declaring an array of negative length.
While the compiler likely optimizes strlen(x) for string literals,
it is not a constant expression.
Hence,
char buffer[strlen("OPTION_000") + 1];
declares a variable-length array. STRLEN() can be used instead
when a constant espression is needed.
It's not entirely identical to strlen(), as STRLEN("a\0") counts 2.
Also, it only works with string literals and the macro enforces
that the argument is a literal.