Andrea Bolognani [Tue, 13 Feb 2024 18:28:09 +0000 (19:28 +0100)]
qemu: Improve error message for USB controller validation
Use the same wording as for SCSI controllers, which also
happens to contain additional information (the controller's
index).
The new error message and error type are more accurate anyway:
in most cases, it's perfectly fine for the user not to provide
a controller model explicitly, as libvirt will try to figure
out a reasonable default.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
qemu: Move error reporting out of qemuDomainDefaultSCSIControllerModel()
We want this helper to work more like other similar ones, where
error reporting is performed by the caller. This introduces a
small amount of code duplication but makes for a cleaner API.
Signed-off-by: Andrea Bolognani <abologna@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Michal Privoznik [Wed, 11 Jun 2025 11:59:49 +0000 (13:59 +0200)]
virt-aa-helper: Check retval of vah_add_file()
Inside of get_files() there are two cases where vah_add_file() is
not checked for its retval. This is possibly dangerous, because
vah_add_file() might fail. Fix those places by introducing checks
for the retval.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Wed, 11 Jun 2025 11:52:46 +0000 (13:52 +0200)]
virt-aa-helper: Decrease scope of @mem_path in get_files()
The @mem_path variable inside of get_files() is used only within
a single block. Move its declaration inside it. And also utilize
automatic memory freeing.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Tue, 10 Jun 2025 07:27:58 +0000 (09:27 +0200)]
virt-aa-helper: Simplify paths collection
The way virt-aa-helper works is the following: the apparmor
secdriver formats domain XML, spawns virt-aa-helper process and
feeds it with domain XML (through stdin). The helper process then
parses the XML and iterates over devices, appending paths in each
loop.
These loops usually are in the following form:
for (i = 0; i < ctl->def->nserials; i++) {
if (ctl->def->serials[i] && ...
}
While we are probably honourable members of tautology club, those
NULL checks are redundant. Our XML parses would never append NULL
into def->devices array. If it did, we're in way bigger problems
anyway.
Then, constantly dereferencing ctl->def just to get to a path
that's hidden a couple of structures deep gets hard to read. Just
introduce temporary variables.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Tue, 10 Jun 2025 12:31:20 +0000 (14:31 +0200)]
virt-aa-helper: Rework USB hostdev handling
For an USB device, the virt-aa-helper must put that
/dev/bus/usb/... path associated with given device. The way the
code is currently written not only leads to a memleak (the @usb
variable is allocated only to be overwritten right away), but is
needlessly cumbersome.
We can use virHostdevFindUSBDevice() to find the USB device,
check if its missing and if not add the path associated with it
into the profile.
While at it, also use automatic memory freeing for the variable.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Tue, 10 Jun 2025 12:30:40 +0000 (14:30 +0200)]
virt-aa-helper-test: Test hostdevs unconditionally
Our test suite is very feature rich. In particular, it has two
mocks that implement sysfs close enough to create
host-independent environment to work with PCI and USB devices.
These mocks are called virpcimock and virusbmock, respectively.
Inside of virt-aa-helper-test there is an attempt to test whether
virt-aa-helper generates profiles for <hostdevs/>, once for USB
and the other time for PCI. Use this mocks to run virt-aa-helper
in an environment where certain PCI/USB devices always exist.
There are two problem though:
1) those two test cases use hardcoded PCI/USB addresses, which
makes them host environment dependant,
2) neither of the test cases checks whether corresponding rule
was added into the profile.
Using mocks we can get away with problem 1), and by passing the
fifth argument to testme() we can list an expected rule in the
profile.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Tue, 10 Jun 2025 09:58:34 +0000 (11:58 +0200)]
virt-aa-helper-test: Silence ls
virt-aa-helper checks presence of files before it adds them into
a profile. Because of that, test cases inside of
virt-aa-helper-test that require presence of /boot/initrd* are
guarded by a check. The check uses ls to find at least one initrd
file. If there's none, then ls prints an error onto stderr. This
is not helpful because the test script prints a message on its
own right after.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Tue, 10 Jun 2025 09:57:43 +0000 (11:57 +0200)]
virt-aa-helper-test: Print errors to stderr
When a test case fails, there are two echo-s executed: the first
one either prints the error message into /dev/null (default) or
onto stdout (when the test script is executed with -d). Then, the
second one prints the error message onto stdout. While this
technically works, there's nothing ever printed onto stderr which
is usually what's captured. Worse, if some command within the
script fails, it prints something onto stderr but then looking at
meson logs it's needlessly hard to match stderr and stdout lines.
Just print error messages onto stderr.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Wed, 11 Jun 2025 14:17:33 +0000 (16:17 +0200)]
tests: Fix mocking of open()
In some cases (well, majority), open() is either rewritten to
open64(), either by plain '#define open open64') or at assembly
level (using __REDIRECT macro). See <fcntl.h> for more info.
This didn't really matter to us, because we do not chain load two
mocks that would need to reimplement open() at the same time. But
this is soon going to change.
The problem is, that VIR_MOCK_REAL_INIT(open) glances over
aforementioned rewrite and initializes real_open pointer to
open() from the standard C library. But it needs to point to
open() (well, open64()) from the next mock on the list.
Therefore, init real_open to open64().
But of course, this is all glibc specific and for example musl
does the oposite (#define open64 open).
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Wed, 11 Jun 2025 11:19:32 +0000 (13:19 +0200)]
virpcimock: Strip fakerootdir prefix in virFileCanonicalizePath()
The mocked implementation of virFileCanonicalizePath() redirects
accesses to few dirs into a temporary directory, where PCI
related files live. See getrealpath() for more info on this.
Anyway, in the end - real implementation of
virFileCanonicalizePath() is called which then might contain the
'fakerootdir' prefix. Up until now this did not matter because
none of our test really cared about actual value of resolved
path. They usually cared about last component of the path or
something. But this will soon change.
TLDR - if the returned path has $fakerootdir prefix, strip it.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Tue, 10 Jun 2025 13:11:55 +0000 (15:11 +0200)]
virpcimock: Automatically invent fakerootdir, if not provided
Currently, all users of virpcimock do set LIBVIRT_FAKE_ROOT_DIR
envvar. But soon, virt-aa-helper will be run with it and
basically right at the beginning of its main() it clears whole
environment. So even if the envvar is provided the mock won't see
that.
Anyway, the solution is to just create a tempdir and then 'rm
-rf' it in the desctructor.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Wed, 11 Jun 2025 11:19:12 +0000 (13:19 +0200)]
virt-aa-helper: Use virFileCanonicalizePath()
While use of realpath() is not forbidden, our some of our mocks
already have a test friendly reimplementation of
virFileCanonicalizePath(). Use the latter.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Michal Privoznik [Wed, 11 Jun 2025 11:18:55 +0000 (13:18 +0200)]
log_cleaner: Use virFileCanonicalizePath()
While use of realpath() is not forbidden, our some of our mocks
already have a test friendly reimplementation of
virFileCanonicalizePath(). Use the latter.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
gendispatch: Finish rename of the migration argument
This patch is useless.
Either APIs it don't have 'resource' nor 'bandwidth' argument to
begin with, or they serve as a wrapper over different API
(changed in previous commits). Nonetheless, in the name of
consistency, let's just change those variable names.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
src: Unify argument name of virDomainMigratePerform3()
The virDomainMigratePerform3() API declares its last argument as
'bandwidth', though throughout various typedefs, RPC and callback
implementations the name is changed to 'resource'. This creates a
confusion. Unify the name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
src: Unify argument name of virDomainMigrateBegin3()
The virDomainMigrateBegin3() API declares its last argument as
'bandwidth', though throughout various typedefs, RPC and callback
implementations the name is changed to 'resource'. This creates a
confusion. Unify the name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
src: Unify argument name of virDomainMigratePrepareTunnel3()
The virDomainMigratePrepareTunnel3() API declares one of its
argument as 'bandwidth', though throughout various typedefs, RPC
and callback implementations the name is changed to 'resource'.
This creates a confusion. Unify the name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
src: Unify argument name of virDomainMigratePrepare3()
The virDomainMigratePrepare3() API declares one of its argument
as 'bandwidth', though throughout various typedefs, RPC and
callback implementations the name is changed to 'resource'. This
creates a confusion. Unify the name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
src: Unify argument name of virDomainMigratePrepareTunnel()
The virDomainMigratePrepareTunnel() API declares one of its
argument as 'bandwidth', though throughout various typedefs, RPC
and callback implementations the name is changed to 'resource'.
This creates a confusion. Unify the name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
src: Unify argument name of virDomainMigratePrepare2()
The virDomainMigratePrepare2() API declares one of its argument as
'bandwidth', though throughout various typedefs, RPC and callback
implementations the name is changed to 'resource'. This creates a
confusion. Unify the name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
src: Unify argument name of virDomainMigratePerform()
The virDomainMigratePerform() API declares its last argument as
'bandwidth', though throughout various typedefs, RPC and callback
implementations the name is changed to 'resource'. This creates a
confusion. Unify the name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
src: Unify argument name of virDomainMigratePrepare()
The virDomainMigratePrepare() API declares its last argument as
'bandwidth', though throughout various typedefs, RPC and callback
implementations the name is changed to 'resource'. This creates a
confusion. Unify the name.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Akihiko Odaki [Sat, 8 Mar 2025 05:57:41 +0000 (14:57 +0900)]
qemu: Replace usb-storage with usb-bot
usb-storage is a compound device that automatically creates a USB mass
storage device and a SCSI device as its backend. Unfortunately it lacks
some configuration options that are usually present with a SCSI device,
and cannot represent CD-ROM in particular.
Replace usb-storage with usb-bot, which can be combined with a manually
created SCSI device. libvirt will configure the SCSI device in a way
identical with how QEMU does for usb-storage except that now it respects
a configuration option to represent CD-ROM.
Peter Krempa [Thu, 19 Jun 2025 07:46:38 +0000 (09:46 +0200)]
qemuBuildDeviceAddresDriveProps: Prepare for 'drive' address for usb-bot disks
While the 'usb-storage' based disks use the USB address directly, with
'usb-bot' the USB address is on the "controller" part of the device and
the 'scsi-hd/cd' device will use a 'drive' address from qemu's PoV.
Since we do not want to expose the 'usb-bot' as explicit controller
to preserve compatibility with existing configs we plan to upgrade
implement the formatter for 'drive' address when the "diskbus" property
is VIR_DOMAIN_DISK_BUS_USB.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Peter Krempa [Mon, 23 Jun 2025 15:51:16 +0000 (17:51 +0200)]
qemu: Fill in model of 'usb' disks to preserve ABI compatibility
While 'usb-bot' and 'usb-storage' are ABI and migration compatible for
disks it's not the case for cdroms. When migrating from a new config
using 'usb-bot' to an older daemon which would use 'usb-storage' the
guest os will get I/O errors.
Thus we must properly fill in models for 'usb' disks so that cdroms can
be handled properly.
When parsing XML fill in the models and drop the appropriate models when
formatting migratable XML.
The logic is explained in comments in the code.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Peter Krempa [Thu, 19 Jun 2025 13:46:46 +0000 (15:46 +0200)]
conf: introduce usb disk models 'usb-storage' and 'usb-bot'
Historically libvirt specified 'usb-storage' as driver for USB disks.
This though combined with '-blockdev' doesn't properly configure the
device to look like CDROM for <disk type='cdrom'>.
'usb-bot' acts like a controler and allows explicitly connecting a
-device to it.
In qemu the devices share implementation so they are effectively
identical and can be used interchangably. There is a difference in how
the storage device itself (the SCSI part) looks when configured properly
as CDROM which is unfortunately not compatible/interchangable.
As this is effectively a bugfix we'll be fixing the behaviour for the
default configuration. The possibility to explicitly set the model is
added as a possibility for working around possible problems if they'd
appear.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Peter Krempa [Thu, 19 Jun 2025 13:31:46 +0000 (15:31 +0200)]
qemuxmlconftest: Invoke "disk-usb-device" case also without QEMU_CAPS_DEVICE_USB_BOT and with ABI_UPDATE
The QEMU_CAPS_DEVICE_USB_BOT device can be compiled out but
realistically it makes no sense to do it thus also makes no sense to
have another variant of input data for it.
Add another invocation of "disk-usb-device" clearing QEMU_CAPS_DEVICE_USB_BOT
to show the fallback code paths.
Also add "ABI_UPDATE" version for the two cases above as the ABI of
usb-bot cdrom is not migration-compatible and we'll be wanting to update
to the fixed configuration.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Peter Krempa [Thu, 19 Jun 2025 08:07:35 +0000 (10:07 +0200)]
qemuxmlconftest: Distribute testing of 'removable' disk property
The 'removable' property is tested for 'usb' and 'scsi' disks. The test
case for 'usb' disks already has another test case for this, so add
testing of 'removable' SCSI disks into the 'disk-scsi' case and remove
the 'disk-device-removable' case completely.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Peter Krempa [Thu, 19 Jun 2025 07:58:10 +0000 (09:58 +0200)]
qemuxmlconftest: Test various combinations of config
Add multiple USB disks to the definition testing a matrix of 'disk' and
'cdrom' <disk> elements with user-aliases, 'serial' and 'removable'
properties configured.
This patch also removes the 'ide' disk which is not related to what
we're testing here.
Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
util: workaround libxml2 lack of thread safe initialization
The main XML parser code global initializer historically had a mutex
protecting it, and more recently uses a pthread_once. The RelaxNG
code, however, relies on two other global initializers that are
not thread safe, just relying on setting an integer "initialized"
flag.
Calling the relevant initializers from libvirt in a protected global
initializer will protect libvirt's own concurrent usage, however, it
cannot protect against other libraries loaded in process that might
be using libxml2's schema code. Fortunately:
* The chances of other loaded non-libvirt code using libxml is
relatively low
* The chances of other loaded non-libvirt code using the schema
validation / catalog functionality inside libxml is even
lower
* The chances of both libvirt and the non-libvirt usage having
their *1st* usage of libxml2 be concurrent is tiny
IOW, in practice, although our solution doesn't fully fix the thread
safety, it is good enough.
libxml2 should none the less still be fixed to make its global
initializers be thread safe without special actions by its API
consumers[1].
Resolves: https://gitlab.com/libvirt/libvirt/-/issues/788
[1] https://gitlab.gnome.org/GNOME/libxml2/-/merge_requests/326 Reviewed-by: Peter Krempa <pkrempa@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Ján Tomko [Wed, 12 Mar 2025 15:22:25 +0000 (16:22 +0100)]
qemu: introduce QEMU_CAPS_PCI_ID
Introduced by QEMU commit f864a3235ea1d1d714b3cde2d9a810ea6344a7b5
the presence of this attribute allows libvirt to specify the alias
of the AMDVI-PCI device explicitly.
(It was implicit before the introduction of this attribute)
Signed-off-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Peter Krempa [Wed, 18 Jun 2025 06:29:01 +0000 (08:29 +0200)]
virSocketAddrPrefixToNetmask: Prevent undefined behaviour on bitshifts on signed integer
Shifting bits into the sign bit is undefined behaviour in C although
both gcc and clang handle it as expected.
Since the value is used as unsigned convert it to unsigned int. For code
readability use 'if' statement instead of a ternary.
Closes: https://gitlab.com/libvirt/libvirt/-/issues/785 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Peter Krempa [Tue, 17 Jun 2025 13:01:26 +0000 (15:01 +0200)]
tlscert: Don't force 'keyEncipherment' for ECDSA and ECDH
Per RFC8813 [1] which amends RFC5580 [2] ECDSA, ECDH, and ECMQV
algorithms must not have 'keyEncipherment' present, but our code did
check it. Add exemption for known algorithms which don't use it.
Closes: https://gitlab.com/libvirt/libvirt/-/issues/691 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Peter Krempa [Tue, 17 Jun 2025 08:42:52 +0000 (10:42 +0200)]
storage: disk: Properly handle partition numbers separated by 'p'
The 'p' separator for partitions is now common also for NVMe devices.
Fix the algorithm to extract the partition number to always consider it.
The fix is based on suggestion in the issue mentioned below.
Closes: https://gitlab.com/libvirt/libvirt/-/issues/239 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>
Peter Krempa [Tue, 17 Jun 2025 08:00:20 +0000 (10:00 +0200)]
virshPrintJobProgress: Don't rewrite migration status line on non-terminals
On non-terminals print each progress report on a new line. Fix based on
suggestion in the issue report.
Closes: https://gitlab.com/libvirt/libvirt/-/issues/756 Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com> Reviewed-by: Ján Tomko <jtomko@redhat.com>