Repository navigation
core: add systemd-executor binary - #27890
Merged
Merged
Conversation
bluca
force-pushed
the
executor
branch
5 times, most recently
from
June 1, 2023 20:58
f5c9f03 to
a77b51d
Compare
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
mrc0mmand
added a commit
to systemd/systemd-centos-ci
that referenced
this pull request
Jun 2, 2023
Temporary workaround for systemd/systemd#27890 until that change lands and dracut/mkinitcpio is updated.
This comment was marked as resolved.
This comment was marked as resolved.
poettering
reviewed
Oct 12, 2023
| continue; | ||
| } | ||
|
|
||
| p->fds[i] = fd; |
Member
Author
There was a problem hiding this comment.
You mean deserialize_fd_from_array/set? It is already using those
poettering
reviewed
Oct 12, 2023
| } | ||
|
|
||
| p->idle_pipe[i] = fd; | ||
| } |
Member
There was a problem hiding this comment.
deserialize_fd() (here and everywhere)
poettering
reviewed
Oct 12, 2023
poettering
reviewed
Oct 12, 2023
poettering
reviewed
Oct 12, 2023
| return log_debug_errno(fd, "Failed to parse FD out of value: %s", value); | ||
|
|
||
| if (!fdset_contains(fds, fd)) | ||
| return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "FD %d not in fdset.", fd); |
Member
There was a problem hiding this comment.
this check is redundant, fdset_remove() cecks for that too.
also, can we please get #29481 merged, it adds a deserializer for this, and moves everything over.
poettering
reviewed
Oct 12, 2023
This provides CLONE_VM + CLONE_VFORK semantics, so it is useful to avoid CoW traps and other issues around doing work between fork() and exec().
When switching to serialization later, the Manager object will not be serialized, move parameters around instead
When switching to serialization later, the Unit object will not be serialized, move parameters around instead
poettering
requested changes
Oct 12, 2023
Currently we spawn services by forking a child process, doing a bunch of work, and then exec'ing the service executable. There are some advantages to this approach: - quick: we immediately have access to all the enourmous amount of state simply by virtue of sharing the memory with the parent - easy to refactor and add features - part of the same binary, will never be out of sync There are however significant drawbacks: - doing work after fork and before exec is against glibc's supported case for several APIs we call - copy-on-write trap: anytime any memory is touched in either parent or child, a copy of that page will be triggered - memory footprint of the child process will be memory footprint of PID1, but using the cgroup memory limits of the unit The last issue is especially problematic on resource constrained systems where hard memory caps are enforced and swap is not allowed. As soon as PID1 is under load, with no page out due to no swap, and a service with a low MemoryMax= tries to start, hilarity ensues. Add a new systemd-executor binary, that is able to receive all the required state via memfd, deserialize it, prepare the appropriate data structures and call exec_child. Use posix_spawn which uses CLONE_VM + CLONE_VFORK, to ensure there is no copy-on-write (same address space will be used, and parent process will be frozen, until exec). The sd-executor binary is pinned by FD on startup, so that we can guarantee there will be no incompatibilities during upgrades.
No functional changes, only moving code that is only needed in exec_invoke, and adding new dependencies for seccomp/selinux/apparmor/pam in meson for the sd-executor binary.
2 of 3 tasks
Member
Author
|
DId some measurements before/after this PR, building a Fedora 39 image and checking with systemd-analyze the time to boot, and can't see a measurable difference: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Currently we spawn services by forking a child process, doing a bunch
of work, and then exec'ing the service executable.
There are some advantages to this approach:
state simply by virtue of sharing the memory with the parent
There are however significant drawbacks:
case for several APIs we call
or child, a copy of that page will be triggered
PID1, but using the cgroup memory limits of the unit
The last issue is especially problematic on resource constrained
systems where hard memory caps are enforced and swap is not allowed.
As soon as PID1 is under load, with no page out due to no swap, and a
service with a low MemoryMax= tries to start, hilarity ensues.
Add a new systemd-executor binary, that is able to receive all the
required state via memfd, deserialize it, prepare the appropriate
data structures and call exec_child.
Use posix_spawn which uses CLONE_VM + CLONE_VFORK, to ensure there is
no copy-on-write (same address space will be used, and parent process
will be frozen, until exec).
The sd-executor binary is pinned by FD on startup, so that we can
guarantee there will be no incompatibilities during upgrades.