Peter Krempa [Tue, 21 Jul 2026 14:55:39 +0000 (16:55 +0200)]
libvirt-qemu: Add reference to QEMU agent protocol syntax
Add a reference to the expected format of commands used with
'virDomainQemuAgentCommand'.
Closes: https://gitlab.com/libvirt/libvirt/-/work_items/891 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Peter Krempa [Tue, 21 Jul 2026 13:23:11 +0000 (15:23 +0200)]
libvirt-domain: Use consistent flag names for APIs declaring use of 'virDomainDeviceModifyFlags'
APIs which declared that they use 'virDomainDeviceModifyFlags' enum as
flags used 'virDomainModificationImpact' flag names instead. Fix the
flag names so that it's consistent.
Closes: https://gitlab.com/libvirt/libvirt/-/work_items/897 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Peter Krempa [Thu, 16 Jul 2026 13:51:02 +0000 (15:51 +0200)]
qemuxmlconftest: Add a note that the pinned CPU model tests test also old-style QMP monitor instantation
qemu-11.1 switched to the new syntax. Rather than adding a redundant
test case add a comment that we use the pinned cpu tests for the old QMP
monitor too.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Peter Krempa [Tue, 23 Jun 2026 11:33:35 +0000 (13:33 +0200)]
qemuMonitorJSONIOProcessLine: Log monitor object pointer in debug message
The debug message recording the string we've got to process didn't
specify which monitor object the reply comes from which makes it harder
to follow what's happening in cases when multiple VMs communicate (e.g.
when reconnecting at startup).
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Jim Fehlig [Wed, 11 Mar 2026 23:16:53 +0000 (17:16 -0600)]
sanlock: Add option to check ownership of disk leases
In a clustered environment it may be desirable to provision disk leases
for use by a specific domain. This patch adds a 'check_disk_lease_owner'
option to the sanlock driver to check that leases are owned by the domain
attempting to acquire them. sanlock's Lock Value Block (LVB) is used to
store the owning domain UUID within the lease. When a domain is started
and attempts to acquire its leases, the sanlock driver will ensure its
UUID matches the UUID recorded in the leases. Any mismatches will cause
lease acquisition and domain startup to fail.
The 'check_disk_lease_owner' option is disabled by default. When enabled,
it can be used with auto_disk_leases or leases managed by an external
application.
Signed-off-by: Jim Fehlig <jfehlig@suse.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
HE WEI(ギカク) [Thu, 9 Jul 2026 10:47:43 +0000 (19:47 +0900)]
storage_file: bound-check the qcow2v3 header-size read
qcow2GetExtensions() reads a 4-byte value at offset QCOW2v3_HDR_SIZE (100) for a
version-3 image, but the only upstream length guard (qcow2GetFeatures) requires
just buf_size >= 100. For a probed file of 100-102 bytes this reads up to 3 bytes
past the buffer. Require buf_size >= QCOW2v3_HDR_SIZE + 4 before the read, as the
other probe helpers already do for their offsets.
The remote driver client supports specifying a transport in the URI
scheme component such as +ext, +unix, +tls, etc. This determines how
it should connect to the daemons. It strips this transport from the
scheme to create a plain driver name that it forwards on to the remote
server.
It also, however, supports a "name" URI parameter which can be used
to override the stripped URI that gets sent to the remote server.
Unfortunately there is no validation of the URI by the remote server,
so the URI override could include the transport in the scheme
component. When the remote server sees a transport in the URI scheme,
the connection gets diverted into the remote driver which then opens
another client connection.
When the "ext" transport is combined with the "command" URI parameter,
this allows the client to trick the server into running an arbitrary
command with the same privileges as the server. This can be abused
with a read-only connection to a privileged server in order to elevate
local privileges.
There is no a valid reason to accept a transport component in the
URI scheme received by the server, so validate this condition and
reject any connection that violates it.
This patch is derived from a proposal made by the reporter along
with their disclosure, but generalized to block all schemes, not
merely +ext and apply unconditionally to all connections not merely
read-only ones.
Reported-by: Deutsche Telekom Red Team <redteam@telekom.de> Fixes: CVE-2026-15268 Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
HE WEI(ギカク) [Wed, 8 Jul 2026 12:00:00 +0000 (12:00 +0000)]
security: apparmor: reject rule-injection characters in smartcard database path
The smartcard host-certificates <database> path is written straight into the
generated AppArmor profile with virBufferAsprintf(), bypassing valid_path()
which every other emitted path goes through. valid_path() rejects '"' precisely
to stop AppArmor rule injection; because the smartcard path skips it, and
virBufferEscapeString() does not escape newlines in element content, a crafted
<database> value can inject arbitrary profile rules (e.g. "/** rwmlk,").
Reject '"' and newline characters in the value before emitting it.
HE WEI(ギカク) [Thu, 9 Jul 2026 10:35:22 +0000 (19:35 +0900)]
qemu: saveimage: validate cookieOffset and NUL-terminate XML buffer
qemuSaveImageReadHeader() computed cookie_len = data_len - xml_len in size_t
with no check that cookieOffset <= data_len; a crafted header with
cookieOffset > data_len underflows cookie_len to ~SIZE_MAX and g_new0() aborts
the daemon. The XML buffer was also allocated to exactly xml_len with no NUL
terminator, then parsed as a C string, allowing a heap over-read for a
non-NUL-terminated payload. Reject cookieOffset > data_len and allocate one
extra (zeroed) byte for the XML terminator.
tests: cover line-break rejection in DNS TXT and SRV records
Add negative tests that feed XML numeric character references for LF
( ) and CR ( ) into the DNS TXT value and SRV domain/target
attributes, covering both the network XML parse path and the update
API. Literal newlines are insufficient because XML parsers normalize
raw attribute whitespace to spaces; the numeric references are what
survive to the configuration emitter.
CVE-2026-61477
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
network: reject line breaks before writing dnsmasq DNS config
The parser now rejects line breaks in typed DNS TXT and SRV fields,
but the dnsmasq configuration emitter is the actual trust boundary:
any future parser gap, or a value reaching the emitter by another
path, would again let a typed DNS field inject an arbitrary dnsmasq
directive.
Add a defensive check in networkDnsmasqConfContents() that rejects
LF and CR in every typed DNS string immediately before it is written
to the line-based configuration file. This sits behind the parser
checks and keeps the emitter correct on its own.
The raw <dnsmasq:options> namespace is intentionally left untouched:
it is the documented escape hatch for arbitrary dnsmasq options, and
sanitizing it would be a separate, deliberate behavior change.
CVE-2026-61477
Fixes: 8b32c80df089 ("network: put dnsmasq parameters in conf-file instead of command line") Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
conf: reject line breaks in DNS SRV domain and target
The <dns><srv> domain and target attributes flow through the same
dnsmasq configuration emitter as TXT values, written into srv-host=
lines. Like the TXT value they accept XML numeric character
references for LF and CR and are not otherwise constrained, unlike
service and protocol which already have allow-lists. An embedded
line break ends the srv-host= directive and begins a new one.
Reject LF and CR in the SRV domain and target during XML parsing,
reusing the helper added for TXT values.
CVE-2026-61477
Fixes: 6612d1adb794 ("network: fix problems with SRV records") Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
The network XML schema exposes typed DNS records through the
<dns><txt> element. The TXT value attribute accepts XML numeric
character references, including (LF) and (CR), which
survive attribute-value normalization. The network driver later
writes the value verbatim into dnsmasq's line-oriented configuration
file as a txt-record= line, so an embedded line break ends that
directive and starts a new one under attacker control.
This is a real boundary where a management layer permits editing
typed DNS records while withholding the raw <dnsmasq:options>
passthrough: the injected line escapes that restriction. Direct
read-write access to the libvirt socket is already root-equivalent,
so for the default deployment this is schema-correctness hardening.
Add a helper that rejects LF and CR and call it for the TXT value
during XML parsing.
CVE-2026-61477
Fixes: 8b32c80df089 ("network: put dnsmasq parameters in conf-file instead of command line") Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
src: fix crash searching for XML context string on errors
When we have an XML parse error, libxml2 invokes a callback that
receives pointers to the start of the document being parsed and the
location where the error was triggered.
In the case of a document that contains 100's of empty lines
(ie a sequence of newlines), at some point libxml2 will advance
the base pointer discarding the useful context.
Thus when catchXMLError then searches backwards to discard empty
lines and look for the context element, it will eventually get
to the start of the string. When this happens the virBuffer that
holds the context string ends up empty and then catchXMLError will
dereference a NULL pointer.
In almost all cases, the APIs which accept XML documents from
the user are behind the primary read-write socket, however, the
CPU baseline API is exposed to the read-only socket. Thus an
unprivileged user can trigger a denial of service by crashing
the libvirt daemons with a malicious XML document.
Check for this empty string condition and skip inclusion of the
XML document context in the error message.
Fixes: CVE-2026-61478 Reported-by: Rx <rx1513@altlinux.org> Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Current cleanup routine for the domain start errors misses quite a few
important steps. It does not set the proper domain state, it does not
clean up sockets and so forth. The only thing it does is destroying of
the actual domain and performing network cleanup.
To properly clean all resources, replace running
virBhyveProcessBuildDestroyCmd() command with executing
virBhyveProcessStop() which already does the necessary steps.
Extend virBhyveProcessStop() with the forceCleanup boolean argument
which instructs it not to error out on some checks to account for
inconsistent state after the partial startup.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
The virBhyveProcessStartImpl() function which implements domain start
does not check if bhyve monitor open is successful. Check that and
jump to the cleanup routines if it was not.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Implementation is fairly similar to the one found in the test and qemu
drivers. Lack of checkpoint and snapshot support in the bhyve driver
makes the implementation a bit simpler.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
virt-host-validate-bhyve: replace if_tap check with if_tuntap check
The tun(4) and tap(4) FreeBSD device drivers were merged
into a single tuntap(4) driver back in 2019 and now it's effective
for all supported FreeBSD versions.
As the virt-host-validate-bhyve still checks for the "if_tap" module,
it does not report actual status on the supported FreeBSD releases.
Fix by checking for the "if_tuntap" module instead.
Signed-off-by: Nimish Jain <unauthorizen@gmail.com> Reviewed-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
Jim Fehlig [Mon, 20 Apr 2026 17:36:48 +0000 (11:36 -0600)]
build: Add option to control building libvirtd
Add meson option 'libvirtd' to control building of the monolithic
libvirtd, independent from the stateful, daemon-based drivers. E.g.
meson configure -Dlibvirtd=disabled build-dir
The new option defaults to 'auto' and will be enabled when 'driver_libvirtd'
is enabled. Setting libvirtd=disabled skips building the libvirtd binary,
and related items such as config files, systemd units, etc.
The existing option 'driver_libvirtd' controls building libvirtd and all
stateful, daemon-based drivers, making it unsuitable for disabling only
the monolithic daemon. Additionally, 'driver_libvirtd' is used by the
various libvirt-ci projects to produce a minimalistic build.
Signed-off-by: Jim Fehlig <jfehlig@suse.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
lxc: Assign aliases to filesystem and network devices
LXC domains did not assign device aliases to filesystem and network
interface during domain startup. Only console devices received
aliases.
This change introduces two new functions:
- virLXCAssignDeviceNetAlias()
- virLXCAssignDeviceFSAlias()
These functions scan existing devices to find the next available
device index. Also ensure correct alias assignment after network
and block device hotplug/unplug operations when a gap can
be introduced in device numbering.
The new functions are called during:
- domain startup virLXCProcessStart()
- device hotplug lxcDomainAttachDeviceNetLive()
Signed-off-by: Radoslaw Smigielski <rsmigiel@redhat.com> Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Let's modify our gendispatch.pl script so that the code it
generates for the ACL checks uses g_autoptr instead of explicit
unref()-ing in each exit path.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Denis V. Lunev [Thu, 18 Jun 2026 14:51:49 +0000 (16:51 +0200)]
qemu: stop silently narrowing the guest CPU during live migration
qemuDomainMakeCPUMigratable() strips the features that a CPU model marks
as added (in src/cpu_map/x86_*.xml) from the migratable definition unless
the user requested them explicitly. This keeps a custom CPU migratable to
an older destination libvirt whose copy of the model does not know those
features yet.
A host-model CPU gains nothing from this and is actively harmed by it. By
the time it reaches this function host-model has already been expanded
into an explicit custom model that is exactly what we ask QEMU for on the
source, and host-model is not guaranteed to migrate to an older libvirt
in the first place. Stripping the added features only narrows the guest
CPU silently on the destination.
Every Intel model from Westmere through Sapphire Rapids marks
vmx-exit-load-perf-global-ctrl and vmx-entry-load-perf-global-ctrl as
added. These control the LOAD_IA32_PERF_GLOBAL_CTRL allowed-1 bits of the
MSR_IA32_VMX_{EXIT,ENTRY}_CTLS MSRs, which modern QEMU only advertises
when the features are present on the -cpu command line. After a host-model
live migration the destination QEMU is started without them, so a nested
guest observes different VMX capability MSRs than it did before the
migration. A guest that snapshots those MSRs at kvm_intel module load and
validates every newly onlined CPU against the snapshot -- Linux does
exactly that -- then refuses to bring up a vCPU hot-plugged after the
migration:
kvm_intel: Inconsistent VMCS config on CPU N
kvm: enabling virtualization on CPUN failed
smpboot: CPU N is now offline
and the guest agent's online attempt returns -EIO.
Treat a host-model CPU's features as explicitly requested by building the
keep list from the already expanded definition rather than from origCPU.
Custom CPUs are unaffected, so their migration compatibility with older
destinations is preserved.
Signed-off-by: Denis V. Lunev <den@openvz.org> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Michal Privoznik [Wed, 24 Jun 2026 07:10:54 +0000 (09:10 +0200)]
spec: Enable hyperv driver on RHEL
Resolves: https://redhat.atlassian.net/browse/RHEL-187057 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Now on startup everything is fine, because with socket activation, when
'virtqemud.service' wants to use 'virtlogd' services the socket is
already up due to the dependency+ordering and opening a connection will
cause 'virtlogd.service' to be socket-activated.
On shutdown though there's no transitive 'After' ordering between
'virtqemud.service' and 'virtlogd.service' and thus nothing explicitly
telling systemd that if virtlogd was started. In fact systemd is free to
translate it that 'virtlogd' and 'virtqemud' need to be stopped before
stopping 'virtlogd.socket'.
To illustrate what happens consider the following scenario:
A host is running a VM under virtqemud. 'virtqemud' is configured to
attempt shutdown on the VMs before killing them (daemon-based guest
shutdown, but the same reproduces also with libvirt-guests). The host
is being rebooted.
(virtqemud attempts to shut down guests, but guest takes more than the
configured shutdown inhibition timeout, journald output follows):
Now the log shows that we want to add VM log file message in
'qemuDomainLogAppendMessage' but it fails because virtlogd is dead
already.
Now the same happens also with 'virtlockd' but with much worse outcome,
especially if the configured action is to save the VMs because shutdown
of 'virtlockd' when locks are held ends up 'fencing' the VMs by killing
them.
The same also happens when libvirt-guests is used to shutdown the guests
instead.
This patch adds an explicit 'After=virtlo[ck|g]d.service' to the daemons
containing the qemu driver to ensure that the shutdown ordering makes
sense. This doesn't break socket activation (e.g. the log/lock daemons
are not started unless first invoked).
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Peter Krempa [Thu, 18 Jun 2026 13:12:10 +0000 (15:12 +0200)]
virQEMUCapsLogProbeFailure: Reraise error with more information
While we don't normally try to re-wrap errors to be more descriptive,
probing of qemu capabilities is a special case as the errors can be
cryptic and don't give users enough information about what's going on.
An example is (obtained from a patched qemu which accidentally returned
a broken QMP schema):
$ virsh start VM
error: Failed to start domain 'VM'
error: internal error: Duplicate hash table key 'str'
The error is unusable. On the other hand in 'virQEMUCapsLogProbeFailure'
we do special logging of the caps probing failure with a custom UUID so
that it can be easily found in the logs which reports a much better
error message. Re-raise the same as a normal error too so that the user
gets similar experience:
$ virsh start VM
error: Failed to start domain 'VM'
error: internal error: Failed to probe capabilities for /home/user/git/qemu.git/build/qemu-system-x86_64: internal error: Duplicate hash table key 'str'
This does mean though that the error is logged twice, once via the
custom log entry and second via 'virReportError'. Given that this error
is extremely unlikely, having two log entries IMO doesn't warant
reworking the whole error reporting infra to allow passing extra
metadata just for this one case.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Peter Krempa [Thu, 18 Jun 2026 12:52:50 +0000 (14:52 +0200)]
qemuProcessQMPStop: Preserve error when killing qemu used for capability probing
When probing of capabilities fails 'qemuProcessQMPStop' kills the qemu
process, but also resets the error. The virResetLastError() was
originally intended to reset the error from 'virProcessKillPainfully',
it also resets any probing error resulting in the following:
$ virsh start VM
error: Failed to start domain 'VM'
error: An error occurred, but the cause is unknown
Keep the error clearing as this might be called on success but preserve
the original error around it.
Fixes: db7b0b12b7b07b8a0313161e3cbedb38a74e5954 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Akash Kulhalli [Wed, 10 Jun 2026 10:54:14 +0000 (16:24 +0530)]
qemuhotplugtest: test setvcpus async downscale
Add async unplug coverage for the setvcpus count-based path.
The test downscales an x86 domain by multiple hotpluggable vCPU entities,
verifying the pending XML before completion, the final XML after DEVICE_DELETED
processing, and one vcpu-removed event for each removed vCPU.
Signed-off-by: Akash Kulhalli <akash.kulhalli@oracle.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Akash Kulhalli [Wed, 10 Jun 2026 10:54:13 +0000 (16:24 +0530)]
qemuhotplugtest: test setvcpu async unplug
Add async unplug coverage for the setvcpu path.
The x86 case covers removal of a single hotpluggable vCPU entity, while the
ppc64 case covers removal of a grouped hotpluggable entity. Both cases verify
the pending XML before DEVICE_DELETED, the final XML after completion, and the
expected vcpu-removed events.
Signed-off-by: Akash Kulhalli <akash.kulhalli@oracle.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Akash Kulhalli [Wed, 10 Jun 2026 10:54:12 +0000 (16:24 +0530)]
qemuhotplugtest: support async vcpu unplug completion
Add async CPU hotplug harness support so tests can observe the state
between device_del and DEVICE_DELETED, and then complete the unplug
through the QEMU driver's normal process-event path.
The async path compares the pending live XML, emits DEVICE_DELETED
events via the monitor test helper, waits for the driver worker to
process them, and validates the vcpu-removed events before running the
existing final XML checks.
Signed-off-by: Akash Kulhalli <akash.kulhalli@oracle.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Akash Kulhalli [Wed, 10 Jun 2026 10:54:10 +0000 (16:24 +0530)]
qemu: expose process event handler to tests
Async QEMU process events are normally completed through
qemuProcessEventHandler(). Tests that exercise DEVICE_DELETED completion
need to drive that same path instead of mirroring the production logic locally.
Move the declaration to a guarded private header and make the handler
non-static so test code can wire it into a test worker pool. This does not
change runtime behaviour.
Signed-off-by: Akash Kulhalli <akash.kulhalli@oracle.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
VIR_NODE_CPU_STATS_GUEST was introduced in: b5878727c714
("util: virHostCPUGetStatsLinux: support VIR_NODE_CPU_STATS_GUEST")
with the goal of specifically accounting the CPU time spent running guest VCPUs.
Unfortunately at the time it was not considered that to get a measure of this
time, "guest" is not sufficient, because any guest that is "niced" is accounted
in a separate category, "guest_nice".
This patch rectifies the situation by adding the guest_nice counter, so that
VIR_NODE_CPU_STATS_GUEST = (guest + guest_nice)
which makes the statistic useful to the caller, as the totals sum up correctly.
In order to find the total USER time spent running host tasks, for example:
Michal Privoznik [Mon, 22 Jun 2026 10:51:39 +0000 (12:51 +0200)]
virsh: Add completer for '--type' option of 'attach-interface' command
The '--type' option of 'attach-interface' command is translated
from string into int using virDomainNetTypeFromString(), IOW the
expected value is from virDomainNetType enum.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
vmx: Fix a case with 64 disks on one SCSI controller
The constants for maximum units on a bus are slightly tricky because for
the narrow bus it does not need to account for the extra unit used by
the controller, but the wide and super-wide ones need to.
With this patch a VMX with 64 disks on a pvscsi controller can be
properly parsed.
To properly handle the maximum numbers one of the conditions also needs
to be changed to not allow for units 16 and 65. This does not change
various conditionals in XML parsing and VMX formatting as they need a
significant rewrite. And since that is already working only with the
wide scsi controller (and not the super-wide one) we leave that refactor
for another day as it was done previously.
Tests show this is now possible and they fail before this change.
Resolves: https://redhat.atlassian.net/browse/RHEL-181350 Signed-off-by: Martin Kletzander <mkletzan@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Implement domain reboot using the guest agent.
Implementation is very similar to the domain shutdown
added earlier.
Also, change the VIR_DOMAIN_REBOOT_ACPI_POWER_BTN flag
to VIR_DOMAIN_REBOOT_SIGNAL. Even though bhyve emulates
the ACPI button, it's triggered by sending a signal to the
bhyve process, so VIR_DOMAIN_REBOOT_SIGNAL looks like
a more accurate description of communication between
libvirt and bhyve.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Implement shutdown using a guest agent.
Implementation and behaviour is very similar to the one
found in the qemu driver.
The bhyveDomainShutdownFlags() function now supports
the VIR_DOMAIN_SHUTDOWN_SIGNAL and VIR_DOMAIN_SHUTDOWN_GUEST_AGENT.
If flags were not specified, try the agent first, and if it does
not work, proceed with the signal.
As we do not expect a response from the agent shutdown command,
we do not check qemuAgentShutdown()'s return value. Assume that the
command failed if the agent did not receive EOF, thus "priv->agent"
is not NULL.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
qemu: use proper job type for qemuDomainAuthorizedSSHKeysSet()
The qemuDomainAuthorizedSSHKeysSet() call currently uses
VIR_AGENT_JOB_QUERY. While it's not an issue as this call does not
modify any of the libvirt-stored state, semantically it modifies
the domain, so VIR_AGENT_JOB_MODIFY fits better. Also, similar
calls like qemuDomainSetUserPassword() or qemuDomainSetTime()
already use VIR_AGENT_JOB_MODIFY, so use it in
qemuDomainAuthorizedSSHKeysSet() too.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Michal Privoznik [Thu, 18 Jun 2026 07:53:09 +0000 (09:53 +0200)]
virsh: Make --type argument of detach-interface optional
The detach-interface virsh command requires domain (obviously)
and --type to identify <interface/>. Optionally, --mac can be
provided to chose from multiple interfaces. Well, that renders
--type argument redundant. I mean, if there are but unique MACs
within domain XML, then interface type is implied. If there are
duplicate MACs then --type can help to differentiate, though at
that point detach-device seems like a better fit.
Long story short, make --type optional.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Michal Privoznik [Thu, 18 Jun 2026 07:20:25 +0000 (09:20 +0200)]
lxc: Rework cleanup section in lxcDomainAttachDeviceNetLive()
The cleanup section in lxcDomainAttachDeviceNetLive() is
suspicious. It checks @ret for success and adds net into domain
definition. This is not something fits into cleanup. It belongs
right before 'ret = 0' line when we know everything before
succeeded. Moving that piece of code where it belongs, the
cleanup section becomes error because it is executed only in case
of failure.
Change the label to error, fix corresponding goto-s, and drop
@ret variable.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Michal Privoznik [Thu, 18 Jun 2026 07:14:15 +0000 (09:14 +0200)]
lxc: Don't leak @veth in lxcDomainAttachDeviceNetLive()
During hotplug of an <interface/> into an LXC domain
(lxcDomainAttachDeviceNetLive()), the host side name of the
interface is stored in @veth variable. Well, all possible paths
that set the variable (virLXCProcessSetupInterfaceTap(),
virLXCProcessSetupInterfaceDirect()) document it is caller's
responsibility to free the memory. But it never does so.
==49848== 12 bytes in 2 blocks are definitely lost in loss record 68 of 1,763
==49848== at 0x4913888: malloc (vg_replace_malloc.c:447)
==49848== by 0x546F0BC: __vasprintf_internal (in /usr/lib64/libc.so.6)
==49848== by 0x5077A70: g_vasprintf (in /usr/lib64/libglib-2.0.so.0.8400.4)
==49848== by 0x50404DB: g_strdup_vprintf (in /usr/lib64/libglib-2.0.so.0.8400.4)
==49848== by 0x50405A4: g_strdup_printf (in /usr/lib64/libglib-2.0.so.0.8400.4)
==49848== by 0x4A8591E: virNetDevGenerateName (virnetdev.c:3573)
==49848== by 0x4A93C38: virNetDevVethCreate (virnetdevveth.c:124)
==49848== by 0xED6C505: virLXCProcessSetupInterfaceTap (lxc_process.c:279)
==49848== by 0xED5F7A7: lxcDomainAttachDeviceNetLive (lxc_driver.c:3517)
==49848== by 0xED60D24: lxcDomainAttachDeviceLive (lxc_driver.c:3925)
==49848== by 0xED6262D: lxcDomainAttachDeviceFlags (lxc_driver.c:4453)
==49848== by 0xED62819: lxcDomainAttachDevice (lxc_driver.c:4485)
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Michal Privoznik [Wed, 17 Jun 2026 15:20:20 +0000 (17:20 +0200)]
lxc: Drop pointless g_free() from virLXCProcessStart()
When staring an LXC domain (well, container) its consoles are
opened and each one is assigned an alias (for later use with
virDomainOpenConsole()). Now, before generating new alias the old
one is freed. But the old one can never be anything other than
NULL. The domain is inactive at this point (we are in process of
starting it, after all). And LXC driver does not support user
aliases, yet.
Just drop the pointless g_free().
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Peter Krempa [Wed, 10 Jun 2026 10:38:00 +0000 (12:38 +0200)]
qemuDeviceVideoGetModel: Simplify by relying on checks from 'qemuValidateDomainDeviceDefVideo'
'qemuValidateDomainDeviceDefVideo' ensures that only the correct video
device models are selected as well as that only QXL and VIRTIO video
devices can be selected as secondary.
Remove unnecessary checks and simplify the code.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Tue, 9 Jun 2026 20:02:21 +0000 (22:02 +0200)]
qemuDeviceVideoGetModel: Remove logic for selecting 'virtio' devices
The virtio video device frontend type is either selected by the
post-parse code based on capabilities or provided by the user/existing
XML explicitly. No need to try to come up with a model when generating
commandline based on broken logic.
The difference in test output shows:
- honours user's config in case of the new 'device' attribute
- shows how incorrect fallback would be used for 'virtio-vga-gl'
(picked virtio-vga (non-gl) instead of 'virtio-gpu-gl')
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Wed, 10 Jun 2026 12:45:24 +0000 (14:45 +0200)]
qemuValidateDomainDeviceDefVideo: Fix checks of virtio video devices
The currently existing checks are broken:
- only QEMU_CAPS_DEVICE_VHOST_USER_GPU is checked for vhostuser
backends (vhost-user-vga is actually separately packaged)
- the check for the 3d accelerated (-gl) versions checks only if one
of them exists (the commandline formatter picks a non-gl afterwards)
- 'virtio-vga'/'virtio-gpu' is not checked at all
The code also doesn't yet check if, when the user passes the new
'device' property manually the config actually makes sense.
To fix all of the above introduce a table of supported frontend devices
as well as properties that need to be checked for them.
This requires fixing a recently-introduced test case which shows a
nonsensical situation.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Mon, 8 Jun 2026 14:54:50 +0000 (16:54 +0200)]
qemu: postparse: Fill in selected virtio video frondend device in the XML
Historically 'virtio-vga' was always picked as the first '<video>'
(virtio) device and any sub-sequent ones were 'virtio-gpu'. When support
for aarch64 VMs was being added an exception to use 'virtio-gpu' for the
primary device was added as aarch64 doesn't have anything resembling the
"legacy" 'VGA' interface. At this point this exception was only for
aarch64. The distinction between 'virtio-vga' and 'virtio-gpu' was *not*
recorded in the VM XML as it was a new feature (for aarch64) and it
didn't make sense to pick 'virtio-vga'.
qemu_command: properly detect which model to use for video device
This improves commit 706b5b6277 in a way that we check qemu capabilities
instead of what architecture we are running on to detect whether we can
use *virtio-vga* model or not. This is not a case only for arm/aarch64.
modified the code to do this picking by checking presence of
'virtio-vga' device instead. That approach didn't consider the fact that
the modular deployment of qemu allows for the 'virtio-vga' device to be
missing in certain cases, thus introducing a latent bug as we'll pick
'virtio-gpu' in such case but don't record it anywhere.
Now this creates a problem, if the deployments differ, because you can
have two *incompatible* (at migration stream level) setups which are
based on the same identical XML without the possibility for the
destination libvirt instance during migration to pick which is the
correct one.
To prevent this and actually fix any existing such deployment (which
allows upgrade of libvirt daemons on the source) we will record the
picked device frontend at post-parse time into the XML. This luckily
properly handles running VMs even if 'virtio-vga' were already
installed since we record the actual qemuCaps we've started the VM with.
Now 'virtio-vga' vs 'virtio-gpu' is not the only broken piece of logic.
In fact 'virtio-vga-gl' could have been downgraded to 'virtio-vga' based
on some very weird logic (see comments in code for explanation).
The logic in 'qemuDomainDeviceVideoDefPostParse' re-creates the logic
used to setup virtio-vga vs. virtio-gpu, and 'vhost-user-vga' vs.
'vhost-user-gpu' as those still make sense. For the 'gl' variants two
versions exist, one meant to recover running VMs and one for new VMs
where the broken logic makes no sense.
Now this patch just records what was selected into the XML, but doesn't
yet modify the commandline to actually use that value verbatim (e.g. if
the user specified an actual non-default value already).
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Mon, 8 Jun 2026 13:11:45 +0000 (15:11 +0200)]
qemuDeviceVideoGetModel: Directly return picked model
There's no point in falling through to the check reporting invalid
type since if the code picks a model that one will be valid.
Reorganize the code so that we can return final decision right away.
This means that the two flags 'virtio' and 'virtioBusSuffix' need to be
set prior to the return.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Mon, 8 Jun 2026 14:55:05 +0000 (16:55 +0200)]
conf: Add fields for recording actually-selected virtio video device
QEMU's commandline generator picks for virtio video between various
actual device models not only based on the XML definition but also
capabilities present. Since none of the devices is actually ABI
compatible we need to record the actually selected device in the XML.
which will record the actually selected model so that we can preserve
ABI across restarts on deployment changes but more importantly across
migrations where the deployment differs.
The code specifically avoids an ABI stability check for the new field
because there are already possibly broken configurations that the users
may want to fix by picking the proper model which could be forbidden.
Users are instructed to not set the field in the XML.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Mon, 8 Jun 2026 15:30:50 +0000 (17:30 +0200)]
qemustatusxml2xml: Add test case capturing virtio video device
Add example of two running configs with distinct recorded capabilities
(presence of QEMU_CAPS_DEVICE_VIRTIO_VGA at startup) which will
demonstrate the recording of the picked actual device type on the
commandline.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Wed, 10 Jun 2026 14:31:44 +0000 (16:31 +0200)]
qemuxmlconftest: Add invocation of 'video-virtio-vga-gpu-gl' with missing caps and VIR_DOMAIN_DEF_PARSE_ABI_UPDATE
Similarly to previous patch add testing of 'virtio-gpu-gl' or
'virtio-vga-gl' with missing the respective capabilities, but this time
allowing VIR_DOMAIN_DEF_PARSE_ABI_UPDATE.
This will later on show that in case when the fallback can't be honoured
the code will not pick a device that doesn't support acceleration (the
non-gl variant).
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Tue, 9 Jun 2026 12:33:04 +0000 (14:33 +0200)]
qemuxmlconftest: Add test cases for configs asking for 'virtio-gpu-gl' or 'virtio-vga-gl' without the capability
The capability check in 'qemuValidateDomainDeviceDefVideo' which
validates whether a <video> definition with acceleration enabled is
possible is only aggregate, thus validates that any '-gl' video backend
is available.
Since qemu compiles each backend into a separate module it's possible to
have an installation where 'virtio-gpu-pci-gl' exist but 'virtio-vga-gl'
doesn't and it will not be rejected at validation. The commandline
though will generate a device *without* the '-gl' which is ABI
incompatible with the counterpart which does have '-gl', but the VM
starts. If such a VM is then migrated to a deployment which does have
the '-gl' variant available, migration will fail because qemu will
generate the '-gl' device as we don't record this fact in the XML.
This test case captures this situation which will be fixed later.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Tue, 26 May 2026 12:14:31 +0000 (14:14 +0200)]
qemuxmlconftest: Add 'video-virtio-vga' invocation with QEMU_CAPS_DEVICE_VIRTIO_VGA disabled
The test case shows that if the 'QEMU_CAPS_DEVICE_VIRTIO_VGA' capability
is not present (e.g. if the corresponding qemu module isn't installed)
libvirt will pick:
-device '{"driver":"virtio-gpu-pci", ...
instead of:
-device '{"driver":"virtio-vga", ...
but without any discernable difference in the XML.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Upcoming patches will add additional testing for various virtio-*-gl
devices, including filling of the default model. The output file needs
to not influnece the input for this test to work properly.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Tue, 26 May 2026 09:39:28 +0000 (11:39 +0200)]
virQEMUCapsCacheLookupDefault: Fix error message when no emulators are installed
When querying capabilities for the default emulator with no other
arguments (e.g. 'virsh domcapabilities) fix error whithout emulator
installed an error is reported but the error would mention '(null)'
architecture:
# virsh domcapabilities
error: failed to get emulator capabilities
error: unsupported configuration: unable to find any emulator to serve '(null)' architecture
This happens as the error formatting takes 'archStr' which is NULL for
the default architecture instead of using 'arch' which is populated by
the host's architecture and converting it back.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Thu, 11 Jun 2026 10:56:17 +0000 (12:56 +0200)]
qemu: postparse: Process VM config with qemuCaps influenced by <qemu:capabilities>
The user configuration of added/removed qemu capabilities via the qemu
namespace element was applied only right before generating a
commandline, but the post parse code code didn't see these.
Apply the capability modification prior to running post parse code so
that defaults are properly picked based on the configuration.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Thu, 11 Jun 2026 10:52:16 +0000 (12:52 +0200)]
qemu: validate: Validate VM config with qemuCaps influenced by <qemu:capabilities>
The user configuration of added/removed qemu capabilities via the qemu
namespace element was applied only right before generating a
commandline, but the validation code didn't see these.
Modify the validation entry points so that they apply this optionally.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Thu, 11 Jun 2026 10:00:45 +0000 (12:00 +0200)]
qemu: Allow reuse of 'qemuProcessStartUpdateCustomCaps'
Move and rename the function to 'qemuDomainUpdateCustomCapabilities' and
modify the arguments so that it will be possible to reuse it also in the
post-parse and validation code which ought to base decisions on the same
logic as VM startup would.
Since copying of the qemu capabilities object is very expensive (I've
observed an almost 4x slowdown of qemuxmlconftest)
'qemuDomainUpdateCustomCapabilities' copies the capabilities only when
necessary.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Thu, 11 Jun 2026 10:12:42 +0000 (12:12 +0200)]
qemu: capabilities: Export 'virQEMUCapsNewCopy' outside of 'qemu_capspriv'
Upcoming patch will add a function which will need to optionally copy
passed capabilities for modification. Export 'virQEMUCapsNewCopy'
outside of tests.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Peter Krempa [Thu, 11 Jun 2026 09:33:36 +0000 (11:33 +0200)]
qemu: capabilities: Apply 'capability_filters' configration option on all capabilities
The 'capability_filters' allows admins to globally disable some qemu
capabilities via the config file.
Until now it was applied only directly when starting the VM, but that is
too late as the capability is still present when e.g. the post-parse
code is picking defaults.
Rework the code so that 'capability_filters' is applied directly after
probing qemu so all existing capabilities will lack the filtered out
ones.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
The bhyveConnectAgent() function calls qemuAgentOpen() to open an agent
connection. If it fails, e.g. because of insufficient permissions to
open the socket, it returns NULL. Currently, if that happens,
bhyveConnectAgent() just sets agentError to true and exits with 0.
This does not match the contract of bhyveDomainEnsureAgent(), which
should either provide an agent connection or fail.
Fix that by returning -1 when qemuAgentOpen() fails. To make intent
clearer, add a documentation for bhyveConnectAgent().
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Currently, the bhyve driver reboot implementation
does not take into account domain's on_reboot action.
Update it so it shuts a domain down on reboot when it is
configured this way.
Additionally, introduce the bhyveDomainShutdownSignal() helper
which shares a common shutdown and reboot implementation
using a signal.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Currently, the bhyve driver shutdown implementation
does not take into account domain's on_poweroff action.
Update it so it reboots a domain on shutdown when it is
configured this way.
Signed-off-by: Roman Bogorodskiy <bogorodskiy@gmail.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>