The way we format <cpu/> element for capabilities is not ideal,
because if there are no CPUs, i.e. no child elements, we still
output opening and closing element. To solve this,
virXMLFormatElement() could be used but that would introduce more
variables into the loop. Therefore, move the formatter into a
separate function and use virXMLFormatElement().
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
In a few places it may happen that the array we want to sort is
still NULL (e.g. because there were no leases found, no paths for
secdriver to lock or no cache banks). However, passing NULL to
qsort() is undefined and even though glibc plays nicely we
shouldn't rely on undefined behaviour.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Tim Wiederhake <twiederh@redhat.com>
In one of my recent commits I've done some renaming. But whilst
doing so I also mistakenly replaced 'goto cleanup' with 'return
-1' in virCapabilitiesHostNUMAInitReal() which was incorrect.
Fixes: fe25224fdaa53bbeceed3ddeef1b3a150665e656
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Martin Kletzander <mkletzan@redhat.com>
After previous patches we have two structures:
virCapsHostNUMACellDistance and virNumaDistance which express the
same thing. And have the exact same members (modulo their names).
Drop the former in favor of the latter.
This change means that distances with value of 0 are no longer
printed out into capabilities XML, because domain XML code allows
partial distance specification and thus threats value of 0 as
unspecified by user (see virDomainNumaGetNodeDistance() which
returns the default LOCAL/REMOTE distance for value of 0).
Also, from ACPI 6.1 specification, section 5.2.17 System Locality
Distance Information Table (SLIT):
Distance values of 0-9 are reserved and have no meaning.
Thus we shouldn't be ever reporting 0 in neither domain nor
capabilities XML.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
The virCapsHostNUMACellSiblingInfo structure really represents
distance to other NUMA node. Rename the structure and variables
of that type to make it more obvious.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Some variables are needed only inside for() loop. They were
declared at the beginning of the function because of VIR_FREE()
calls, but since they are auto-freed they can be declared inside
the loop.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
What this function really does it takes ownership of all pointers
passed (well, except for the first one - caps - to which it
registers new NUMA node). But since all info is passed as a
single pointer it's hard to tell (and use g_auto*). Let's use
double pointers to make the ownership transfer obvious.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
The @cpus variable is an array of structs in which each item
contains a virBitmap member. As such it is not enough to just
VIR_FREE() the array - each bitmap has to be freed too.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
The rest of virCapabilities format functions take virBuffer as
the first argument and struct to format as the second. Also, they
accept NULL (as the second argument). Fix
virCapabilitiesHostNUMAFormat() so that it follows this logic.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Historically, we declared pointer type to our types:
typedef struct _virXXX virXXX;
typedef virXXX *virXXXPtr;
But usefulness of such declaration is questionable, at best.
Unfortunately, we can't drop every such declaration - we have to
carry some over, because they are part of public API (e.g.
virDomainPtr). But for internal types - we can do drop them and
use what every other C project uses 'virXXX *'.
This change was generated by a very ugly shell script that
generated sed script which was then called over each file in the
repository. For the shell script refer to the cover letter:
https://listman.redhat.com/archives/libvir-list/2021-March/msg00537.html
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
Generated by the following spatch:
@@
expression a, b;
@@
+ b = g_steal_pointer(&a);
- b = a;
... when != a
- a = NULL;
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Erik Skultety <eskultet@redhat.com>
Via coccinelle (not the handbag!)
spatches used:
@ rule1 @
identifier a, b;
symbol NULL;
@@
- b = a;
... when != a
- a = NULL;
+ b = g_steal_pointer(&a);
@@
- *b = a;
... when != a
- a = NULL;
+ *b = g_steal_pointer(&a);
Signed-off-by: Kristina Hanicova <khanicov@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Previous patches have converted VIR_FREE to g_free in functions with
names ending in Free() and Dispose(), but there are a few similar
functions with names that don't fit that pattern, but server the same
purpose (and thus can survive the same conversion). in particular
*Free*(), and *Unref().
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
QEMU has the ability to mark machine types as deprecated. This should be
exposed to management applications in the capabilities.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This patch takes on one set of examples of unnecessary use of
VIR_FREE() when g_free() is adequate - it modifies only vir*Free()
functions within the conf directory that take a single pointer and
free the object pointed to by that argument before returning. The
modification is to replace VIR_FREE() with g_free() for the object
itself *and* for all subordinate chunks of memory pointed to by that
object.
(NB: there are other functions that VIR_FREE subordinate memory of
objects that end up being freed before return (also sometimes with
VIR_FREE); I am purposefully ignoring those to reduce scope and focus
on a sub class where the pointlessness is obvious.)
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This use of DIR* was re-using the same function-scope DIR* each time
through a for loop, and due to multiple error gotos in the loop, it
needed to have the scope of the DIR* reduced to just the loop at the
same time as switching to g_autoptr. That's what this patch does.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
In all uses of VIR_DIR_CLOSE() except one, the DIR* is never
referenced after closing all the way until it goes out of
scope. virCapabilitiesInitCaches(), however, reuses the same DIR* over
and over in a loop, but due to having many error conditions that
result in a goto out of the loop, it's not well suited to reducing the
scope of the variable until we introduce a g_autoptr cleanup function
for DIR*.
In preparation for doing just that, we need to get rid of the side
effect of VIR_DIR_CLOSE() setting the DIR* to NULL, so in this one
case, let's manually set the DIR* to NULL. Then in an upcoming patch
we can safely remove the side effect from VIR_DIR_CLOSE().
This extra/ugly bit of code is only temporary: once we introduce the
g_autoptr cleanup function for DIR*, we will remove this manual
close/clear completely anyway.
Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
There are only 3 places using the function. Two can use virBitmapNewCopy
directly. In case of the qemu capabilities code we need to free the old
bitmap first.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Include virutil.h in all files that use it,
instead of relying on it being pulled in somehow.
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
We don't need all the platforms gnulib deals with, so
this is a cut down version of GNULIB's physmem.c
code. This also allows us to integrate libvirt's
error reporting functions closer to the error cause.
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Update the host CPU code to report the die_id in the NUMA topology
capabilities. On systems with multiple dies, this fixes the bug
where CPU cores can't be distinguished:
<cpus num='12'>
<cpu id='0' socket_id='0' core_id='0' siblings='0'/>
<cpu id='1' socket_id='0' core_id='1' siblings='1'/>
<cpu id='2' socket_id='0' core_id='0' siblings='2'/>
<cpu id='3' socket_id='0' core_id='1' siblings='3'/>
</cpus>
Notice how core_id is repeated within the scope of the same socket_id.
It now reports
<cpus num='12'>
<cpu id='0' socket_id='0' die_id='0' core_id='0' siblings='0'/>
<cpu id='1' socket_id='0' die_id='0' core_id='1' siblings='1'/>
<cpu id='2' socket_id='0' die_id='1' core_id='0' siblings='2'/>
<cpu id='3' socket_id='0' die_id='1' core_id='1' siblings='3'/>
</cpus>
So core_id is now unique within a (socket_id, die_id) pair.
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
As pointed out by Ján Tomko, "no_memory seems suspicious in the times of
abort()".
As libvirt decided to take the path to not report OOM and simply abort
when it happens, let's get rid of the no_memory labels and simplify the
code around them.
Reviewed-by: Cole Robinson <crobinso@redhat.com>
Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
If the host OS doesn't have NUMA present, we fallback to
populating fake NUMA info and the code thus assumes only a
single NUMA node.
Unfortunately we also fallback to fake NUMA if numactl-devel
was not present, and in this case we can still have multiple
NUMA nodes. In this case we create all CPUs, but only the
CPUs in the first node have any data filled in, resulting in
capabilities like:
<topology>
<cells num='1'>
<cell id='0'>
<memory unit='KiB'>15977572</memory>
<cpus num='48'>
<cpu id='0' socket_id='0' core_id='0' siblings='0'/>
<cpu id='1' socket_id='0' core_id='0' siblings='1'/>
<cpu id='2' socket_id='0' core_id='1' siblings='2'/>
<cpu id='3' socket_id='0' core_id='1' siblings='3'/>
<cpu id='4' socket_id='0' core_id='2' siblings='4'/>
<cpu id='5' socket_id='0' core_id='2' siblings='5'/>
<cpu id='6' socket_id='0' core_id='3' siblings='6'/>
<cpu id='7' socket_id='0' core_id='3' siblings='7'/>
<cpu id='8' socket_id='0' core_id='4' siblings='8'/>
<cpu id='9' socket_id='0' core_id='4' siblings='9'/>
<cpu id='10' socket_id='0' core_id='5' siblings='10'/>
<cpu id='11' socket_id='0' core_id='5' siblings='11'/>
<cpu id='0'/>
<cpu id='0'/>
<cpu id='0'/>
<cpu id='0'/>
<cpu id='0'/>
<cpu id='0'/>
<cpu id='0'/>
<cpu id='0'/>
<cpu id='0'/>
<cpu id='0'/>
<cpu id='0'/>
</cpus>
</cell>
</cells>
</topology>
With this new code we get something slightly less broken
<topology>
<cells num='4'>
<cell id='0'>
<memory unit='KiB'>15977572</memory>
<cpus num='12'>
<cpu id='0' socket_id='0' core_id='0' siblings='0-1'/>
<cpu id='1' socket_id='0' core_id='0' siblings='0-1'/>
<cpu id='2' socket_id='0' core_id='1' siblings='2-3'/>
<cpu id='3' socket_id='0' core_id='1' siblings='2-3'/>
<cpu id='4' socket_id='0' core_id='2' siblings='4-5'/>
<cpu id='5' socket_id='0' core_id='2' siblings='4-5'/>
<cpu id='6' socket_id='0' core_id='3' siblings='6-7'/>
<cpu id='7' socket_id='0' core_id='3' siblings='6-7'/>
<cpu id='8' socket_id='0' core_id='4' siblings='8-9'/>
<cpu id='9' socket_id='0' core_id='4' siblings='8-9'/>
<cpu id='10' socket_id='0' core_id='5' siblings='10-11'/>
<cpu id='11' socket_id='0' core_id='5' siblings='10-11'/>
</cpus>
</cell>
<cell id='0'>
<memory unit='KiB'>15977572</memory>
<cpus num='12'>
<cpu id='12' socket_id='0' core_id='0' siblings='12-13'/>
<cpu id='13' socket_id='0' core_id='0' siblings='12-13'/>
<cpu id='14' socket_id='0' core_id='1' siblings='14-15'/>
<cpu id='15' socket_id='0' core_id='1' siblings='14-15'/>
<cpu id='16' socket_id='0' core_id='2' siblings='16-17'/>
<cpu id='17' socket_id='0' core_id='2' siblings='16-17'/>
<cpu id='18' socket_id='0' core_id='3' siblings='18-19'/>
<cpu id='19' socket_id='0' core_id='3' siblings='18-19'/>
<cpu id='20' socket_id='0' core_id='4' siblings='20-21'/>
<cpu id='21' socket_id='0' core_id='4' siblings='20-21'/>
<cpu id='22' socket_id='0' core_id='5' siblings='22-23'/>
<cpu id='23' socket_id='0' core_id='5' siblings='22-23'/>
</cpus>
</cell>
</cells>
</topology>
The topology at least now reflects what 'virsh nodeinfo' reports.
The main bug is that the CPU "id" values won't match what the Linux
host actually uses.
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
The 'caps' object is already allocated when the fake NUMA
initialization takes place.
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Fortunately, this is not causing any problems now because glib
does this check for us when calling this function via attribute
cleanup. But in a future commit we will explicitly call this
function over a struct member that might be NULL.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
We learned that the hardware features of CAT, CMT, MBA and MBM
are orthogonal ones, if CAT or MBA is not supported in system,
but CMT or MBM are supported, then the cache monitor or
memoryBW monitor features may not be correctly displayed in
host capabilities through command 'virsh capabilites'.
Showing the cache/memoryBW monitor capabilities even there is
no support of cache allocation or memoryBW allocation features.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Huaqiang <huaqiang.wang@intel.com>
The NUMA cells are stored directly in the virCapsHostPtr
struct. This moves them into their own struct allowing
them to be stored independantly of the rest of the host
capabilities. The change is used as an excuse to switch
the representation to use a GPtrArray too.
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
The XML parser currently calls virCapabilitiesDomainDataLookup during
parsing to find the domain capabilities matching the triple
(virt type, os type, arch)
This is, however, bogus with the QEMU driver as it assumes that there
is an emulator known to the default driver capabilities that matches
this triple. It is entirely possible for the driver to be parsing an
XML file with a custom emulator path specified pointing to a binary
that doesn't exist in the default driver capabilities. This will,
for example be the case on a RHEL host which only installs the host
native emulator to /usr/bin. The user can have built a custom QEMU
for non-native arches into $HOME and wish to use that.
Aside from validation, this call is also used to fill in a machine type
for the guest if not otherwise specified. Again, this data may be
incorrect for the QEMU driver because it is not taking account of
the emulator binary that is referenced.
To start fixing this, move the validation to the post-parse callbacks
where more intelligent driver specific logic can be applied.
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Use the new helper to initialize child XML element buffers.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Remove the need to pass around strings and switch to the enum values
instead.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
The capabilities are declared in the XML schema so passing feature names
as strings from hypervisor drivers makes no sense.
Additionally some of the features expose so called 'toggles' while
others not. This knowledge was encoded by a bunch of 'STREQ's in the
formatter.
Change all of this by declaring the features as an enum and use it
instead of a dynamically allocated array.
Presence of 'toggles' is encoded together with the conversion strings
rather than in the formatter directly.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Use virXMLFormatElement and the automatic memory handlers to simplfy the
code.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Use automatic memory freeing and use virXMLFormatElement instead of open
coding it.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
The function now does not return an error so we can drop it fully.
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
Replace all occurrences of
if (VIR_STRDUP(a, b) < 0)
/* effectively dead code */
with:
a = g_strdup(b);
Signed-off-by: Ján Tomko <jtomko@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>