After d8854ff1ac, if a serialized
leader PID of a machine is already dead when deserialized, then the
leader PID and PIDFD are unset for the machine, and subsequent
machine_start() -> machine_watch_pidfd() will trigger an assertion.
This makes a Machine object without leader PID GCed.
Fixes a bug introduced by the combination of
d8854ff1ac (v255) and
1762c2c045 (v257).
Fixes#35602.
nscd is known to be racy [1] and it was already deprecated and later dropped in
Fedora a while back [1,2]. We don't need to support obsolete stuff in systemd,
and the cache in systemd-resolved provides a better solution anyway.
We announced the plan to drop nscd in d44934f378.
[1] https://fedoraproject.org/wiki/Changes/DeprecateNSCD
[2] https://fedoraproject.org/wiki/Changes/RemoveNSCD
The option is kept as a stub without any effect to make the transition easier.
If we have a pidfd, we might as well track the machine's leader PID's
lifetime, and enqueue the machine for a GC run.
(This is similar to what we are already doing for logind's session
leaders)
One major omission in machine's logic so far was that the GC was only
run at startup and on the check-idle timeout, which is really slow.
Let's make this more like the GC logic in homed or logind: make sure we
run it in a close-by event loop cycle.
if machined exits while a machine is still running, we'll issue the
UnrefUnit() call on the unit. This quite likely will fail if during
shutdown the bus connection is already down. But that's no reason to
warn at all, since the ref count will implicitly be dropped if our side
disappears from the bus. Hence, downgrade to LOG_DEBUG in case of
connection problems.
Also adds three properties:
- VsockCid: the VSOCK CID of the VM
- SshAddress: the address of the VM in a format SSH can connect to
- SshPrivateKeyPath: the path to the SSH private key to use to connect
to the VM.
GetMachineSSHInfo is essentially a convenience method to query both the
SshAddress and SshPrivateKeyPath properties at once.
Those functions take a pointer to a timestamp and return a timestamp pointer,
so the reader would be justified to think that those are just getters. Rename
them to avoid confusion.
Previously the mkdir_label() family of calls was implemented in
src/shared/mkdir-label.c but its functions partly declared ins
src/shared/label.h and partly in src/basic/mkdir.h (!!). That's weird
(and wrong).
Let's clean this up, and add a proper mkdir-label.h matching the .c
file.
We recently started making more use of malloc_usable_size() and rely on
it (see the string_erase() story). Given that we don't really support
sytems where malloc_usable_size() cannot be trusted beyond statistics
anyway, let's go fully in and rework GREEDY_REALLOC() on top of it:
instead of passing around and maintaining the currenly allocated size
everywhere, let's just derive it automatically from
malloc_usable_size().
I am mostly after this for the simplicity this brings. It also brings
minor efficiency improvements I guess, but things become so much nicer
to look at if we can avoid these allocation size variables everywhere.
Note that the malloc_usable_size() man page says relying on it wasn't
"good programming practice", but I think it does this for reasons that
don't apply here: the greedy realloc logic specifically doesn't rely on
the returned extra size, beyond the fact that it is equal or larger than
what was requested.
(This commit was supposed to be a quick patch btw, but apparently we use
the greedy realloc stuff quite a bit across the codebase, so this ends
up touching *a*lot* of code.)
With some versions of the compiler, the _cleanup_ attr makes it think
the variable might be freed/closed when uninitialized, even though it
cannot happen. The added cost is small enough to be worth the benefit,
and optimized builds will help reduce it even further.
Let's move the heavy lifting out of the bus call implemntations, and
into generic code.
This allows us to expose them easily via Varlink too in a later commit.
We don't need a seperate output parameter that is of type int. glibc() says
that the type is "unsigned", but the kernel thinks it's "int". And the
"alternative names" interface also uses ints. So let's standarize on ints,
since it's clearly not realisitic to have interface numbers in the upper half
of unsigned int range.
Before, we'd unref from machine_stop_unit, still keeping the unit name around,
and only forget the name later, when garbage collecting. If we didn't call
manager_stop_unit(), then we wouldn't do the unref. Let's unref at the same
point where we do garbage collection, so that it is always true that
iff we have the name generated with AddRef=1, then have a reference to the unit,
and as soon as we forget the name, we drop the reference.
This should fix the issue when repeated systemd-nspawn --register=yes fails
with "scope already exists" error.
Incidentally, this fixes an error in the code path where r was used instead of q.
Having this function which is called only from one place in a separate file
makes the code harder to follow. In preparation for subsequent changes, let's
make it static.
b92d0b4c5a added AddRef to the StartTransientUnit
call in machine_start_scope()/manager_start_scope() and a corresponding Unref
call in machine_stop_scope(). But when we are running systemd-nspawn@ with
--keep unit, the unit is not created by machined so the AddRef never happens.
Then when trying to stop the unit, we'd get:
systemd-machined[1101]: Sent message type=method_call sender=n/a destination=org.freedesktop.systemd1 path=/org/freedesktop/systemd1 interface=org.freedesktop.systemd1.Manager member=UnrefUnit cookie=37 reply_cookie=0 signature=s error-name=n/a error-message=n/a
systemd-machined[1101]: Got message type=error sender=:1.1 destination=:1.13 path=n/a interface=n/a member=n/a cookie=2443 reply_cookie=37 signature=s error-name=org.freedesktop.systemd1.NotReferenced error-message=Unit has not been referenced yet.
systemd-machined[1101]: Failed to drop reference to machine scope, ignoring: Unit has not been referenced yet.
This is the opposite of RegisterMachine: machined knows that the machine is
"gone", but doesn't do anything on its own. We already had TerminateMachine,
but that would stop the unit, which isn't always wanted.
Allocating a pty is done in a couple of places so let's introduce a new helper
which does the job.
Also the new function, as well as openpt_in_namespace(), returns both pty
master and slave so the callers don't need to know about the pty slave
allocation details.
For the same reasons machine_openpt() prototype has also been changed to return
both pty master and slave so callers don't need to allocate a pty slave which
might be in a different namespace.
Finally openpt_in_namespace() has been renamed into
openpt_allocate_in_namespace().
This is partially a refactoring, but also makes many more places use
unlocked operations implicitly, i.e. all users of fopen_temporary().
AFAICT, the uses are always for short-lived files which are not shared
externally, and are just used within the same context. Locking is not
necessary.