Allows to skip check that ensures units must not be running.
I have a use case that would use reattach, except the orchestrator
is using a non-standard versioning scheme, so image matching cannot
work. As a workaround, need to be able to detach and then attach
manually, without stopping the units to avoid extended downtimes
and loss of FD store.
The loading of an extension image from a symlink "NAME.raw" to
"NAME-VERSION.raw" failed because the release file name check worked
with the backing file of the loop device which already resolves the
symlink and thus the found name "NAME-VERSION" mismatched "NAME".
Pass the original filename and use it instead of the backing file
when available. This fixes the loading of "NAME.raw" extensions which
are a symlink to "NAME-VERSION.raw" as, e.g., may be the case when
systemd-sysupdate manages multiple versions.
Fixes https://github.com/systemd/systemd/issues/24293
Let's rework how we lock loopback block devices in two ways:
1. Lock a separate fd, instead of the main block device fd. We already
did that for our internal locking when allocating loopback block
devices, but do so for the exposed locking (i.e.
loop_device_flock()), too, so that the lock is independent of the
main fd we actually use of IO.
2. Instead of locking the device during allocation of the loopback
device, then unlocking it (which will make udev run), and then
re-locking things if we need, let's instead just keep the lock the
whole time, to make things a bit safer and faster, and not have to
wait for udev at all. This is done by adding a "lock_op" parameter to
loop device allocation functions that declares the initial state of
the lock, and is one of LOCK_UN/LOCK_SH/LOCK_EX. This change also
shortens a lot of code, since we allocate + immediately lock loopback
devices pretty much everywhere.
prefix_roota() is something we should stop using. It is bad for three
reasons:
1. As it names suggests it's supposed to be used when working relative
to some root directory, but given it doesn't follow symlinks (and
instead just stupidly joins paths) it is not a good choice for that.
2. More often than not it is currently used with inputs under control of
the user, and that is icky given it typically allocates memory on the
stack.
3. It's a redundant interface, where chase_symlinks() and path_join()
already exist as better, safer interfaces.
Hence, let's start moving things from prefix_roota() to path_join() for
the cases where that's appropriate.
When running on images you don't want to modify the /tmp
directory even if it's writable, and often it will just
be read-only. Set PrivateTmp=yes.
Fixes https://github.com/systemd/systemd/issues/23592
When we run `portablectl detach --enable --runtime`, then it triggers
`DisableUnitFilesWithFlags` DBus method and the main unit file is
removed, but its drop-ins are not. Hence, portable_detach() failed to
list existing portable units.
This makes the loop for listing portable units also accept drop-in
directories. So, all remaining drop-in directories are correctly
removed.
Before:
```
testsuite-29.sh[600]: + portablectl detach --now --runtime --enable /tmp/rootdir minimal-app0
portablectl[1391]: (Matching unit files with prefixes 'minimal-app0'.)
portablectl[1391]: Queued /org/freedesktop/systemd1/job/1812 to call StopUnit on portable service minimal-app0-foo.service.
portablectl[1391]: Removed "/run/systemd/system.attached/minimal-app0-foo.service".
portablectl[1391]: Queued /org/freedesktop/systemd1/job/1813 to call StopUnit on portable service minimal-app0.service.
portablectl[1391]: Removed "/run/systemd/system.attached/minimal-app0.service".
portablectl[1391]: Got result done/Success for job minimal-app0-foo.service
portablectl[1391]: Got result done/Success for job minimal-app0.service
portablectl[1391]: DetachImage failed: No unit files associated with '/tmp/rootdir' found attached to the system. Image not attached?
```
After:
```
testsuite-29.sh[508]: + portablectl detach --now --runtime --enable /tmp/rootdir minimal-app0
portablectl[1076]: (Matching unit files with prefixes 'minimal-app0'.)
portablectl[1076]: Queued /org/freedesktop/systemd1/job/1946 to call StopUnit on portable service minimal-app0-foo.service.
portablectl[1076]: Removed "/run/systemd/system.attached/minimal-app0-foo.service".
portablectl[1076]: Queued /org/freedesktop/systemd1/job/1947 to call StopUnit on portable service minimal-app0.service.
portablectl[1076]: Removed "/run/systemd/system.attached/minimal-app0.service".
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0.service.d/10-profile.conf.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0.service.d/20-portable.conf.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0.service.d.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0-foo.service.d/10-profile.conf.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0-foo.service.d/20-portable.conf.
portablectl[1076]: Removed /run/systemd/system.attached/minimal-app0-foo.service.d.
portablectl[1076]: Removed /run/portables/rootdir.
portablectl[1076]: Removed /run/systemd/system.attached.
```
I took inspiration from pid1:
bus_unit_find()
→ find_unit()
→ manager_load_unit_from_dbus_path()
→ unit_name_from_dbus_path()
→ !startswith(path, "/org/freedesktop/systemd1/unit/")
→ return -EINVAL
←
←
←
← if (r < 0) return 0
← 0
←
i.e. we return 0 when queried for "/org/freedesktop/systemd1/unit".
Fixes#23445.
Fixes#23433
matches is plumbed through until it finally gets used in unit_match()
which can deal with NULL matches so the assert() is unnecessary and
can be removed.
The two call sites of extract_image_and_extensions() also don't
assert() on matches either.
So here's something we should always keep in mind:
systemd-udevd actually does *two* things with BSD file locks on block
devices:
1. While it probes a device it takes a LOCK_SH lock. Thus everyone else
taking a LOCK_EX lock will temporarily block udev from probing
devices, which is good when making changes to it.
2. Whenever a device is closed after write (detected via inotify), udevd
will issue BLKRRPART (requesting the kernel to reread the partition
table). It does this while holding a LOCK_EX lock on the block
device. Thus anyone else taking LOCK_SH or LOCK_EX will temporarily
block udevd from issuing that ioctl. And that's quite relevant, since
the kernel will temporarily flush out all partitions while re-reading
the partition table and then create them anew. Thus it is smart to
take LOCK_SH when dissecting a block device to ensure that no
BLKRRPART is issued in the background, until we mounted the devices.
A reattach might go from img.raw to img_0.1.raw or viceversa, but this is
not allowed right now as we try to match the full name.
Also take into account that running strcspn(a, '/') on an image name, without
leading path, will return the length of the full string, but the versions
might be different so they won't match, eg:
img_0.1.raw -> 12
img_0.1.1.raw -> 14
So adjust the check to take that into account, and skip it if we are not
dealing with directories
Same idea as 03677889f0.
No functional change intended. The type of the iterator is generally changed to
be 'const char*' instead of 'char*'. Despite the type commonly used, modifying
the string was not allowed.
I adjusted the naming of some short variables for clarity and reduced the scope
of some variable declarations in code that was being touched anyway.
The complaint was that the output array was used for two kinds of data, and the
input flag decided whether this extra data should be included. The flag is
removed, and instead the old method is changed to include the data always as
a separate parameter.
This breaks backward compatibility, but the old method is effectively broken
and does not appear to be used yet, at least in open source code, by
searching on codesearch.debian.net and github.com.
Fixes#22404.
Co-authored-by: Luca Boccassi <bluca@debian.org>
The approach to use '''…'''.split() instead of a list of strings was initially
used when converting from automake because it allowed identical blocks of lines
to be used for both, making the conversion easier.
But over the years we have been using normal lists more and more, especially
when there were just a few filenames listed. This converts the rest.
No functional change.
This should make things a bit more robust since it ensures system
extension can only applied to the right environments. Right now three
different "scopes" are defined:
1. "system" (for regular OS systems, after the initrd transition)
2. "initrd" (for sysext images that apply to the initrd environment)
3. "portable" (for sysext images that apply to portable images)
If not specified we imply a default of "system portable", i.e. any image
where the field is not specified is implicitly OK for application to OS
images and for portable services – but not for initrds.
(Or when -H is used, since -H and -M are incompatible.)
Note that the slightly unusual form with separate boolean variables (hint_vars,
hint_addr) instead of e.g. a const char* variable to hold the message, because this
way we don't trigger the warning about non-literal format.
Most sd_notify() calls are like log_info() — the result is only informative
and if they fail, it's best ignore this. But if a call with READY=1 fails,
the unit may enter a failed state, so we should warn about this. Similarly
for FSTOREREMOVE=1: the manager may be left with a stale fd, at least wasting
resources.