Commit Graph
100 Commits
Author SHA1 Message Date
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
Michal Privoznik ee0320a7fc qemu: Allow virtio-mem on CCW
After previous commits, we can allow virtio-mem to live on CCW
channel.

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 541dfe40bc qemu: Validate virtio-mem-ccw
There are basically two differences between virtio-mem-ccw and
virtio-mem-pci. s390 doesn't allow mixing different page sizes
and there's no NUMA support in QEMU.

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 a46e33a925 qemu_caps: Introduce QEMU_CAPS_DEVICE_VIRTIO_MEM_CCW
This capability tracks whether QEMU supports virtio-mem-ccw
device. Introduced in QEMU commit v9.2.0-492-gaa910c20ec only
upcoming release of QEMU supports the device.

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 621373d8a8 qemuxmlconftest: Introduce memory-hotplug-virtio-mem-pci-s390x.xml
As of v9.2.0-1413-gd77ae821e8 QEMU supports virtio-mem-pci on
s390 too. Let's add a test case for that.

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 89d56c41ac qemu_command: Use qemuBuildVirtioDevProps() to build cmd line for virtio-mem and virtio-pmem
Both, virtio-mem and virtio-pmem devices follow traditional QEMU
naming convention: their suffix determines what bus they live on.
For instance, virtio-mem-pci, virtio-mem-ccw, virtio-pmem-pci.
We already have a function that constructs device name following
this convention: qemuBuildVirtioDevGetConfigDev().

While there's no virtio-pmem-ccw device yet, the function can
still be used.

Another advantage of using the function is - it'll be easier in
future when we want to configure various virtio aspects of memory
devices (like ats, iommu_platform, etc.).

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 a8ed747b9a qemu: Do NOT autoadd NUMA node for s390
In some cases, we might automatically add a NUMA node. But this
doesn't work for s390 really, because in its commit
v2.12.0-rc0~41^2~6 QEMU forbade specifying NUMA nodes for s390.
Suppress automatic adding of NUMA node on our side.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
2025-02-04 09:15:45 +01:00
Michal Privoznik ff77c2d596 NEWS: Document VBOX-6.1 removal
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-01-31 10:54:13 +01:00
Michal Privoznik da9a804f4e vbox: Drop code supporting old VBox version
Now that only supported version of VirtualBox is 7.0.x the code
that supports older versions can be dropped.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-01-31 10:54:09 +01:00
Michal Privoznik 335bceb115 vbox: Drop support for VirtualBox-6.1.x
According to VirtualBox download page [1] the support for version
6.1.x was terminated a year ago. Drop support for it.

1: https://www.virtualbox.org/wiki/Download_Old_Builds_6_1

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-01-31 10:54:06 +01:00
Michal Privoznik 5ca7f27f75 vbox: Report an error when VBox CAPI initialization fails
If initialization of VBOX fails inside of _pfnInitialize an
negative value is returned to signal an error condition to a
caller but no error message is printed out. Reporting an error
may shed more light into why VBOX failed to initialize.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-01-31 10:54:03 +01:00
Michal Privoznik 10320ad526 vbox: Use g_autofree in tryLoadOne()
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-01-31 10:53:47 +01:00
Michal Privoznik 4819a14fec ch: Include unistd.h in ch_events.c
There's a call to read() in the file but corresponding include of
unistd.h is missing causing a build failure.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2025-01-27 17:35:53 +01:00
Michal Privoznik ab10c0695d tools: ssh-proxy: Check for domain status before parsing its CID
Inactive domain XML can be wildly different to the live XML. For
instance, it can have VSOCK CID of that from another (running)
domain. Since domain status is not checked for, attempting to ssh
into an inactive domain may in fact result in opening a
connection to a different live domain that listens on said CID
currently.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/737
Resolves: https://issues.redhat.com/browse/RHEL-75577

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2025-01-21 13:58:04 +01:00
Michal Privoznik 4933dfcce0 qemuxmlconftest: Drop s390-default-cpu-...ccw-virtio-2.7 test cases
In its upstream commit [1], qemu dropped s390-2.7 machine type,
then in commit [2] the s390-2.8 machine type was dropped. But as
Thomas Huth pointed out, any machine type that's older than 6
years is subject to removal [3]. This means, any machine type
older than 4.1 is going to be removed eventually.

We have two test cases that assumes existence of 2.7 machine type.
While they could be switched to 4.1 machine type, we also have
another test case that already check 4.2 machine type.
Therefore, just drop the 2.7 ones.

1: https://gitlab.com/qemu-project/qemu/-/commit/3199c7ee76089fb6844f6b2bed1f5d3d99a7527c
2: https://gitlab.com/qemu-project/qemu/-/commit/66924fe36977d9d9e45ba3e0b6e851ee170507f6
3: https://gitlab.com/qemu-project/qemu/-/commit/ce80c4fa6ff0f5c379bba7db74d04593e9fb12f2
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
2025-01-20 15:18:43 +01:00
Michal Privoznik 1942a88813 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: Ján Tomko <jtomko@redhat.com>
2025-01-14 16:00:49 +01:00
Michal Privoznik 32140bdb09 meson: Replace meson.source_root() with meson.project_source_root()
The source_root() method is deprecated in 0.56.0 and we're
recommended to use project_source_root() instead.

This is similar to commit v8.9.0-rc1~70 but somehow, the old
method sneaked in.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2025-01-13 12:33:23 +01:00
Michal Privoznik 18b8e6d3cc hyperv: Introduce and export 'facility' variable.
In its upstream commit [1] openwsman dropped 'facility' variable
which is documented as:

 * all processes that use the libu must define a "facility" variable somewhere
 * to satisfy this external linkage reference.
 *
 * Such variable will be used as the syslog(3) facility argument.

Well, prior to that commit, openwsman itself declared the
variable (and set it to LOG_DAEMON). Now it's up to us.

Yeah, the variable naming is terrible and also I we are not using
libu directly, but apparently libwsman.so requires it anyway:

  $ objdump -T /usr/lib64/libwsman.so | grep facility
  0000000000000000      D  *UND*  0000000000000000  Base        facility

1: https://github.com/Openwsman/openwsman/commit/d72c51f21b9c85a773b7955ac587d2d3cea982c1
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2025-01-06 14:21:18 +01:00
Michal Privoznik 9636ac40a3 qemu_capabilities: Avoid memleak in virQEMUCapsProbeFullDeprecatedProperties()
As one of its arguments, the
virQEMUCapsProbeFullDeprecatedProperties() gets a pointer to
GStrv (a string list), which it may eventually replace. It's
single caller (virQEMUCapsProbeQMPHostCPU()) passes a string list
indeed. Now, when replacing one string list with another plain
g_free() is not enough as we need to free individual strings too.

==13573== 34 bytes in 8 blocks are definitely lost in loss record 271 of 576
==13573==    at 0x4844878: malloc (vg_replace_malloc.c:446)
==13573==    by 0x51789D1: g_malloc (in /usr/lib64/libglib-2.0.so.0.7800.6)
==13573==    by 0x5193E82: g_strdup (in /usr/lib64/libglib-2.0.so.0.7800.6)
==13573==    by 0x4997F73: g_strdup_inline (gstrfuncs.h:321)
==13573==    by 0x4997F73: virJSONValueArrayToStringList (virjson.c:1296)
==13573==    by 0x5027CF7: qemuMonitorJSONParseCPUModelExpansion (qemu_monitor_json.c:5139)
==13573==    by 0x50281C9: qemuMonitorJSONGetCPUModelExpansion (qemu_monitor_json.c:5245)
==13573==    by 0x501044F: qemuMonitorGetCPUModelExpansion (qemu_monitor.c:3261)
==13573==    by 0x4F190D0: virQEMUCapsProbeQMPHostCPU (qemu_capabilities.c:3227)
==13573==    by 0x4F2145E: virQEMUCapsInitQMPMonitor (qemu_capabilities.c:5758)
==13573==    by 0x10FFF8: testQemuCaps (qemucapabilitiestest.c:111)
==13573==    by 0x110B53: virTestRun (testutils.c:143)
==13573==    by 0x11063E: doCapsTest (qemucapabilitiestest.c:200)

Fixes: 51c098347d
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
2024-12-19 09:14:53 +01:00
Michal Privoznik 0162f2008e qemu: Enable I/O APIC even more frequently
In my previous commit v10.10.0-48-g2d222ecf6e I've made us enable
I/O APIC when there is an IOMMU with EIM. This works well. What
does not work is case when there's just an IOMMU without EIM but
with 256+ vCPUS. Problem is that post parsing happens in two
stages: general domain post parse (where
qemuDomainDefEnableDefaultFeatures() is called) and then per
device post parse (where qemuDomainIOMMUDefPostParse() is
called). Now, in aforementioned case it is the device post parse
phase where EIM is enabled but the code that would enable
VIR_DOMAIN_FEATURE_IOAPIC has already run.

To resolve this, make the domain post parse callback "foresee"
the future enabling of EIM so that it can turn on I/O APIC
beforehand.

Resolves: https://issues.redhat.com/browse/RHEL-65844
Fixes: 2d222ecf6e
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2024-12-18 15:27:12 +01:00
Michal Privoznik 2d222ecf6e qemu: Enable I/O APIC if needed
This is a follow up of my previous commits. If the number of
vCPUs exceeds some arbitrary value (255) then QEMU requires IOMMU
with EIM and intremap enabled. But in turn, intremap IOMMU
requires split I/O APIC (per virDomainDefIOMMUValidate()). Since
after my previous commits (e.g. v10.10.0-rc1~183) IOMMU is added
automagically, the I/O APIC can be also enabled automagically.

Relates to: https://issues.redhat.com/browse/RHEL-65844
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-12-16 15:43:16 +01:00
Michal Privoznik 6cc93bf288 qemu: Grab a QUERY job when formatting domain XML
It may happen that, for instance after daemon restart, that one
thread is still in qemuProcessReconnect(), i.e. filling in
runtime information by talking to QEMU on monitor. If another
thread then tries to format domain XML (which is currently
guarded by plain mutex on virDomainObj) it'll produce incomplete
and misleading information (e.g. current size of virtio-mem).
This happens because the reconnecting thread talks to QEMU on
monitor and thus unlocks the domain object frequently allowing
the XML formatting thread to acquire the mutex meanwhile.

Resolves: https://issues.redhat.com/browse/RHEL-71042
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-12-12 14:46:25 +01:00
Michal Privoznik 304b93dbb5 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>
2024-11-28 12:18:52 +01:00
Michal Privoznik c4d6bd3bf5 qemu: Validate QoS values in qemuDomainSetInterfaceParameters()
This is similar to one of my previous commits (v10.7.0-rc1~22)
which introduced a check that <bandwidth/> values fit into
certain limits. My original commit validated values when parsing
<bandwidth/> XML, but completely missed the case when values are
set over virDomainSetInterfaceParameters() API.

Solution is simple - just perform validation after bandwidth
structure is reconstructed from arguments passed to the API.

Resolves: https://issues.redhat.com/browse/RHEL-65372
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2024-11-27 15:11:13 +01:00
Michal Privoznik 24580d13d1 qemu: Move PostParse functions out of qemu_domain.c
Problem with qemu_domain.c is that it's constantly growing. But
there are few options for improvement. For instance, validation
functions were moved out and now live in qemu_validate.c. We can
do the same for PostParse functions, though since PostParse may
modify domain definition, some functions need to be exported from
qemu_domain.c.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-11-13 13:13:54 +01:00
Michal Privoznik aeebb30ba2 Drop unused function declarations
When moving function and/or renaming them sometimes corresponding
change to corresponding header file is not done. This leaves us
with functions that are declared in header files, but nowhere
implemented. Drop such declarations.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-11-12 15:35:53 +01:00
Michal Privoznik 6c50d11276 virnetserverclient.h: Fix typo in comment of virNetServerClientPrivPreExecRestart()
The function the comment is referring to is
virNetServerClientPrivNew() not virNetServerClintPrivNew(). The
latter doesn't even exist.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-11-12 15:35:53 +01:00
Michal Privoznik d88ebd4374 ch_monitor: Report OS error when removing socket fails
When removing a socket in virCHMonitorClose() fails, a warning is
printed. But it doesn't contain errno nor g_strerror() which may
shed more light into why removing of the socket failed.

Oh, and since virCHMonitorClose() is registered as autoptr
cleanup for virCHMonitor() it may happen that virCHMonitorClose()
is called with mon->socketpath allocated but file not existing
yet (see virCHMonitorNew()). Thus ignore ENOENT and do not print
warning in that case - the file doesn't exist anyways.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-11-12 09:11:47 +01:00
Michal Privoznik f1f4cbb50a ch_monitor: Avoid possible double free in virCHMonitorClose()
The virCHMonitorClose() is meant to be called when monitor to
cloud-hypervisor process closes. It removes the socket and frees
string containing path to the socket.

In general, there is a problem with the following pattern:

  if (var) {
      do_something();
      g_free(var);
  }

because if the pattern executes twice the variable is freed
twice. That's why we have VIR_FREE() macro. Well, replace plain
g_free() with g_clear_pointer(). Mind you, this is NOT a
destructor where clearing pointers is needless.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-11-12 09:11:36 +01:00
Michal Privoznik a3b8753db9 virnetdevopenvswitch: Warn on unsupported QoS settings
Let me preface this with stating the obvious: documentation on
QoS in OVS is very sparse. This is all based on my observation
and OVS codebase analysis.

For the following QoS setting:

  <bandwidth>
    <inbound average="512" peak="1024" burst="32"/>
  </bandwidth>

the following QoS setting is generated into OVS (NB, our XML
values are in KiB/s, OVS has them in bits/s):

  # ovs-vsctl list qos
  _uuid               : a087226b-2da6-4575-ad4c-bf570cb812a9
  external_ids        : {ifname=vnet1, vm-id="7714e6b5-4885-4140-bc59-2f77cc99b3b5"}
  other_config        : {burst="262144", max-rate="8192000", min-rate="4096000"}
  queues              : {0=655bf3a7-e530-4516-9caf-ec9555dfbd4c}
  type                : linux-htb

from which the following topology is generated:

  # for i in qdisc class; do tc -s -d -g $i show dev vnet1; done
  qdisc htb 1: root refcnt 2 r2q 10 default 0x1 direct_packets_stat 0 ver 3.17 direct_qlen 1000
   Sent 2186 bytes 16 pkt (dropped 0, overlimits 0 requeues 0)
   backlog 0b 0p requeues 0

  +---(1:fffe) htb rate 8192Kbit ceil 8192Kbit linklayer ethernet burst 1499b/1mpu 60b cburst 1499b/1mpu 60b level 7
       |       Sent 2186 bytes 16 pkt (dropped 0, overlimits 0 requeues 0)
       |       backlog 0b 0p requeues 0
       |
       +---(1:1) htb prio 0 quantum 51200 rate 4096Kbit ceil 8192Kbit linklayer ethernet burst 32Kb/1mpu 60b cburst 32Kb/1mpu 60b level 0
                 Sent 2186 bytes 16 pkt (dropped 0, overlimits 0 requeues 0)
                 backlog 0b 0p requeues 0

Long story short, the default class (1:) for an OVS interface has
average and peak set exactly as requested. But since it's nested
under another class (1:fffe), it can borrow unused bandwidth. And
the parent is set to have rate = ceil = peak from our XML. From
[1]: htb_tc_install() calls htb_parse_qdisc_details__() which
sets: 'hc->min_rate = hc->max_rate;' and then calls
htb_setup_class_(..., tc_make_handle(1, 0xfffe), tc_make_handle(1, 0), &hc);
to set up the top parent class.

In other words - the interface is set up to so that it can always
consume 'peak' bandwidth and there is no way for us to set it up
differently. It's too late to deny setting 'peak' different to
'average' at XML validation phase so do the next best thing -
throw a warning, just like we do in case <bandwidth/> is set for
an unsupported <interface/> type.

1: https://github.com/openvswitch/ovs/blob/main/lib/netdev-linux.c#L5039
Resolves: https://issues.redhat.com/browse/RHEL-53963
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-11-08 10:41:02 +01:00
Michal Privoznik 844d1036eb qemu_domain: Automagically add IOMMU if needed
If a Q35 domain has huge number of vCPUS (over 255, currently), then
it needs IOMMU with Extended Interrupt Mode enabled (see check in
qemuValidateDomainVCpuTopology()).

Well, we already add some devices and to other tricks when
parsing new domain XML. Might as well add IOMMU device if above
condition is met.

Resolves: https://issues.redhat.com/browse/RHEL-65844
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-11-07 10:46:33 +01:00
Michal Privoznik b15047ff26 qemu: Turn EIM IOMMU on automagically
If a Q35 domain has huge number of vCPUS (over 255, currently), then
it needs IOMMU with Extended Interrupt Mode enabled (see check in
qemuValidateDomainVCpuTopology()).

Well, we already add some devices and to other tricks when
parsing new domain XML. Might as well turn the EIM on for IOMMU
device.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-11-07 10:46:33 +01:00
Michal Privoznik a9797d7c43 libvirt_private.syms: Export virDomainIOMMUDefNew()
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
2024-11-07 10:46:32 +01:00
Michal Privoznik 99acc29557 NEWS: Fix naming of DISK_DETECT_ZEROES migration parameter
There's a typo in NEWS.rst where
VIR_MIGRATE_PARAM_MIGRATE_DISKS_DETECT_ZEROES has the _ZEROES
suffix duplicated referring to a non-existent migration
parameter. Drop the suffix.

Fixes: 2e29ab3269
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2024-10-17 16:50:12 +02:00
Michal Privoznik 6126f743b1 qemu: Provide sane default for dump_guest_core
QEMU uses Linux extensions to madvise() to include/exclude guest
memory from core dump. These are obviously not available
everywhere. Currently, users have two options:

  1) configure <memory dumpCore=''/> in domain XML, or
  2) configure dump_guest_core in qemu.conf

While these work, they may harm user experience as "things just
don't work" out of the box. Provide sane default in
virQEMUDriverConfigNew() so neither of two options is required.

To have predictable results in tests, explicitly set
cfg->dumpGuestCore to false in qemuTestDriverInit() (which
creates cfg object for tests).

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

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-09-25 08:38:09 +02:00
Michal Privoznik 18b61cb4f9 qemu.conf.in: Fix dumpCore capitalization
In qemu.conf.in we give examples of enabling/disabling core
dumps in domain XML. But the attribute is spelled wrong.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-09-25 08:38:09 +02:00
Michal Privoznik 1c76827270 meson: Sort values reported in summary()
So far the only sorted summary() is list of detected libraries.
Other sections like hypervisor, storage, security drivers and
misc are in random order. Sort them alphabetically.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2024-09-24 09:59:00 +02:00
Michal Privoznik 794d49e3cf meson: Restore alphabetical order of reported libraries
One of previous commits introduced json-c library and reports it
in the summary at the end. However, we like the list to be sorted
alphabetically which is not the case.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
2024-09-24 09:58:49 +02:00
Michal Privoznik ebc4580a5f Revert "vircommand: Parse /dev/fd on *BSD-like systems when looking for opened FDs"
Unfortunately, devfs on FreeBSD (accessible via /dev/fd) exposes
only those FDs which can be represented as a file. To cite
manpage [1]:

  The files /dev/fd/0 through /dev/fd/# refer to file descriptors
  which can be accessed through the file system.

This means FDs representing pipes and/or unnamed sockets are not
visible by default. To expose all FDs a slightly different
filesystem must be mounted [2]:

  mount -t fdescfs none /dev/fd

Apparently, on my test machine fdescfs is mounted by default and
thus I haven't seen any problem. Only after aforementioned patch
was merged our CI started reporting problems. While we could try
to figure out whether correct FS is mounted, it's a needless
micro optimization. Just revert the code to the state it was
before I touched it.

1: https://man.freebsd.org/cgi/man.cgi?query=fd&sektion=4&manpath=freebsd-release-ports
2: https://man.freebsd.org/cgi/man.cgi?query=fdescfs&sektion=5&n=1

This reverts commit 308ec0fb2c.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-09-16 12:05:19 +02:00
Michal Privoznik 308ec0fb2c vircommand: Parse /dev/fd on *BSD-like systems when looking for opened FDs
On BSD-like systems "/dev/fd" serves the same purpose as
"/proc/self/fd". And since procfs is usually not mounted, on such
systems we can use "/dev/fd" instead.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/518
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-09-13 14:50:43 +02:00
Michal Privoznik 4df8dc576f vircommand: Make sysconf(_SC_OPEN_MAX) failure non-fatal
The point of calling sysconf(_SC_OPEN_MAX) is to allocate big
enough bitmap so that subsequent call to
virCommandMassCloseGetFDsDir() can just set the bit instead of
expanding memory (this code runs in a forked off child and thus
using async-signal-unsafe functions like malloc() is a bit
tricky).

But on some systems the limit for opened FDs is virtually
non-existent (typically macOS Ventura started reporting EINVAL).

But with both glibc and musl using malloc() after fork() is safe.
And with sufficiently new glib too, as it's using malloc() with
newer releases instead of their own allocator.

Therefore, pick a sufficiently large value (glibc falls back to
256, [1], Darwin to 10240 [2] so 10240 should be good enough) to
fall back to and make the error non-fatal.

1: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/unix/sysv/linux/getdtsz.c;h=4c5a6208067d2f9eaaac6dba652702fb4af9b7e3;hb=HEAD
2  https://github.com/apple/darwin-xnu/blob/main/bsd/sys/syslimits.h#L104

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-09-13 14:50:43 +02:00
Michal Privoznik 6ded014ba3 vircommand: Isolate FD dir parsing into a separate function
So far, virCommandMassCloseGetFDsLinux() opens "/proc/self/fd",
iterates over it marking opened FDs in @fds bitmap. Well, we can
do the same on other systems (with altered path), like MacOS or
FreeBSD. Therefore, isolate dir iteration into a separate
function that accepts dir path as an argument.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-09-13 14:50:43 +02:00
Michal Privoznik dfe496ae33 vircommand: Drop unused arguments from virCommandMassCloseGetFDs*()
Both virCommandMassCloseGetFDsLinux() and
virCommandMassCloseGetFDsGeneric() take @cmd argument only to
mark it as unused. Drop it from both.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
2024-09-13 14:50:43 +02:00
Michal Privoznik 2feeefc0b4 cpu_map: Install SierraForest description file
In one of recent commits new CPU model was introduced. But
corresponding change in meson.build is missing which results in
the XML file not being installed.

Fixes: 3afbb1644c
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2024-09-09 09:30:04 +02:00
Michal Privoznik 4d8ebbfee8 virschematest: Replace g_lstat() with virFileIsLink()
Inside of virschematest.c there's testSchemaDir() which iterates
over dentries in given directory but skips some files: those
without ".xml" suffix, hidden files, symlinks, etc.

Now, symlinks are detected as g_lstat() + S_ISLNK() combo which
works, except it fails to compile on mingw where is no concept of
symlinks. Replace the combo with a call to virFileIsLink() which
at least allows us to compile cleanly on mingw.

Fixes: f997fcca71
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2024-08-28 08:46:16 +02:00
Michal Privoznik 0888784f38 qemu: Use virEventThreadStop() in qemuProcessStop()
Currently, qemuProcessStop() unlocks given domain object right in
the middle of cleanup process. This is dangerous because there
might be another thread which is executing virDomainObjListAdd().
And since the domain object is on the list of domain objects AND
by the time qemuProcessStop() unlocks it the object is also
marked as inactive, the other thread acquires the lock and
switches vm->def pointer.

The unlocking of domain object is needed though, to allow even
processing thread finish its queue. Well, the processing can be
done before any cleanup is attempted.

Therefore, use freshly introduced virEventThreadStop() to join
the event thread and drop lock/unlock from the middle of
qemuProcessStop().

Now, there's a comment being removed that mentions
qemuDomainObjStopWorker() and why it has to be called only after
the domain is marked as dead. This comment is no longed
applicable because call to qemuDomainObjStopWorker() is removed
also. Moreover, priv->beingDestroyed is set to true before
unlocking the domain object, thus any event processing callback
is going to see the domain being destroyed and can chose to
either exit early or finish processing event.

Fixes: 3865410e7f
Resolves: https://issues.redhat.com/browse/RHEL-49607
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2024-08-22 13:33:09 +02:00
Michal Privoznik 7aca235d8d vireventthread: Introduce virEventThreadStop
The aim is to move parts of vir_event_thread_finalize() that MAY
block into a separate function, so that unrefing the a
virEventThread no longer blocks (or require releasing and
subsequent re-acquiring of a mutex).

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2024-08-22 13:33:06 +02:00
Michal Privoznik 85e07fb1ce security: apparmor: Allow QEMU read /proc/sys/vm/max_map_count
In its commit v9.0.0-rc0~1^2 QEMU started to read
/proc/sys/vm/max_map_count file to set up coroutine limits better
(something about VMAs, mmap(), see the commit for more info).
Allow the file in apparmor profile.

Resolves: https://gitlab.com/libvirt/libvirt/-/issues/660
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2024-08-20 14:44:04 +02:00
Michal Privoznik a70cdeeb2a conf: Validate QoS values
Since we use 'tc' to set QoS, or we instruct OVS which then uses
'tc', we have to make sure values are within range acceptable to
'tc'.

Resolves: https://issues.redhat.com/browse/RHEL-45200
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2024-08-20 09:19:28 +02:00
Michal Privoznik ab489ea318 conf: Introduce virNetDevBandwidthValidate()
This function validates whether parsed limits are within range as
defined by 'tc' sources (since we use tc to set QoS; or OVS which
then uses tc too). The 'tc' program stores speeds in 64bit
integers (unit is bytes per second) and sizes in uints (unit is
bytes). We use different units: kilobytes per second and
kibibytes and therefore we can parse values larger than 'tc' can
handle and thus need a function to check if values still fit.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2024-08-20 09:19:25 +02:00
Michal Privoznik f644cba8ae virsh: Simplify vshTableRowAppend() calling in cmdList(), part two
Instead of having many if-else statements, each with its own
vshTableRowAppend() call, we can use a simple trick - have an
array of string pointers, set array members in the if bodies and
then call vshTableRowAppend() once.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2024-08-20 09:08:35 +02:00
Michal Privoznik cf0e0715e0 virsh: Simplify vshTableRowAppend() calling in cmdList(), part one
All calls to vshTableRowAppend() inside of cmdList() share couple
of same arguments: domain ID, domain name and domain state. While
the first one is stored in a variable and then passed to all
vshTableRowAppend() calls, the others are passed as a function
call. Switch the latter to variables too.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2024-08-20 08:58:47 +02:00
Michal Privoznik ab7f877f27 lib: Use NULLSTR family of macros more
There is a family of convenient macros: NULLSTR, NULLSTR_EMPTY,
NULLSTR_STAR, NULLSTR_MINUS which hides ternary operator.

Generated using the following spatch (and its obvious variants):

  @@
  expression s;
  @@
    <+...
  - s ? s : "<null>"
  + NULLSTR(s)
    ...+>

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
2024-08-19 13:44:12 +02:00
Michal Privoznik 1b797e6421 virnetlibsshsession: Reflect API change in libssh
As of libssh commit of libssh-0.11.0~70 [1] the
ssh_channel_get_exit_status() function is deprecated and a new
one is introduced instead: ssh_channel_get_exit_state().
It's not a drop-in replacement, but it's simple enough.
Adapt our libssh handling code to this change.

1: https://git.libssh.org/projects/libssh.git/commit/?id=04d86aeeae73c78af8b3dcdabb2e588cd31a8923

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
2024-08-12 15:47:48 +02:00
Michal Privoznik 18fd4899f3 vsh: Allow vshReadlineInit() to be called multiple times
Thing about vshReadlineInit() is - it's called multiple times.
The first time from vshInit(), when @ctl was filled only
partially (most notably, before any argv parsing is done, hence
ctl->imode is set to false). The second time after argv parsing,
from virshInit() -> vshInitReload(). In here, ctl->imode might
have changed and thus vshReadlineInit() can't exit early - it
needs to set up stuff for interactive mode (history basically).

To allow vshReadlineInit() to be called again,
vshReadlineDeinit() must set @autoCompleteOpaque to NULL.

Fixes: cab1e71f01
Resolves: https://issues.redhat.com/browse/RHEL-53560
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2024-08-08 15:45:37 +02:00
Michal Privoznik ac0b669c56 security: Allow RW access to pstore device
The whole point of pstore device is that the guest writes crash
dumps into it. But the way SELinux label is set on the
corresponding file warrants RO access only. This is due to a
copy-paste from code around: kernel/initrd/DTB/SLIC - these are
RO indeed, but pstore MUST be writable too. In a sense it's
closer to NVRAM/disks - hence set imagelabel on it.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2024-07-31 14:15:59 +02:00
Michal Privoznik d913f204e0 qemu: Pre-create pstore device file
So far we are relying on QEMU or sysadmin to create the file for
pstore. This is suboptimal as in the case of the former we can
not set proper seclabels (there's nothing to set seclabels on
until QEMU is started).

Therefore, make sure the file is created before launching QEMU
and that it has the correct size.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2024-07-31 14:15:48 +02:00
Michal Privoznik aec390df81 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: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Boris Fiuczynski <fiuczy@linux.ibm.com>
2024-07-30 17:42:24 +02:00
Michal Privoznik de355b7873 qemu: Autofill pstore path if missing
Introduced only a couple of commits ago (in
v10.5.0-84-g90e50e67c6) the pstore device acts as a nonvolatile
storage, where guest kernel can store information about crashes.
This device, however, expects a file in the host from which the
crash data is read. So far, we expected users to provide a path,
but we can autogenerate one if missing. Just put it next to
per-domain's NVRAM stores.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Andrea Bolognani <abologna@redhat.com>
2024-07-30 17:22:00 +02:00
Michal Privoznik bd11c753f3 virsysinfo: Calculate OEM string index better
As can be seen in earlier commits, there can be two OEM strings
with the same index. But since our parser
(virSysinfoParseOEMStrings()) doesn't expect that, it increments
index in each run and thus skips over these strings.
Fortunately, we have the right index at hand - we're just
skipping over it in a loop. Just reconstruct the index back
inside the loop.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2024-07-25 16:51:17 +02:00
Michal Privoznik 5bb4540dbb virsysinfo: Be more forgiving when decoding OEM strings
On some systems, there are two or even more 'OEM Strings'
sections in DMI table. Here's an example of dmidecode output on
such system:

  # dmidecode -q -t 11
  OEM Strings
          String 1: Default string

  OEM Strings
          String 1: ThunderX2 System
          String 2: cavium.com
          String 3: Comanche

Now, this poses a problem, because when one tries to obtain
individual strings, they get:

  # dmidecode -q --oem-string 1
  Default string
  ThunderX2 System

  # dmidecode -q --oem-string 2
  No OEM string number 2
  cavium.com

NB, the "No OEM string number 2" is printed onto stderr and
everything else onto stdout. Oh, and trying to get OEM strings
from just one section doesn't fly:

  # dmidecode -q -H 0x1d --oem-string 2
  Options --string, --type, --handle and --dump-bin are mutually exclusive

This means two things:

1) we have no way of distinguishing OEM strings at the same index
   but in different sections,

2) because of how virSysinfoDMIDecodeOEMString() is written, we
   fail in querying OEM string that exists in one section but not
   in the others (for instance string #2 from example above).

While there's not much we can do about 1), there is something
that can be done about 2) - refine the error condition and make
the function return an error iff there's nothing on stdout and
there's something on stderr.

Resolves: https://issues.redhat.com/browse/RHEL-45952
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2024-07-25 16:50:47 +02:00
Michal Privoznik 98a9dc532d tests: Add HPE Apollo test case to sysinfotest
Introduce a test case for sysinfotest. The data was obtained by
running dmidecode as libvirt would run it:

   dmidecode -q -t 0,1,2,3,4,11,17

Now, the expected output fits almost perfectly, except for OEM
strings where the third string looks nothing like in the
dmidecode output. This is because of testDMIDecodeDryRun() which
overwrites the third OEM string (see v6.5.0-rc1~214 for more
info). But that's okay for now.

Speaking of OEM strings, it's worth noticing two 'OEM Strings'
sections in the dmidecode output. This is causing some troubles
and will be fixed in next commit.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2024-07-25 16:49:45 +02:00
Michal Privoznik 185065b645 virsysinfo: Trim newline when decoding OEM strings
dmidecode always puts a newline character at the end of each
OEM string it prints. It's the dmi_oem_strings() function [1] that
iterates over strings and calls pr_attr() over each one which
puts "\n" at the end, unconditionally [2[.

Since it's not part of the string though, trim it.

1: https://git.savannah.nongnu.org/cgit/dmidecode.git/tree/dmidecode.c#n2431
2: https://git.savannah.nongnu.org/cgit/dmidecode.git/tree/dmioutput.c#n63

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2024-07-25 16:49:27 +02:00
Michal Privoznik b103200bf3 vircommand: Initialize dryRunStatus to portable EXIT_SUCCESS instead of 0
If dry run of a command was requested (virCommandSetDryRun())
then a specified callback is called instead of running actual
command. This is meant to be used in tests. To mimic running the
command as closely as possible the callback can also set exit
status of the command it's implementing. To save some lines
though, the exit status is initialized to 0 so that callback has
to set it only on failures. Now, 0 is not exactly portable value
- that's why stdlib.h has EXIT_SUCCESS (and EXIT_FAILURE) values.
Initialize the exit status (held in dryRunStatus) to EXIT_SUCCESS
then.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
2024-07-25 16:47:55 +02:00