varlink-io.systemd.MachineInstance,vmspawn: treat AddStorage/RemoveStorage name as opaque
The 'name' field on AddStorage and RemoveStorage was documented as
'<provider>:<volume>' and enforced via machine_storage_name_split() at
the varlink boundary. That form is only the convention machinectl
inherits from the StorageProvider routing path; the API itself only
needs a unique identifier the caller can re-use to detach the binding.
Drop the strict format check, require only a non-empty string, and
update the IDL docs to describe the field as a caller-supplied
identifier with machinectl's convention as a non-normative example.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
vmspawn: reject O_PATH and O_WRONLY fds in AddStorage
An fd opened O_PATH cannot be read, and an O_WRONLY fd cannot serve as
a backing file for a virtual disk image. Reject both at the bind-volume
entry point with -EBADF instead of letting the request proceed to QMP
where QEMU's file backend would fail to read from the fd. The
ReplaceStorage entry point grew the same checks in parallel.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
test: integration test for io.systemd.MachineInstance.ReplaceStorage
Modelled on TEST-87-AUX-UTILS-VM.bind-volume.sh. Boots vmspawn with
one boot-time bind-volume, hot-adds a runtime volume via machinectl
bind-volume, then exercises ReplaceStorage:
1. happy-path replace of a runtime drive
2. successive replace (verify file_generation rotation — no
node-name collisions on the second swap)
3. replace of the boot-time drive must fail with StorageImmutable
4. replace of an unknown name must fail with NoSuchStorage
5. invalid name (no provider:volume separator) must fail with
InvalidParameter
6. unbind-volume after replace must succeed — proves the new file
node is monitor-owned and the format-then-file teardown order
in vmspawn_qmp_block_device_teardown() correctly cleans up both
blockdev nodes
Pushes the new backing file via varlinkctl --push-fd; the file is a
plain truncate'd image. Auto-discovered by run_subtests in
TEST-87-AUX-UTILS-VM.sh.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Wire up the runtime hot-swap Varlink method. The signature mirrors
AddStorage minus 'config': the device frontend (virtio-blk,
virtio-scsi, nvme, scsi-cd) doesn't change, only the backing file
behind it. Read-only/read-write may flip based on the new fd's
O_ACCMODE; scsi-cd is forced read-only to match the boot-time policy.
add-fd → on_replace_observe_stage
blockdev-add (new file) → on_replace_blockdev_add_complete
remove-fd (new fdset) → on_replace_observe_stage
blockdev-reopen (format) → on_replace_blockdev_reopen_complete
[commit + fire trailing del]
blockdev-del (old file) → on_replace_old_blockdev_del_complete
The reopen options must be a superset of every option that
qmp_build_blockdev_add_format() may emit, otherwise reopen rejects
'Cannot reset option X to default'. The 'file' field is a string
reference to the new file node — case 3 of the schema in
qemu/qapi/block-core.json:5034-5040 ("the current child is replaced
with that other node"). The format node's qmp_node_name is preserved
so the device frontend's drive=<X> binding does not move.
ReplaceCtx tracks the per-call state with a refcount mirroring the
add-stage drive-info pattern. On any pre-commit failure replace_fail
tears down whatever new-side state we created on the wire and replies
on drive->link via reply_qmp_error (disconnect → NotConnected). On
post-commit del failure we log a warning, leak the orphan, and reply
success — the swap itself succeeded and the leak resolves at VM exit.
file_generation is bumped before issuing blockdev-add so failed
attempts cannot collide on node-name when the user retries.
Errors:
NoSuchStorage - drive not in the registry
StorageImmutable - drive lacks QMP_DRIVE_REMOVABLE (boot-time)
EBUSY - add still pending or another replace/remove in flight
NotConnected - QMP transport disconnect during the chain
EIO - QEMU rejected blockdev-reopen
Also gates RemoveStorage on REPLACE_PENDING so a device_del cannot
race a mid-flight blockdev-reopen on the same drive.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Define the IDL for io.systemd.MachineInstance.ReplaceStorage, a
runtime hot-swap of an already-attached storage volume's backing
file. The signature mirrors AddStorage minus the 'config' field
because the device frontend (virtio-blk, virtio-scsi, nvme, scsi-cd)
does not change — only the backing file behind it.
The implementation lives in vmspawn (next commit) and uses QMP
blockdev-reopen to swap the file child of the existing format node.
The reused error vocabulary (NoSuchStorage, StorageImmutable,
NotConnected, plus the generic errno path) covers every failure
mode; no new errors are added.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
vmspawn: split blockdev-add into separate file and format calls
The current vmspawn_qmp_add_block_device() emits a single blockdev-add
that combines the format-level node ("vmspawn-N-storage") with an
inline file child. QEMU's qmp_blockdev_add() only marks the top-level
returned BDS as monitor-owned (qemu/blockdev.c:3440); inline children
are NOT, so qmp_blockdev_del() rejects them with "Node X is not owned
by the monitor" (qemu/blockdev.c:3513-3517).
To prepare for ReplaceStorage — which needs to swap the file child of
an existing format node via blockdev-reopen, and then blockdev-del the
old file node — make the file node monitor-owned by issuing it as its
own blockdev-add call. The 4-stage add chain becomes 5 stages:
DriveInfo gains qmp_file_node_name ("vmspawn-N-file-G", G a generation
counter bumped on every replace), file_generation, and a stashed
fdset_id so future ReplaceStorage can target both for cleanup.
vmspawn_qmp_block_device_teardown() now deletes both nodes in order —
format first, then file — because the format holds a strong reference
to its file child and a file-first del is rejected with "Node X is
busy: node is used as 'file' of Y".
Folds bridge->features VMSPAWN_QMP_FEATURE_IO_URING into the file
node's flags so the new path inherits io_uring just like the old
inline form did. The format-level options (read-only, discard,
discard-no-unref) are unchanged.
The ephemeral path is structurally already separate file+format with
monitor-owned children; no behavioural change there beyond the
on_add_blockdev_stage → on_add_format_node_stage rename.
Drops the now-unused qmp_build_blockdev_add_inline() helper.
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Daan De Meyer [Tue, 12 May 2026 13:03:49 +0000 (13:03 +0000)]
vmspawn: Prefer systemd-journal-remote from $PATH
$PATH might point to a systemd checkout containing
a newer version of systemd-journal-remote which we
should use, hence prefer an executable from $PATH
over the one from /usr/lib/systemd.
Luca Boccassi [Tue, 12 May 2026 11:40:54 +0000 (12:40 +0100)]
test: make TEST-75-RESOLVED robust against journald metadata race
Even after switching the wait loop to a polling `journalctl --grep`, the
test still fails intermittently because the very first messages emitted by
the freshly-spawned systemd-networkd-wait-online process can carry stale
journald metadata. journald associates `_SYSTEMD_UNIT=` (and friends) with
each entry by reading `/proc/$pid/cgroup` of the originating PID; if those
messages are produced before journald notices the cgroup migration into the
new service, they get tagged with `_SYSTEMD_UNIT=init.scope`. The
`-u $unit` filter then fails to match them.
Capture a journal cursor before launching the unit, and grep using
`--after-cursor=` plus `SYSLOG_IDENTIFIER=systemd-networkd-wait-online`
instead of `-u $unit`. SYSLOG_IDENTIFIER is set by the program itself, so
it's not subject to the cgroup-discovery race. The cursor bounds the search
to entries produced by this invocation, so prior wait-online runs in
earlier testcases don't interfere.
Logs from the failing run showing the messages exist but are tagged with
the wrong unit:
_SYSTEMD_CGROUP=/init.scope
_SYSTEMD_UNIT=init.scope
_EXE=/usr/lib/systemd/systemd-executor
_CMDLINE=/usr/lib/systemd/systemd-executor --deserialize 68 ...
SYSLOG_IDENTIFIER=systemd-networkd-wait-online
MESSAGE=dns0: No DNS server is accessible.
Daan De Meyer [Tue, 12 May 2026 10:26:37 +0000 (12:26 +0200)]
json-stream: tolerate truncated SCM_RIGHTS on inbound messages
When an LSM (e.g. SELinux) denies an fd transfer or the receiver hits
RLIMIT_NOFILE, the kernel drops the fd(s) from the SCM_RIGHTS cmsg and
sets MSG_CTRUNC on the recvmsg(). recvmsg_safe() turns that into
-ECHRNG, which causes json_stream_read() to discard the data bytes
that were nevertheless received and the varlink server to silently
tear down the connection — leaving the caller waiting for a reply
that never comes.
Inline the recvmsg() call instead and, on MSG_CTRUNC, drop the partial
fds but keep the message data. The method handler will surface a clean
-ENXIO when it tries to peek the missing fd, which sd-varlink wraps as
io.systemd.System for the peer, instead of a hang. This matches the
recent sd-bus fix in 6c8de404c9 ('sd-bus: allow receiving messages with
MSG_CTRUNC set').
core: when skipping state deserializing units, also skip job subsections (#41957)
If a unit has active jobs, when it gets serialized there are job
subsections, each with their own empty line marker. The skipping
function ignores this and skips until the marker, but then leaves
the job in place, breaking deserialization.
Consume jobs subsections too.
This shows up now that there's TEST-07-PID1.alias-corruption,
which occasionally fails when the aliased unit happens to
still have a job when the reexec happens.
Implement Path/Scope/Swap/Timer Context/Runtime for `io.systemd.Unit.List` (#41980)
The PR implements the following objects + tests for
io.systemd.Unit.List:
* PathContext
* PathRuntime
* ScopeContext
* ScopeRuntime
* SwapContext
* SwapRuntime
* TimerContext
* TimerRuntime
It's a continuation of the following PRs:
* https://github.com/systemd/systemd/pull/37432
* https://github.com/systemd/systemd/pull/37646
* https://github.com/systemd/systemd/pull/38032
* https://github.com/systemd/systemd/pull/38212
* https://github.com/systemd/systemd/pull/39391
Daan De Meyer [Tue, 12 May 2026 11:19:18 +0000 (13:19 +0200)]
btrfs-util: clear RDONLY flag on subvolume before destroy ioctl
Without CAP_SYS_ADMIN, btrfs_ioctl_snap_destroy() runs an
inode_permission(MAY_WRITE) check against the target subvolume root, which
btrfs_permission() rejects with EROFS for a read-only subvolume. As a
result, unprivileged removal of a read-only subvolume fails — both via
btrfs_subvol_remove_at() directly and via the recursive cleanup path used
by rm_rf_subvolume_and_freep(), which propagates the EROFS up.
Detect EROFS after the destroy ioctl, clear the RDONLY flag (only inode
ownership is required for BTRFS_IOC_SUBVOL_SETFLAGS), and retry once.
While at it, fix the surrounding comments: BTRFS_IOC_SNAP_DESTROY drops the
entire subvolume tree, so regular files inside are irrelevant; ENOTEMPTY
from the ioctl indicates nested subvolumes (BTRFS_ROOT_REF_KEY entries) via
may_destroy_subvol(), not non-empty contents.
journalctl: move handling of --smart-relinquish-var to action logic
The help string for --smart-relinquish-var and --relinquish-var
were in reversed order because of the _fallthrough_.
We would resolve the conditions for "smart relinquish" immediately
in parse_argv() and call 'return 0' if the conditions were wrong,
terminating option parsing and the program. It seems nicer to delay
action until later. This makes the logic flow more standard. This
also allows the option parsing cases to be exchanged, fixing the
issue with --help.
Two namespaces are used: "journalctl" and "journalctl-varlink". Help for
--user/--system in the latter is added, even though it is not used yet.
I think it'll be good to have this for introspection.
The four FSS-related options (--interval, --verify-key, --force,
--setup-keys) unfortunately each gain an inline #if HAVE_GCRYPT / #else;
the EOPNOTSUPP fallback is duplicated four times.
The metavar for --identifier/--exclude-identifier is changed to "ID"
to make the layout nicer. (And because that seems to make more sense.)
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
We have different help strings for --user/--system in different places, so this
only covers a subset of --system/--user instances. But this particular help
seems to be the most widely used.
(In a few cases, the help string is fixed: it should be "system mode", not
"per-system mode".)
journalctl: reorder parse_argv() cases to match --help
Pure reordering. ARG_SMART_RELINQUISH_VAR is kept immediately before
ARG_RELINQUISH_VAR because of the existing _fallthrough_; that's the
only deviation from strict --help order.
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
Yu Watanabe [Sun, 22 Mar 2026 08:00:33 +0000 (17:00 +0900)]
dhcp: use TLV object to manage extra and vendor options
Note, previously we replaced the previous option with the same option code with
new one. But, DHCP message can have multiple options with same option code.
Hence, this make the conf parser not replace, but append new one.
sd-dhcp-protocol: rename DHCP option 43, 124, and 125
There are four DHCP options with confusing names:
Option 43: Vendor-Specific Information
Option 60: Vendor Class Identifier
Option 124: Vendor-Identifying Vendor Class
Option 125: Vendor-Identifying Vendor-Specific Information
Let's use their full names for their corresponding enums.
Daan De Meyer [Mon, 11 May 2026 19:58:24 +0000 (21:58 +0200)]
btrfs-util: Make nested subvolume operations work unpriv
BTRFS_IOC_SEARCH is only available to root in the
initial userns. This means we fail to recursively
snapshot even if a subvolume has no nested subvolumes
at the moment.
Let's fix this by using the newer btrfs ioctls which
do work even if we don't have CAP_SYS_ADMIN in the initial
userns.
Artem Proskurnev [Tue, 12 May 2026 08:07:39 +0000 (11:07 +0300)]
hwdb/keyboard: Map f21 key on Wareus B15
Addition to PR https://github.com/systemd/systemd/pull/41181
Plasma-workspace OSD notifications about turning the touchpad on
and off are guided by f21. When this match is specified,
KDE notifies on this laptop that the on/off switch of the atchpad
state is pressed.
Fix dmesg:
atkbd serio0: Unknown key pressed (translated set 2, code 0xc1 on isa0060/serio0).
firstboot,sysinstall,hostnamed: always show FANCY_NAME=
This makes sure that whenever we want to show the OS name we can show
the fancy name. Thus this moves the escaping/validation of the fancy
name out of hostnamed into generic code, and then makes use of it in
sysinstall,firstboot,prompt-util.
Daan De Meyer [Mon, 11 May 2026 19:58:24 +0000 (21:58 +0200)]
mkosi: Drop CPUs= limit
Limiting VMs to 2 cpus was cargo culting without any
actual data that this benefits performance. The host OS
has a scheduler, let's make use of it and give the VM access
to all the CPUs. This doesn't mean they become inaccessible to
the host, it just means the VM gets as many virtual CPUs as the
host has CPU cores (threads). How they get scheduled is still up
to the host OS.
units: pull in basic.target rather than sysinit.target from system-install.target
Many of our services are nowadays implemented via socket activation, and
hence require sockets.target to be active to be accessible. One of them
is mute-console.socket, which we typically want to use from
systemd-firstboot.service, systemd-sysinstall.service and other related
services. Hence let's pull in basic.target rather than sysinit.target
from system-install.target since it pulls sockets.target in too.
Effectively, this doesn't change much except for pulling in a bunch more
sockets, and frankly going for sysinit.target was really a bug to begin
width.
Daan De Meyer [Mon, 11 May 2026 13:03:49 +0000 (13:03 +0000)]
boot,vconsole: Propagate UEFI HII keyboard layout to the OS
UEFI firmware can report the currently-active keyboard layout via
EFI_HII_DATABASE_PROTOCOL.GetKeyboardLayout(). The layout descriptor
includes an RFC 4646 / BCP 47 language tag (e.g. "en-US"). Query this
from sd-boot/sd-stub and write it to a new LoaderKeyboardLayout EFI
variable, advertised through a new EFI_LOADER_FEATURE_KEYBOARD_LAYOUT
feature bit.
On the OS side, systemd-vconsole-setup reads the variable as a
lowest-priority fallback for the console keymap. To map the BCP 47
tag to a vconsole keymap we extend /usr/share/systemd/kbd-model-map
with an optional sixth column listing the comma-separated BCP 47 tags
each row covers; a new find_vconsole_keymap_for_bcp47() helper walks
the file, preferring an exact tag match and otherwise falling back to
the row whose tag matches the input's primary subtag. Credentials,
/etc/vconsole.conf, and vconsole.keymap= on the kernel command line
continue to take precedence.
bootctl status surfaces the new variable, printing the language tag
or "n/a (not reported by firmware)" when sd-boot advertises the
feature but the firmware HII database didn't expose a layout (common
on QEMU without a USB keyboard, since EDK2's PS/2 driver does not
register an HII keyboard layout).
Daan De Meyer [Mon, 11 May 2026 13:00:19 +0000 (15:00 +0200)]
vmspawn: Attach a USB keyboard in GUI mode
EDK2's UsbKbDxe is the only driver that registers a default HII
keyboard layout via the HII database protocol; the PS/2 driver does
not. Adding a USB xHCI controller and usb-kbd in CONSOLE_GUI mode
gives us a layout to query, which systemd-boot exports through the
LoaderKeyboardLayout EFI variable — useful for exercising that
codepath end-to-end.
Michael Vogt [Fri, 8 May 2026 14:37:52 +0000 (16:37 +0200)]
units: enable systemd-report-basic.socket by default
In https://github.com/systemd/systemd/pull/41688 we merged metrics
and facts for systemd-report. However while some metric sources
are enabled by default (like `io.systemd.{Manager,Network}`) the
`io.systemd.Basic` service is not enabled by default.
This commit changes this and enables it by default.
We could also enable the systemd-report-cgroup.socket but that sends
a lot more data not sure that is a good default.
repart: make definitions varlink parameter actually optional
The Varlink iterface said the definitions directory was mandatory, and
so did the dispatch table. But that's nonsense, the code is completely
fine to operate without (same as cmdline repart invocations): it will
just use the standard definitions dir.
Luca Boccassi [Mon, 11 May 2026 11:58:13 +0000 (12:58 +0100)]
TEST-67-INTEGRITY: pre-load crypto modules and skip unsupported algorithms
The test occasionally fails on GHA CI when formatting with xxhash64
because dm-integrity's crypto_alloc_shash() -> request_module() path
flakily fails to load the algorithm:
[ 29.172664] TEST-67-INTEGRITY.sh[447]: + for a in crc32c crc32 xxhash64 sha1 sha256
[ 29.172664] TEST-67-INTEGRITY.sh[447]: + [[ xxhash64 == crc32 ]]
[ 29.172664] TEST-67-INTEGRITY.sh[447]: + test_one xxhash64 0
[ 29.172664] TEST-67-INTEGRITY.sh[447]: + integritysetup format /dev/loop0 --batch-mode -I xxhash64 ''
[ 29.223383] TEST-67-INTEGRITY.sh[1220]: device-mapper: reload ioctl on temporary-cryptsetup-fa8bebe3-1d87-4796-91e8-abc02c487bb5 (254:0) failed: No such file or directory
[ 29.226916] kernel: device-mapper: table: 254:0: integrity: Invalid internal hash (-ENOENT)
[ 29.227415] kernel: device-mapper: ioctl: error adding target to table
[ 29.231586] TEST-67-INTEGRITY.sh[1220]: Cannot format integrity for device /dev/loop0.
Preload each algorithm's crypto module before use, and skip algorithms
that are not registered in /proc/crypto.
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
Daan De Meyer [Sun, 10 May 2026 19:24:26 +0000 (21:24 +0200)]
clang-tidy: Drop unknown gcc compiler args
clang-tidy recently gained support to allow dropping
compiler args from the entries parsed from the compilation
database. Let's make use of this to drop the two compiler
args we use with gcc that clang doesn't support so we can
run clang-tidy on meson build trees configured to use gcc
without getting tons of false positives.
Ivan Kruglov [Thu, 7 May 2026 17:55:32 +0000 (10:55 -0700)]
test: use jq // empty instead of grep -v null in Unit.List tests
Replace `grep -v null` with jq's `// empty` alternative operator when filtering unit IDs. With `set -o pipefail`, `grep` returns 1 when no lines match, which aborts the script before conditional guards can run. The `// empty` operator suppresses null output directly in jq without risking a pipeline failure.
MonotonicTimerSpec and CalendarTimerSpec are separate types since they have different value types (int vs string). MonotonicTimerBase and TimerResult are proper varlink enum types.
Compared to the old io-systemd-Unit-List branch, this adds RandomizedOffsetUSec and DeferReactivation (both present in D-Bus but previously missing), and adds full runtime fields.
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
Ivan Kruglov [Thu, 7 May 2026 12:47:59 +0000 (05:47 -0700)]
shared: move OOMPolicy varlink enum to varlink-idl-common
OOMPolicy is used by both io.systemd.Manager (DefaultOOMPolicy) and io.systemd.Unit (ScopeContext.OOMPolicy), so it belongs in the shared common types alongside ManagedOOMMode and EmergencyAction.
favilances [Sat, 9 May 2026 18:52:04 +0000 (21:52 +0300)]
test-path-util: add coverage for path edge cases
Path utility helpers are used throughout systemd for validation, comparison and manipulation of filesystem paths. Add coverage for additional corner cases around absolute path detection, normalization and prefix matching so regressions in these common helpers are easier to catch.
Luca Boccassi [Fri, 8 May 2026 19:25:56 +0000 (20:25 +0100)]
test: bump TEST-58-REPART timeouts with sanitizers
The test is flaky under sanitizers as the timeouts seem to be too short,
bump them like we do in other tests to try and make it more robust when
running with sanitizers
Luca Boccassi [Fri, 8 May 2026 15:16:04 +0000 (16:16 +0100)]
test: fix flaky TEST-07-PID1.socket-defer.sh
The socket's SubState transitions from 'running' to 'listening' shortly
after the triggered service becomes inactive, so the assert can race and
observe the stale 'running' state:
Luca Boccassi [Fri, 8 May 2026 14:09:25 +0000 (15:09 +0100)]
test: workaroud flaky TEST-53-TIMER.restart-trigger against journald cgroup attribution race
The restart-trigger subtest occasionally fails on CI with:
+ assert_eq 0 1
FAIL: expected: '1' actual: '0'
even though the timer fires correctly and the echo message is in fact
written to the journal. The failure happens because the test relies on
`journalctl --unit=$UNIT_NAME` to find the message, and that filter is
based on the cgroup journald looks up for the writer PID at the time
the stdout message is received.
For very short-lived processes spawned via systemd-executor (like
`echo`), that lookup is racy: the writer's `/proc/$PID/cgroup` can
still resolve to `/init.scope` (systemd-executor's own cgroup) rather
than the service's cgroup, so the message ends up attributed to
`init.scope` and `--unit=` filtering misses it.
Note _SYSTEMD_UNIT=init.scope / _SYSTEMD_CGROUP=/init.scope on the
echo output: this is what causes `--unit=timer-restart-14362` to
return 0 hits. The test failure logs from the same run confirm this:
+ JOURNAL_TS=1778160292
+ journalctl -p info --since=@1778160292 --unit=timer-restart-14362 '--grep=Hello from timer 29581'
-- No entries --
+ systemctl restart timer-restart-14362.timer
...
+ date '--set=+2 hours'
Thu May 7 15:24:52 UTC 2026
+ sleep 1
...
echo[816]: Hello from timer 29581
...
++ journalctl -q -p info --since=@1778160292 --unit=timer-restart-14362 '--grep=Hello from timer 29581'
++ wc -l
+ assert_eq 0 1
FAIL: expected: '1' actual: '0'
For comparison, in a passing local run the same message is attributed
correctly to the service unit (_SYSTEMD_UNIT=timer-restart-24147.service),
so `--unit=` matches.
Work around the underlying journald race in the test by setting an
explicit `SyslogIdentifier=` on the service and matching with `-t` plus
the unique grep pattern: `SyslogIdentifier` is carried over the stdout
stream protocol and is not affected by the cgroup lookup race.
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
The ITE keyboard controller firmware (version 0xAB83) is shared
between the Clevo PA70ES and the X+ piccolo series.
The piccolo's hwdb rule matches by input device ID
(evdev:input:b0011v0001p0001eAB83*) and remaps scan code 0x9c
(KP_Enter) to Enter, since the piccolo has no numpad and its
main Enter key sends the wrong scan code.
The Clevo PA70ES has a real numpad. The piccolo rule matches it
because both laptops use the same ITE controller firmware, which
breaks KP_Enter on the PA70ES.
Add a DMI-specific override that restores KEY_KPENTER for 0x9c
on the PA70ES.
The piccolo rule should ideally be narrowed to use DMI matching
instead of input device ID to avoid catching other laptops with
the same ITE controller firmware.
Daan De Meyer [Fri, 8 May 2026 19:28:36 +0000 (21:28 +0200)]
mkosi: drop libucontext again
Turns out it's possible to implement fibers without unnecessary
system calls and without ucontext.h so there's no need for libucontext
anymore, so drop it from the package list.
Ivan Kruglov [Thu, 7 May 2026 09:16:51 +0000 (02:16 -0700)]
test: add missing varlink IDL enum tests for Job and ServiceType
PR #41583 (io.systemd.Unit.StartTransient) introduced several new varlink IDL enum types without corresponding enum consistency tests:
- JobType, JobState, JobResult in the new io.systemd.Job interface
- ServiceType in the Unit interface's ServiceContext
Add a new test-varlink-idl-job test file covering all three Job enums, and add ServiceType coverage to the existing test-varlink-idl-unit test. Export vl_type_ServiceType (was static) so it can be referenced from the test.
Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
userdbctl: actually implement option parsing stop after --chain
The basic idea is that --chain should stop option parsing. But
previously this didn't work, so --chain could be specified anywhere
in the command line. To maintain with compatibility with that,
allow --chain to be specified anywhere until the first positional
arg or option in the command string. This allows options to be passed
in the expected fashion:
userdbctl --chain ssh-authorized-keys user cmd --opt1 --opt2
userdbctl --chain ssh-authorized-keys user -- cmd --opt1 --opt2
but also allows the invocations which worked previously:
userdbctl ssh-authorized-keys user --chain cmd
userdbctl ssh-authorized-keys user cmd --chain
Daan De Meyer [Fri, 1 May 2026 09:08:35 +0000 (09:08 +0000)]
curl-util: bring CurlGlue/CurlSlot in line with sd-bus and qmp-client
Refactor curl-util to use the same per-request, refcounted, cancellable
slot model as sd-bus, sd-varlink and qmp-client.
CurlGlue becomes opaque and refcounted, and dispatches per-slot
completion callbacks through CURLOPT_PRIVATE instead of a single
g->on_finished demux that every caller had to switch on. The new
curl_glue_perform_async(g, easy, cb, userdata, &slot) replaces
curl_glue_add + the on_finished/userdata wiring.
CurlSlot is the per-request handle: it owns the easy handle,
curl_slot_unref does curl_multi_remove_handle + curl_easy_cleanup
(which doubles as cancel since remove aborts in-flight transfers
without queuing CURLMSG_DONE), and floating slots (ret_slot=NULL) are
kept alive in the glue's slot set until the callback fires. Drop the
userdata parameter from curl_glue_make: CURLOPT_PRIVATE is now used
internally to route completions to the slot.
Migrate pull-job and the pull-{oci,raw,tar} drivers, and imdsd, to the
new shape. PullJob.curl becomes PullJob.slot; pull_job_curl_on_finished
becomes a per-slot callback. imdsd routes its token-vs-data branch off
slot identity rather than easy-handle pointer comparison. Both daemons
drop the global on_finished/userdata wiring on the glue. pull_job_finish
and context_fail{,_full} now return int (always 0) so the callbacks
stay in the `return finish(...);` style.
Add test-curl-util covering glue lifecycle, easy-handle defaults,
floating and non-floating perform paths, cancel-via-slot-unref (verified
by a sentinel request that drives the loop to completion), and three
concurrent requests on a single glue. Tests fetch local files via
file:// URLs so no network is needed; libcurl availability is probed
once via dlopen_curl in intro().