Commit Graph
100 Commits
Author SHA1 Message Date
Michal Privoznik 1f9a64a016 build: prohibit realpath() by syntax-check
We have virFileCanonicalizePath() which calls realpath() but
also is present in our mocks (in contrast to realpath()).
Introduce a syntax-check rule to enforce use of our wrapper.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-07-15 10:13:23 +02:00
Michal Privoznik 01badd1bfb virt-aa-helper-test: Switch to getopts
Instead of treating -d and -v arguments as positional, use
getopts to parse cmd line arguments passed to
virt-aa-helper-test script.

While at it, introduce -h for printing basic help describing each
argument.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-07-02 13:54:38 +02:00
Michal Privoznik 9569a43b7a virt-aa-helper: Drop cleanup label from get_files()
After previous cleanup the cleanup label is no longer necessary.
Drop it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-07-02 13:54:36 +02:00
Michal Privoznik ecca0dded4 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>
2025-07-02 13:54:30 +02:00
Michal Privoznik 05e06927b6 virt-aa-helper: Use automatic memory freeing
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-07-02 13:54:27 +02:00
Michal Privoznik 2f7e11aaa3 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>
2025-07-02 13:54:23 +02:00
Michal Privoznik 980607b1e9 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>
2025-07-02 13:54:20 +02:00
Michal Privoznik cca3563602 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>
2025-07-02 13:54:17 +02:00
Michal Privoznik 935bd37c4a 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>
2025-07-02 13:54:12 +02:00
Michal Privoznik 9f12874238 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>
2025-07-02 13:54:10 +02:00
Michal Privoznik 58bf3de02c 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>
2025-07-02 13:54:07 +02:00
Michal Privoznik 300965f4f1 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>
2025-07-02 13:54:04 +02:00
Michal Privoznik 21e7bcc14f 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>
2025-07-02 13:54:00 +02:00
Michal Privoznik 99dd19c013 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>
2025-07-02 13:53:56 +02:00
Michal Privoznik 96f286ef1d 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>
2025-07-02 13:53:53 +02:00
Michal Privoznik 68e877c1ad 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>
2025-07-02 13:53:49 +02:00
Michal Privoznik 55668bc3e0 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>
2025-07-02 10:00:13 +02:00
Michal Privoznik 9d69dc2dbc qemu: Finish argument rename
There are still some functions around migration code that use
'resource' instead 'bandwidth'. Rename the variable/argument
inside them.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-07-02 10:00:13 +02:00
Michal Privoznik 91e74f1de8 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>
2025-07-02 10:00:13 +02:00
Michal Privoznik 96a5c4cb85 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>
2025-07-02 10:00:13 +02:00
Michal Privoznik 767b2b72e7 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>
2025-07-02 10:00:13 +02:00
Michal Privoznik 45d4a7bf57 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>
2025-07-02 10:00:13 +02:00
Michal Privoznik 0cf91e4ed3 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>
2025-07-02 10:00:13 +02:00
Michal Privoznik 8e5e69e6eb 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>
2025-07-02 10:00:13 +02:00
Michal Privoznik 846e584654 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>
2025-07-02 10:00:13 +02:00
Michal Privoznik 74976e7e52 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>
2025-07-02 10:00:13 +02:00
Michal Privoznik cd867f28cf NEWS: Document features/improvements/bug fixes I've participated in
There are some features/improvements/bug fixes I've either
contributed or reviewed/merged. Document them for upcoming
release.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-06-30 12:05:35 +02:00
Michal Privoznik be04898d18 security_manager: Don't leak seclabel in virSecurityManagerGenLabel()
When a domain is being started, seclabels are generated for it.
This is handled in virSecurityManagerGenLabel() which can either
find pre-existing seclabel in domain def or generate a new one.
At any rate, domainGenSecurityLabel() callback is called and if
it fails then the seclabel is removed from domain definition
using VIR_DELETE_ELEMENT(). While this shrinks down the seclabels
array, it does not free individual item. It has to be freed
manually.

80 bytes in 2 blocks are definitely lost in loss record 1,359 of 1,876
   at 0x484CEF3: calloc (vg_replace_malloc.c:1675)
   by 0x4F19B29: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.8200.5)
   by 0x49E4953: virSecurityLabelDefNew (virseclabel.c:59)
   by 0x4BDE0A4: virSecurityManagerGenLabel (security_manager.c:638)
   by 0xBA029B7: qemuProcessPrepareDomain (qemu_process.c:6760)
   by 0xBA07DF2: qemuProcessStart (qemu_process.c:8369)
   by 0xB93DAC0: qemuDomainObjStart (qemu_driver.c:6371)
   by 0xB93DE08: qemuDomainCreateWithFlags (qemu_driver.c:6420)
   by 0xB93DE86: qemuDomainCreate (qemu_driver.c:6438)
   by 0x4CECEA8: virDomainCreate (libvirt-domain.c:7142)

Now, you might think this may lead to a double free, because
@seclabel is freed under the 'cleanup' label (if @generated is
true). But if @generated is true, then just before calling the
callback there's VIR_APPEND_ELEMENT() which clears @seclabel out
turning the free under 'cleanup' label into a NOP.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-06-18 11:37:58 +02:00
Michal Privoznik 441c23a7e6 qemu: Be more forgiving when acquiring QUERY job when formatting domain XML
In my previous commit of v11.0.0-rc1~115 I've made QEMU driver
implementation for virDomainGetXMLDesc() (qemuDomainGetXMLDesc())
acquire QERY job. See its commit message for more info. But this
unfortunately broke apps witch fetch domain XML for incoming
migration (like virt-manager). The reason is that for incoming
migration the VIR_ASYNC_JOB_MIGRATION_IN async job is set, but
the mask of allowed synchronous jobs is empty (because QEMU can't
talk on monitor really). This makes virDomainObjBeginJob() fail
which in turn makes qemuDomainGetXMLDesc() fail too.

It makes sense for qemuDomainGetXMLDesc() to acquire the job
(e.g. so that it's coherent with another thread that might be in
the middle of a MODIFY job). But failure to dump XML may be
treated as broken daemon (e.g. virt-manager does so).

Therefore, still try to acquire the QUERY job (if job mask
permits it) but, do not treat failure as an error.

Fixes: 6cc93bf288
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2369243
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2025-06-18 10:41:33 +02:00
Michal Privoznik 657d677a2f ci: refresh with 'lcitool manifest'
- Replace Alpine 3.21 with 3.22

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2025-06-09 12:14:49 +02:00
Michal Privoznik 3588bad8c0 libxl_capabilities: Make some functions return void
Inside of libxlMakeDomainCapabilities() there are some functions
called and basically all of them never return anything but zero
(indicating success). Yet, they are called in a fashion that
suggests otherwise. Turn those functions into void and drop
checks for their retvals.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-06-05 14:08:55 +02:00
Michal Privoznik 496afd354f NEWS: Document removal of support of VIR_DUMP_LIVE flag from QEMU driver
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2025-06-03 16:51:32 +02:00
Michal Privoznik 65bc6b0d4e qemu: Don't accept VIR_DUMP_LIVE flag in qemuDomainCoreDumpWithFormat()
QEMU can't really do live dumps of guest memory. It's because
inside of dump_init() the vm_stop() is called basically
unconditionally (the only condition is whether vCPUs are
running). Hence, there is no way for us to do live dumps and thus
honor VIR_DUMP_LIVE flag. Instead of silently pretending the flag
works, reject it with appropriate error message.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/646
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2025-06-03 16:51:32 +02:00
Michal Privoznik 481a38c45f libvirt_nss: Allocate buffer in aiforaf() dynamically
While we were trying to decrease stack usage of some functions,
in v9.8.0-rc1~217 we introduced a couple of internal blocks to
the aiforaf() and declared some variables inside those blocks
hoping the compiler will reuse the stack for each block. While in
general this might be a good strategy, specifically in case of
NSS_NAME(gethostbyname2) this is a terrible thing to do.

Problem is, NSS_NAME(gethostbyname2) is given a caller allocated
buffer and an address of a pointer where the resolved address is
stored. And you've probably guessed it already: upon successful
return, the pointer is set to point somewhere inside the buffer.

Now, if the buffer doesn't live long enough, which in our case it
does not (since it was left in the previous block), we should
refrain from dereferencing the resolved pointer.

Just allocate the buffer on the heap.

Fixes: 9e5f2fe402
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-05-22 15:44:12 +02:00
Michal Privoznik 209ca5f839 libvirt_nss: Allocate buffer in ERROR() dynamically
So far, inside of the ERROR() macro there's pretty large buffer
allocated on the stack (for use by strerror_r()). Problem is,
with our current stack size limit of 2048 bytes we may come
pretty close to the limit or even overshoot it, e.g. in aiforaf()
where the function itself declares another stack allocated buffer
1024 bytes long.

Just allocate the buffer dynamically.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-05-22 15:44:12 +02:00
Michal Privoznik 6133c09cf5 libvirt_nss: Drop needless cleanup labels
After previous cleanup, some labels were rendered pointless. Drop
them.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-05-22 15:44:12 +02:00
Michal Privoznik dbd41b6558 libvirt_nss: Use automatic memory freeing
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-05-22 15:44:12 +02:00
Michal Privoznik 6d1848ac12 nss: Declare g_autofree and g_steal_pointer() macros
While we do not want the nss plugin to link with anything but
necessary libs (libc and libjson-c) it can benefit from automatic
memory freeing. Instead of inventing macros with new name for
them, lets stick with g_autofree and g_steal_pointer() which we
are used to from the rest of the code. Borrow and simplify
definitions for these macros then.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-05-22 15:44:12 +02:00
Michal Privoznik f79ef43f2c nss: Add missing includes for gai_strerror()
There are two places where gai_strerror() is called but neither
of them includes all necessary header files as documented in its
manpage. Fortunately, both calls occur in ERROR() macro which by
default does nothing - hence we don't see any compilation errors.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-05-22 15:44:12 +02:00
Michal Privoznik 46b0115778 libvirt_nss_macs: Fix type of @len in findMACsFromJSON()
Inside of findMACsFromJSON(), the retval of
json_object_array_length() is stored in a variable that's type of
int. But the function is declared to return size_t:

  /usr/include/json-c/json_object.h:JSON_EXPORT size_t json_object_array_length(const struct json_object *obj);

Fix the type of the local variable.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-05-22 15:44:12 +02:00
Michal Privoznik 768b539d83 spec: Bump min_fedora
Fedora 40 is now officially at end of life [1]. The minimal
version we aim to support upstream is thus Fedora 41. Reflect
this in the spec file.

1: https://lists.fedoraproject.org/archives/list/devel-announce@lists.fedoraproject.org/thread/XCUBN7NR7LXFFSA3IJDRTGHC7K4CXARV/

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-05-16 13:51:25 +02:00
Michal Privoznik e2bc742fcc spec: Bump min_rhel
RHEL-8 is out of our support scope. The minimal version we aim to
support upstream is RHEL-9. Reflect this in the spec file.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-05-16 13:51:25 +02:00
Michal Privoznik 37ce03c6fe ci: refresh with 'lcitool manifest'
- Add Fedora 42
- Remove EOL Fedora 40
- Switch mingw from Fedora 41 to Fedora 42

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-16 13:51:25 +02:00
Michal Privoznik 1e2b13fb20 src: Fix retval of some functions declared to return an int
There are couple of functions (virCHDomainPrepareHostdevPCI(),
qemuDomainPrepareHostdevPCI(),
virStorageBackendRBDSetAllocation(), virCommandHandshakeChild())
that are declared to return an integer, but in fact return a
boolean. This may lead to incorrect behaviour. Fix their retvals.

This diff was generated using the following semantic patch:

  @@
  identifier foo;
  @@

  int foo(...) {
      <+...
  (
  -   return true;
  +   return 0;
  |
  -   return false;
  +   return -1;
  )
      ...+>
  }

Each function and its callers were then inspected to see what
retvals are expected.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-15 10:49:41 +02:00
Michal Privoznik fe1f94a034 virsh-pool.c: Fix return type of virshBuildPoolXML()
The virshBuildPoolXML() function is declared to return an int but
in fact its return type is a boolean. Even its both callers
(cmdPoolCreateAs() and cmdPoolDefineAs()) treat its retval as a
boolean. Switch the return type from integer to boolean.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-15 10:49:26 +02:00
Michal Privoznik a9adca0956 virnetdevvlan: Fix return type of virNetDevVlanEqual()
The virNetDevVlanEqual() function is declared to return an int
but in fact its return type is a boolean. Even its only caller
(qemuDomainChangeNet()) treats its retval as a boolean. Switch
the return type from integer to boolean.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-15 10:49:25 +02:00
Michal Privoznik a857d993d1 storage_backend_rbd.C: Fix return type of a volStorageBackendRBDUseFastDiff() stub
Inside of storage_backend.c there are two implementations of
volStorageBackendRBDUseFastDiff() function: one when librbd is
new enough and one when it isn't. The former returns a bool, but
the latter is declared to return an int despite it returning a
boolean. Fix the latter.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-15 10:49:24 +02:00
Michal Privoznik 1cf0944ceb qemu_process: Fix return type of qemuDomainHasHotpluggableStartupVcpus()
The qemuDomainHasHotpluggableStartupVcpus() function is declared
to return an int but in fact its return type is a boolean. Even
its only caller (qemuProcessLaunch()) treats its retval as a
boolean. Switch the return type from integer to boolean.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-15 10:49:23 +02:00
Michal Privoznik 7e763c5275 nwfilter: Fix return type of virNWFilterCanApplyBasicRules callback
The virNWFilterCanApplyBasicRules() callback returns an int but
in fact its return type is a boolean. Even its only
implementation (ebiptablesCanApplyBasicRules()) returns a
boolean. Switch the return type from integer to boolean.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-15 10:49:23 +02:00
Michal Privoznik 9fc9395c41 storage_backend_rbd.c: Make virStorageBackendRBDSetAllocation() stub report an error
Inside of storage_backend_rbd.c there are two implementations of
virStorageBackendRBDSetAllocation(). One reports an error on
failure, so the stub implementation should report an error too.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-15 10:49:21 +02:00
Michal Privoznik 6c4260b501 virnetlink: Split virNetlinkBridgeVlanFilterSet()
Currently, virNetlinkBridgeVlanFilterSet() takes @cmd as the
second argument where either RTM_SETLINK or RTM_DELLINK is
expected. Both of these constants come from linux/rtnetlink.h and
thus are undefined when building without netlink. This design
also clashes with the whole point of virnetlink: to offload
netlink dependency onto a single file.

Therefore, drop the argument, turn
virNetlinkBridgeVlanFilterSet() into just setter, effectively,
and introduce virNetlinkBridgeVlanFilterDel() for the case when
RTM_DELLINK would be passed as @cmd.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/770
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-14 12:32:11 +02:00
Michal Privoznik 6a23a61496 virnetdevbridge: Include virnetlink.h more often
The whole point of virnetlink.h is that it hides away the build
time dependency on netlink. It wraps netlink functions in our
functions which then have a stub implementation in case netlink
support was disabled.

Though, netlink is still Linux specific, so keep it in the
'#ifdef __linux__` block to cause a compilation error should
anybody try to use any of the wrapped functions on non-Linux.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-14 12:32:08 +02:00
Michal Privoznik 54fbcc6c7d virnetdevbridge.c: Fix comments in virNetDevBridgeSetupVlans()
We still use C89 style of comments. Fix C99 style of comments
used in virNetDevBridgeSetupVlans().

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-14 12:32:07 +02:00
Michal Privoznik 89c622744f virnetlink: Provide stub for virNetlinkBridgeVlanFilterSet()
In virnetlink.c there are two sections: the first one when
building WITH_LIBNL support, the other that provides stubs for
functions declared in the corresponding header file when building
without netlink support. But the stub implementation for
virNetlinkBridgeVlanFilterSet() was missing.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-14 12:32:02 +02:00
Michal Privoznik 6ff8d08777 qemu_capabilities: Fetch caps for virtio-mem-ccw too
While with upstream QEMU it's impossible to have virtio-mem-ccw and not
have virtio-mem-pci, in RHEL the QEMU's build system is patched to make
that possible. But this breaks our assumption when fetching
capabilities.

Well, just do what we are already doing in this situation (e.g.
"virtio-blk-pci"/"virtio-blk-ccw" & virQEMUCapsDevicePropsVirtioBlk, or
"virtio-scsi-pci"/"virtio-net-ccw" & virQEMUCapsDevicePropsVirtioSCSI):
fetch the same set of props for both devices.

Resolves: https://issues.redhat.com/browse/RHEL-87528
Resolves: https://issues.redhat.com/browse/RHEL-87532

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-09 08:43:30 +02:00
Michal Privoznik 2756609a3e docs: hooks: Document when shutoff-reason argument was introduced
Introduced in v10.5.0-rc1~52, qemu and lxc hook scripts are
executed with additional argument: shutoff reason. But wording of
our docs make it looks like it's been that way forever. Make it
clear this is `recent` feature.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/766
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-05-06 08:31:39 +02:00
Michal Privoznik 5df511d178 scripts: Adapt mock-noinline.py to ATTRIBUTE_MOCKABLE
The script is renamed to mockable-attribute.py and adjusted to
check for the new attribute.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2025-05-02 14:31:19 +02:00
Michal Privoznik f8bc6af44d src: s/G_NO_INLINE/ATTRIBUTE_MOCKABLE/
Per change in coding style done in previous commit,
ATTRIBUTE_MOCKABLE should be used instead of G_NO_INLINE for
functions that are mocked in our test suite. Do the change.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2025-05-02 14:31:19 +02:00
Michal Privoznik 76f8c0b80d internal: Introduce ATTRIBUTE_MOCKABLE
Currently, if we want to mock a function the noinline attribute
is appended after the function (via G_NO_INLINE macro). This used
to work for non pure functions. But there are some trivial
functions (for instance virQEMUCapsProbeHVF()) that are pure,
i.e. have no side effect, and while their call from other parts
of the code is not optimized out, their call from within the same
compilation unit (qemu_capabilities.c) is optimized out.

This is because inlining and semantic interposition are two
different things. Even GCC's documentation for noinline attribute
[1] states that clearly:

  This function attribute prevents a function from being
  considered for inlining. It also disables some other
  interprocedural optimizations; it’s preferable to use the more
  comprehensive noipa attribute instead if that is your goal.

  Even if a function is declared with the noinline attribute,
  there are optimizations other than inlining that can cause
  calls to be optimized away if it does not have side effects,
  although the function call is live.

Unfortunately, despite attempts [2] Clang still does not support
the attribute and thus we have to rely on noinline +
-fsemantic-interposition combo.

1: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute
2: https://reviews.llvm.org/D101011

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2025-05-02 14:31:19 +02:00
Michal Privoznik e1fdff61be scripts: Fix reading list of files in mock-noinline.py
The mock-noinline.py script is fed list of files through its
stdin, each file on its own line. Unfortunately, the way the
script is written does nothing as the trailing newline character
prevents any .endswith() match. Strip each line of white spaces.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-04-28 14:35:29 +02:00
Michal Privoznik c19c8f1996 util: Add missing G_NO_INLINE annotation
There are two functions that are mocked, but are missing required
G_NO_INLINE attribute: virFirewallDIsRegistered() and
virHostCPUGetPhysAddrSize(). Add it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-04-28 14:35:22 +02:00
Michal Privoznik ac6519084c vsh: Turn _vshControl::progname into a const string
The aim of the progname member of the _vshControl struct is to
point to argv[0] which is then used in vshOutputLogFile() to
create a prefix for a log message. But the member is never
modified (nor it should be) and thus can be a const char *.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-04-14 12:00:55 +02:00
Michal Privoznik 9e89ef3f2f vsh: Free commands in vshDeinit()
Whether virsh/virt-admin is running in interactive or
non-interactive mode, vshControl::cmd contains the batch of last
executed commands as a linked list. Just look into
vshCommandParse(). Free the linked list in vshDeinit() to avoid
memleak.

  3,312 bytes in 3 blocks are still reachable in loss record 572 of 577
     at 0x484CEF3: calloc (vg_replace_malloc.c:1675)
     by 0x506AB29: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.8200.5)
     by 0x1B74B8: vshCmdNew (vsh.c:1466)
     by 0x1B7A80: vshCommandParse (vsh.c:1615)
     by 0x1B8458: vshCommandStringParse (vsh.c:1874)
     by 0x1419C1: virshParseArgv (virsh.c:773)
     by 0x141D11: main (virsh.c:879)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
2025-04-14 12:00:48 +02:00
Michal Privoznik ac5874ba87 network: Suppress reporting an error when D-Bus is unavailable in networkStateInitialize()
When the network driver initializes itself, it tries to subscribe
to signals from Firewalld sent over system D-Bus. Well, the code
is written in best effort mode, i.e. lack of D-Bus is not
considered an error. Problem is, virGDBusGetSystemBus() which is
used to obtain system D-Bus prints out an error in case of
lacking system D-Bus. This pollutes the logs (which may mislead
users) and goes against the best-effort nature of aforementioned
code. Check for the system D-Bus presence via
virGDBusHasSystemBus() first.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-04-10 13:22:43 +02:00
Michal Privoznik 4f502feebf virinhibitor: Suppress reporting an error when D-Bus is unavailable in virInhibitorAcquire()
At the beginning of virInhibitorAcquire() the system D-Bus
connection is obtained by calling virGDBusGetSystemBus(). If
there's no D-Bus available then an debug message is printed out
and function returns early. Problem is, in case of no D-Bus an
error message was reported by virGDBusGetSystemBus() and thus
logs were polluted which may mislead users.

Just check whether D-Bus is available first (by calling
virGDBusHasSystemBus()). If it is then virGDBusGetSystemBus()
should return a valid connection. Nevertheless, respect previous
logic and don't propagate error to the caller, just return 0.

Resolves: https://issues.redhat.com/browse/RHEL-79088
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-04-10 12:40:38 +02:00
Michal Privoznik 73d8cbaae5 meson: Drop workaround for -Wframe-larger-than and clang
After previous cleanups, all functions have their stack smaller
than 2048 bytes and thus the workaround is no longer needed.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
2025-04-07 08:43:23 +02:00
Michal Privoznik 01a098ebc7 vbox: Move parts of vboxSnapshotRedefine() into a separate function
There's too much happening inside of vboxSnapshotRedefine(). Not
only it makes the function hard to read, but it also increases
stack size of the function. Move one part into a separate
function: vboxSnapshotCreateFakeDiffStorage()

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
2025-04-07 08:43:19 +02:00
Michal Privoznik 61e1e61f81 vbox: Move parts of vboxSnapshotRedefine() into a separate function
There's too much happening inside of vboxSnapshotRedefine(). Not
only it makes the function hard to read, but it also increases
stack size of the function. Move one part into a separate
function: vboxSnapshotAddRWDisks()

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
2025-04-07 08:43:15 +02:00
Michal Privoznik cccdb33ced vbox: Move parts of vboxSnapshotRedefine() into a separate function
There's too much happening inside of vboxSnapshotRedefine(). Not
only it makes the function hard to read, but it also increases
stack size of the function. Move one part into a separate
function: vboxSnapshotAddDisksToMediaRegistry()

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
2025-04-07 08:43:11 +02:00
Michal Privoznik de3ea81270 vbox: Move parts of vboxSnapshotRedefine() into a separate function
There's too much happening inside of vboxSnapshotRedefine(). Not
only it makes the function hard to read, but it also increases
stack size of the function. Move one part into a separate
function: vboxSnapshotReplaceRWDisks()

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
2025-04-07 08:43:07 +02:00
Michal Privoznik f9c4f20d8f doRemoteOpen: Drop needless typecast of @transport
The @transport variable is already pass into the function with
proper type. There's no need to typecast it to its very same type
inside the function.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
2025-04-07 08:43:03 +02:00
Michal Privoznik 62ba268cd7 doRemoteOpen: Move RPC talk to a separate function
When opening a connection, the client does some RPC talk
(most notably REMOTE_PROC_CONNECT_OPEN, and in some cases
REMOTE_PROC_CONNECT_GET_URI even).

Now, calling RPC means that local variables must be created.
Having them in doRemoteOpen() increases its stack size which goes
against our effort in bringing the size down (see one of previous
commits).

Move that part of the code into a separate function.

This brings the stack size of doRemoteOpen() even further: from
1320 bytes to 1272.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
2025-04-07 08:42:54 +02:00
Michal Privoznik 063222801a remote_driver: Move URI arg extraction into a separate function
There's a problem with glib: what we might consider functions are
in fact macros and to make things worse - they do declare local
variables. For instance here's the declaration of
g_clear_pointer() macro:

#define g_clear_pointer(pp, destroy)                     \
  G_STMT_START                                           \
  {                                                      \
    G_STATIC_ASSERT (sizeof *(pp) == sizeof (gpointer)); \
    glib_typeof ((pp)) _pp = (pp);                       \
    glib_typeof (*(pp)) _ptr = *_pp;                     \
    *_pp = NULL;                                         \
    if (_ptr)                                            \
      (destroy) (_ptr);                                  \
  }                                                      \
  G_STMT_END                                             \

Now, as of v6.2.0-rc1~267 our VIR_FREE() macro is in fact a
redeclaration of g_clear_pointer(). Thus, calling VIR_FREE()
increases stack size!

Ideally, this wouldn't be a problem, because those variables
(_pp, _ptr) live in their own block. And clever compiler can just
reuse space created for one block.

But then there's clang where we are hitting this exact problem in
functions like doRemoteOpen() where either g_clear_pointer() is
called directly, or there are macros like EXTRACT_URI_ARG_STR()
which hide the call away.

That's why despite our previous efforts decreasing stack size we
still needed v9.8.0-rc1~208.

Well, moving URI argument extraction (those calls to
EXTRACT_URI_ARG_* macros) into a separate function helps us
decrease stack size from 2296 bytes to 1320.

Even after this there are still more possibilities for
improvements, but those will be addressed in future commits.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Roman Bogorodskiy <bogorodskiy@gmail.com>
2025-04-07 08:42:20 +02:00
Michal Privoznik 008ccd3518 ch: Fix printf format strings wrt size_t argument
In a few places, when a size_t typed argument is passed to a
printf-like function the corresponding specifier is %ld instead
of %zu. Fix those places.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-04-04 15:30:26 +02:00
Michal Privoznik b065df3d04 ch: Drop pid from monitor
The domain object already has a member that allows storing
hypervisor's PID (vm->pid). There's no need to duplicate it in
_virCHMonitor struct. Switch CH code to use the former.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-04-04 15:30:23 +02:00
Michal Privoznik 3dae81c8d7 ch: Use CH_DOMAIN_PRIVATE() more
There are two instances where vm->privateData is typecasted only
so that it can be dereferenced further. Well, that's exactly what
CH_DOMAIN_PRIVATE() macro is for. Use that instead.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-04-04 15:30:13 +02:00
Michal Privoznik 0123456789 NEWS: Document features/improvements/bug fixes I've participated in
There are some features/improvements/bug fixes I've either
contributed or reviewed/merged. Document them for upcoming
release.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-03-31 09:06:24 +02:00
Michal Privoznik 50981052a5 qemu: Emit NIC_MAC_CHANGE event
So far, we only process NIC_RX_FILTER_CHANGED event when the
corresponding device has 'trustGuestRxFilters' enabled. And the
event is emitted only for virtio model. IOW, this is fairly
limited situation and other scenarios don't emit any event (e.g.
change of MAC address on a PCI passthrough device).

Resolves: https://issues.redhat.com/browse/RHEL-7035
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-03-25 11:49:30 +01:00
Michal Privoznik 057872df2d Introduce NIC_MAC_CHANGE event
The aim off this event is to notify management application that
guest changed MAC address on one of its vNICs so the app can
update its internal records, e.g. for finding match between
guest/host view of vNICs.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-03-25 11:49:30 +01:00
Michal Privoznik ac95617d3d qemu: Reflect MAC address change in live domain XML
If a guest changes MAC address on its vNIC, then QEMU emits
NIC_RX_FILTER_CHANGED event (the event is emitted in other cases
too, but that's not important right now). Now, domain XML allows
users to chose whether to trust these events or not:

  <interface trustGuestRxFilters='yes|no'/>

For the 'no' case no action is performed and the event is
ignored. But for the 'yes' case, some host side features of
corresponding vNIC (well tap/macvtap device) are tweaked to
reflect changed MAC address. But what is missing is reflecting
this new MAC address in domain XML.

Basically, what happens is: the host sees traffic with new MAC
address, all tools inside the guest see the new MAC address
(including 'virsh domifaddr --source agent') which makes it
harder to match device in the guest with the one in the domain
XML.

Therefore, report this new MAC address as another attribute of
the <mac/> element:

  <mac address="52:54:00:a4:6f:91" currentAddress="00:11:22:33:44:55"/>

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-03-25 11:49:30 +01:00
Michal Privoznik eb6c28408d ch: Rework virCHProcessConnectMonitor()
Firstly, let's switch from explicit virCHDriverGetConfig() +
virObjectUnref() combo to g_autoptr(virCHDriverConfig). This
leaves us with the @monitor variable which is initialized to NULL
only to be then set to the retval of virCHMonitorNew() and
returned instantly. Well, the variable is now useless and can be
dropped.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-03-13 15:51:15 +01:00
Michal Privoznik 5ed2ed8708 ch: Unref @cfg in virCHProcessStop()
At the beginning of virCHProcessStop() the ref to driver config
is obtained (via virCHDriverGetConfig()), but corresponding unref
call is lacking. Use g_autoptr() to make sure the config is
unrefed always.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-03-13 15:51:15 +01:00
Michal Privoznik b9a10cf4bb ch: Free @iothreads array in virCHProcessSetupIOThreads()
When the CH driver starts a domain virCHProcessSetupIOThreads()
is called eventually which in turn calls
virCHMonitorGetIOThreads(). The latter returns an array of
iothreads which is never freed leading to a memleak:

130 (104 direct, 26 indirect) bytes in 1 blocks are definitely lost in loss record 1,804 of 1,998
   at 0x484CEF3: calloc (vg_replace_malloc.c:1675)
   by 0x4F0E7A9: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.8000.5)
   by 0xB3A9359: virCHMonitorGetIOThreads (ch_monitor.c:1183)
   by 0xB3AA5BB: virCHProcessSetupIOThreads (ch_process.c:348)
   by 0xB3AAC59: virCHProcessSetup (ch_process.c:480)
   by 0xB3AC75A: virCHProcessStart (ch_process.c:973)
   by 0xB39B7D4: chDomainCreateXML (ch_driver.c:246)
   by 0x4CC9D32: virDomainCreateXML (libvirt-domain.c:188)
   by 0x168F91: remoteDispatchDomainCreateXML (remote_daemon_dispatch_stubs.h:5186)
   by 0x168F18: remoteDispatchDomainCreateXMLHelper (remote_daemon_dispatch_stubs.h:5167)
   by 0x4B20066: virNetServerProgramDispatchCall (virnetserverprogram.c:423)
   by 0x4B1FB99: virNetServerProgramDispatch (virnetserverprogram.c:299)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-03-13 15:51:15 +01:00
Michal Privoznik 1b25f1e53b ch: Don't leak virCHDomainObjPrivate struct members
There are some members of the virCHDomainObjPrivate struct that
are allocated at various stages of domain lifecycle but then are
never freed:

1) cgroup - allocated in virDomainCgroupSetupCgroup()
2) autoCpuset - this one is actually never allocated (and thus is
                always NULL, but soon it may be used. Just free
                it for now, which is a NOP anyways.
3) autoNodeset - same story as 2).

There are two more members, which shouldn't be freed:

1) driver - this is just a raw pointer to the CH driver (see
   virCHDomainObjPrivateAlloc()).

2) monitor - this member is cleared in virCHProcessStop(), way
             before control even gets to
             virCHDomainObjPrivateFree().

452 (400 direct, 52 indirect) bytes in 1 blocks are definitely lost in loss record 1,944 of 1,998
   at 0x484CEF3: calloc (vg_replace_malloc.c:1675)
   by 0x4F0E7A9: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.8000.5)
   by 0x49479CE: virCgroupNewFromParent (vircgroup.c:893)
   by 0x49481BA: virCgroupNewDomainPartition (vircgroup.c:1068)
   by 0x494915E: virCgroupNewMachineManual (vircgroup.c:1378)
   by 0x49492FE: virCgroupNewMachine (vircgroup.c:1432)
   by 0x4B5E3DE: virDomainCgroupInitCgroup (domain_cgroup.c:377)
   by 0x4B5E9CD: virDomainCgroupSetupCgroup (domain_cgroup.c:524)
   by 0xB3AC693: virCHProcessStart (ch_process.c:951)
   by 0xB39B7D4: chDomainCreateXML (ch_driver.c:246)
   by 0x4CC9D32: virDomainCreateXML (libvirt-domain.c:188)
   by 0x168F91: remoteDispatchDomainCreateXML (remote_daemon_dispatch_stubs.h:5186)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-03-13 15:51:15 +01:00
Michal Privoznik 9da8db464a ch: Free retval of curl_slist_append()
There are two places where curl_slist_append() is called but
corresponding call to curl_slist_free_all() is missing:
virCHMonitorPutNoContent() and virCHMonitorGet() which leads to
memleaks:

41 (16 direct, 25 indirect) bytes in 1 blocks are definitely lost in loss record 992 of 1,998
   at 0x4845888: malloc (vg_replace_malloc.c:446)
   by 0x5B2F8FE: curl_slist_append (in /usr/lib64/libcurl.so.4.8.0)
   by 0xB3A7B41: virCHMonitorPutNoContent (ch_monitor.c:824)
   by 0xB3A89FF: virCHMonitorBootVM (ch_monitor.c:1030)
   by 0xB3AC6F1: virCHProcessStart (ch_process.c:967)
   by 0xB39B7D4: chDomainCreateXML (ch_driver.c:246)
   by 0x4CC9D32: virDomainCreateXML (libvirt-domain.c:188)
   by 0x168F91: remoteDispatchDomainCreateXML (remote_daemon_dispatch_stubs.h:5186)
   by 0x168F18: remoteDispatchDomainCreateXMLHelper (remote_daemon_dispatch_stubs.h:5167)
   by 0x4B20066: virNetServerProgramDispatchCall (virnetserverprogram.c:423)
   by 0x4B1FB99: virNetServerProgramDispatch (virnetserverprogram.c:299)
   by 0x4B28B5E: virNetServerProcessMsg (virnetserver.c:135)

88 (16 direct, 72 indirect) bytes in 1 blocks are definitely lost in loss record 1,501 of 1,998
   at 0x4845888: malloc (vg_replace_malloc.c:446)
   by 0x5B2F8FE: curl_slist_append (in /usr/lib64/libcurl.so.4.8.0)
   by 0xB3A7E41: virCHMonitorGet (ch_monitor.c:864)
   by 0xB3A92E2: virCHMonitorGetInfo (ch_monitor.c:1157)
   by 0xB3A9CEA: virCHProcessUpdateInfo (ch_process.c:142)
   by 0xB3AAD36: virCHProcessSetup (ch_process.c:492)
   by 0xB3AC75A: virCHProcessStart (ch_process.c:973)
   by 0xB39B7D4: chDomainCreateXML (ch_driver.c:246)
   by 0x4CC9D32: virDomainCreateXML (libvirt-domain.c:188)
   by 0x168F91: remoteDispatchDomainCreateXML (remote_daemon_dispatch_stubs.h:5186)
   by 0x168F18: remoteDispatchDomainCreateXMLHelper (remote_daemon_dispatch_stubs.h:5167)
   by 0x4B20066: virNetServerProgramDispatchCall (virnetserverprogram.c:423)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-03-13 15:51:15 +01:00
Michal Privoznik 8701ba4feb network: Free inhibitor in networkStateCleanup()
The shutdown inhibitor is created in networkStateInitialize() but
corresponding call to virInhibitorFree() is missing in
networkStateCleanup() leading to a memleak:

116 (72 direct, 44 indirect) bytes in 1 blocks are definitely lost in loss record 1,769 of 1,998
   at 0x484CEF3: calloc (vg_replace_malloc.c:1675)
   by 0x4F0E7A9: g_malloc0 (in /usr/lib64/libglib-2.0.so.0.8000.5)
   by 0x4993B9B: virInhibitorNew (virinhibitor.c:152)
   by 0x5279394: networkStateInitialize (bridge_driver.c:654)
   by 0x4CC74DC: virStateInitialize (libvirt.c:665)
   by 0x15B719: daemonRunStateInit (remote_daemon.c:613)
   by 0x49F2B44: virThreadHelper (virthread.c:256)
   by 0x5356662: start_thread (in /usr/lib64/libc.so.6)
   by 0x53D7DA3: clone (in /usr/lib64/libc.so.6)

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-03-13 15:51:15 +01:00
Michal Privoznik fc47a37a7a security: Don't stop restoring labels too early
The point of virSecurityManagerRestoreAllLabel() function is to
restore ALL labels and be tolerant to possible errors, i.e.
continue restoring seclabels and NOT return early.

Well, in two implementations of this internal API this type of
problem was found:

1) virSecurityDACRestoreAllLabel() returned early if
   virSecurityDACRestoreGraphicsLabel() failed, or when
   def->sec->sectype equals to an impossible value.

2) virSecuritySELinuxRestoreAllLabel() returned early if
   virSecuritySELinuxRestoreMemoryLabel() failed.

Fix all three places.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2025-03-11 15:05:41 +01:00
Michal Privoznik 9d1e4b25ba security: Set seclabels on UEFI shim
Again, trivial. Just copy what is done for kernel and initrd.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2025-03-10 13:54:59 +01:00
Michal Privoznik 39c1784ca0 qemu_command: Generate cmd line for UEFI shim
Trivial.

Resolves: https://issues.redhat.com/browse/RHEL-68043
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2025-03-10 13:54:42 +01:00
Michal Privoznik b136e492c5 qemu_validate: Check whether UEFI shim is supported
If UEFI shim is specified in domain XML but QEMU is too old, then
report an error.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2025-03-10 13:53:06 +01:00
Michal Privoznik 30be3b0d9d qemu_capabilities: Introduce QEMU_CAPS_MACHINE_SHIM
In its commit v9.2.0-323-ga5bd044b15 QEMU introduced another
command line option: -shim. It's used to load kernel. Track
presence of it via QEMU_CAPS_MACHINE_SHIM.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2025-03-10 13:51:42 +01:00
Michal Privoznik 6b63334233 conf: Introduce os/shim element
For secure boot environments where <loader/> is signed, it may be
unfeasible to keep the binary up to date (esp. when revoking
certificates contained within). To address that, QEMU introduced
'-shim' cmd line option which side loads another UEFI binary
which can then contain new certification authorities or list of
revocations. Expose it as <shim/> element that's nested under
<os/>, just like kernel and initrd are.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2025-03-10 13:32:46 +01:00
Michal Privoznik e5299ddf86 meson: Generate runstatedir according to newer standard
While previously FHS 2.3 defined /var/run as a place to store
runtime information [1] it's no longer 2004 and newer
specification was released which favors /run [2]. Since it was
released 10 years ago, maybe it's time we start honouring it.

On majority of Linux systems (if not all), /var/run is a symlink
to /run anyways.

Users can still pass old location via -Drunstatedir.

1: https://refspecs.linuxfoundation.org/FHS_2.3/fhs-2.3.html#VARRUNRUNTIMEVARIABLEDATA
2: https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s15.html

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2025-03-04 08:36:21 +01:00
Michal Privoznik d99d3e1232 NEWS: Document features/improvements/bug fixes I've participated in
There are some features/improvements/bug fixes I've either
contributed or reviewed/merged. Document them for upcoming
release.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-02-27 15:54:54 +01:00
Michal Privoznik 291186daa3 apparmor: Allow SGX if configured
If SGX memory model is configured for domain then we need to
allow QEMU access some additional files:

  1) /dev/sgx_vepc needs to be RW
  2) /dev/sgx_provision needs to be RO

We already do this in SELinux driver but not in AppArmor.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/751

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2025-02-25 12:48:24 +01:00
Michal Privoznik 715bfc5e54 remote_daemon: Silence DBus errors
When a daemon (like libvirtd, virtqemud, etc.) is started as an
unprivileged user (which is exactly how KubeVirt does it), then
it tries to register on both session and system DBus-es so that
it can shut itself down (e.g. when system is powering off or user
logs out). It's worth noting that this is just opportunistic and
if no DBus is available then no error is reported.

Or at least that's what we thought. Because the way our
virGDBusGetSessionBus() and virGDBusGetSystemBus() are written an
error is actually reported every time the daemon starts.

Use virGDBusHasSessionBus() and virGDBusHasSystemBus() to check
if corresponding bus is available.

Resolves: https://issues.redhat.com/browse/RHEL-79088
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2025-02-13 15:20:34 +01:00
Michal Privoznik 0428c69b09 virgdbus: Introduce virGDBusHasSessionBus()
This is just like virGDBusHasSystemBus() except it checks for the
session bus instead of the system one.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2025-02-13 15:20:34 +01:00
Michal Privoznik 14af443139 tests: qemuxmlconfdata: Update launch-security-sev-snp.xml
Recently, I was part of a discussion where it was suspected that
libvirt does not pick up correct FW for SEV-SNP guests. Update
our test to demonstrate it does.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-02-06 11:31:42 +01:00
Michal Privoznik 22e90a3b17 NEWS: Document virtio-mem-ccw
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
2025-02-04 09:15:45 +01:00
Michal Privoznik f23f8ff91a qemuxmlconftest: Introduce memory-hotplug-virtio-mem-ccw-s390x.xml
This is similar to emuxmlconfdata/memory-hotplug-virtio-mem-pci-s390x.xml
except the explicit placement of virtio-mem onto a PCI bus is removed.
This results in virtio-mem being placed onto CCW "bus" this demonstrating
previous commits working as expected.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
2025-02-04 09:15:45 +01:00