mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 05:17:59 +03:00
caps: Add virCapabilitiesDomainDataLookup
This is a helper function to look up all capabilities data for all the OS bits that are relevant to <domain>. This is - os type - arch - domain type - emulator - machine type This will be used to replace several functions in later commits.
This commit is contained in:
parent
4fa6f9b413
commit
a693652341
@ -225,7 +225,6 @@ virCapabilitiesDispose(void *object)
|
||||
virCPUDefFree(caps->host.cpu);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* virCapabilitiesAddHostFeature:
|
||||
* @caps: capabilities to extend
|
||||
@ -568,6 +567,168 @@ virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool
|
||||
virCapsDomainDataCompare(virCapsGuestPtr guest,
|
||||
virCapsGuestDomainPtr domain,
|
||||
virCapsGuestMachinePtr machine,
|
||||
int ostype,
|
||||
virArch arch,
|
||||
int domaintype,
|
||||
const char *emulator,
|
||||
const char *machinetype)
|
||||
{
|
||||
const char *check_emulator = NULL;
|
||||
|
||||
if (ostype != -1 && guest->ostype != ostype)
|
||||
return false;
|
||||
if ((arch != VIR_ARCH_NONE) && (guest->arch.id != arch))
|
||||
return false;
|
||||
|
||||
if (domaintype != -1 && (!domain || domain->type != domaintype))
|
||||
return false;
|
||||
|
||||
if (emulator) {
|
||||
if (domain)
|
||||
check_emulator = domain->info.emulator;
|
||||
if (!check_emulator)
|
||||
check_emulator = guest->arch.defaultInfo.emulator;
|
||||
if (STRNEQ_NULLABLE(check_emulator, emulator))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (machinetype) {
|
||||
if (!machine)
|
||||
return false;
|
||||
if (STRNEQ(machine->name, machinetype) &&
|
||||
(STRNEQ_NULLABLE(machine->canonical, machinetype)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* virCapabilitiesDomainDataLookup:
|
||||
* @caps: capabilities to query
|
||||
* @ostype: guest operating system type, of enum VIR_DOMAIN_OSTYPE
|
||||
* @arch: Architecture to search for
|
||||
* @domaintype: domain type to search for, of enum VIR_DOMAIN_VIRT
|
||||
* @emulator: Emulator path to search for
|
||||
* @machinetype: Machine type to search for
|
||||
*
|
||||
* Search capabilities for the passed values, and if found return
|
||||
* virCapabilitiesDomainDataLookup filled in with the default values
|
||||
*/
|
||||
virCapsDomainDataPtr
|
||||
virCapabilitiesDomainDataLookup(virCapsPtr caps,
|
||||
int ostype,
|
||||
virArch arch,
|
||||
int domaintype,
|
||||
const char *emulator,
|
||||
const char *machinetype)
|
||||
{
|
||||
virCapsGuestPtr foundguest = NULL;
|
||||
virCapsGuestDomainPtr founddomain = NULL;
|
||||
virCapsGuestMachinePtr foundmachine = NULL;
|
||||
virCapsDomainDataPtr ret = NULL;
|
||||
size_t i, j, k;
|
||||
|
||||
for (i = 0; i < caps->nguests; i++) {
|
||||
virCapsGuestPtr guest = caps->guests[i];
|
||||
|
||||
for (j = 0; j < guest->arch.ndomains; j++) {
|
||||
virCapsGuestDomainPtr domain = guest->arch.domains[j];
|
||||
virCapsGuestMachinePtr *machinelist;
|
||||
int nmachines;
|
||||
|
||||
if (domain->info.nmachines) {
|
||||
nmachines = domain->info.nmachines;
|
||||
machinelist = domain->info.machines;
|
||||
} else {
|
||||
nmachines = guest->arch.defaultInfo.nmachines;
|
||||
machinelist = guest->arch.defaultInfo.machines;
|
||||
}
|
||||
|
||||
for (k = 0; k < nmachines; k++) {
|
||||
virCapsGuestMachinePtr machine = machinelist[k];
|
||||
if (!virCapsDomainDataCompare(guest, domain, machine,
|
||||
ostype, arch, domaintype,
|
||||
emulator, machinetype))
|
||||
continue;
|
||||
|
||||
foundmachine = machine;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!foundmachine) {
|
||||
if (!virCapsDomainDataCompare(guest, domain, NULL,
|
||||
ostype, arch, domaintype,
|
||||
emulator, machinetype))
|
||||
continue;
|
||||
}
|
||||
|
||||
founddomain = domain;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!founddomain) {
|
||||
if (!virCapsDomainDataCompare(guest, NULL, NULL,
|
||||
ostype, arch, domaintype,
|
||||
emulator, machinetype))
|
||||
continue;
|
||||
}
|
||||
|
||||
foundguest = guest;
|
||||
break;
|
||||
}
|
||||
|
||||
/* XXX check default_emulator, see how it uses this */
|
||||
if (!foundguest) {
|
||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
if (ostype)
|
||||
virBufferAsprintf(&buf, "ostype=%s ",
|
||||
virDomainOSTypeToString(ostype));
|
||||
if (arch)
|
||||
virBufferAsprintf(&buf, "arch=%s ", virArchToString(arch));
|
||||
if (domaintype)
|
||||
virBufferAsprintf(&buf, "domaintype=%s ",
|
||||
virDomainVirtTypeToString(domaintype));
|
||||
if (emulator)
|
||||
virBufferAsprintf(&buf, "emulator=%s ", emulator);
|
||||
if (machinetype)
|
||||
virBufferAsprintf(&buf, "machine=%s ", machinetype);
|
||||
if (virBufferCurrentContent(&buf) &&
|
||||
!virBufferCurrentContent(&buf)[0])
|
||||
virBufferAsprintf(&buf, "%s", _("any configuration"));
|
||||
if (virBufferCheckError(&buf) < 0) {
|
||||
virBufferContentAndReset(&buf);
|
||||
goto error;
|
||||
}
|
||||
|
||||
virReportError(VIR_ERR_INVALID_ARG,
|
||||
_("could not find capabilities for %s"),
|
||||
virBufferContentAndReset(&buf));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC(ret) < 0)
|
||||
goto error;
|
||||
|
||||
ret->ostype = foundguest->ostype;
|
||||
ret->arch = foundguest->arch.id;
|
||||
if (founddomain) {
|
||||
ret->domaintype = founddomain->type;
|
||||
ret->emulator = founddomain->info.emulator;
|
||||
}
|
||||
if (!ret->emulator)
|
||||
ret->emulator = foundguest->arch.defaultInfo.emulator;
|
||||
if (foundmachine)
|
||||
ret->machinetype = foundmachine->name;
|
||||
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* virCapabilitiesSupportsGuestArch:
|
||||
* @caps: capabilities to query
|
||||
|
@ -192,6 +192,16 @@ struct _virCaps {
|
||||
virCapsGuestPtr *guests;
|
||||
};
|
||||
|
||||
typedef struct _virCapsDomainData virCapsDomainData;
|
||||
typedef virCapsDomainData *virCapsDomainDataPtr;
|
||||
struct _virCapsDomainData {
|
||||
int ostype;
|
||||
int arch;
|
||||
int domaintype;
|
||||
const char *emulator;
|
||||
const char *machinetype;
|
||||
};
|
||||
|
||||
|
||||
extern virCapsPtr
|
||||
virCapabilitiesNew(virArch hostarch,
|
||||
@ -262,6 +272,14 @@ virCapabilitiesHostSecModelAddBaseLabel(virCapsHostSecModelPtr secmodel,
|
||||
const char *type,
|
||||
const char *label);
|
||||
|
||||
virCapsDomainDataPtr
|
||||
virCapabilitiesDomainDataLookup(virCapsPtr caps,
|
||||
int ostype,
|
||||
virArch arch,
|
||||
int domaintype,
|
||||
const char *emulator,
|
||||
const char *machinetype);
|
||||
|
||||
extern int
|
||||
virCapabilitiesSupportsGuestArch(virCapsPtr caps,
|
||||
virArch arch);
|
||||
|
@ -54,6 +54,7 @@ virCapabilitiesClearHostNUMACellCPUTopology;
|
||||
virCapabilitiesDefaultGuestArch;
|
||||
virCapabilitiesDefaultGuestEmulator;
|
||||
virCapabilitiesDefaultGuestMachine;
|
||||
virCapabilitiesDomainDataLookup;
|
||||
virCapabilitiesFormatXML;
|
||||
virCapabilitiesFreeMachines;
|
||||
virCapabilitiesFreeNUMAInfo;
|
||||
|
@ -877,8 +877,12 @@ virkmodtest_SOURCES = \
|
||||
virkmodtest_LDADD = $(LDADDS)
|
||||
|
||||
vircapstest_SOURCES = \
|
||||
vircapstest.c testutils.h testutils.c
|
||||
vircapstest_LDADD = $(LDADDS)
|
||||
vircapstest.c testutils.h testutils.c \
|
||||
testutilsqemu.c testutilsqemu.h \
|
||||
testutilslxc.c testutilslxc.h \
|
||||
testutilsxen.c testutilsxen.h \
|
||||
$(NULL)
|
||||
vircapstest_LDADD = $(qemu_LDADDS) $(LDADDS)
|
||||
|
||||
vircaps2xmltest_SOURCES = \
|
||||
vircaps2xmltest.c testutils.h testutils.c
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "testutils.h"
|
||||
#include "testutilslxc.h"
|
||||
#include "testutilsxen.h"
|
||||
#include "testutilsqemu.h"
|
||||
#include "capabilities.h"
|
||||
#include "virbitmap.h"
|
||||
|
||||
@ -66,8 +69,8 @@ buildNUMATopology(int seq)
|
||||
if (virCapabilitiesAddHostNUMACell(caps, cell_id + seq,
|
||||
MAX_MEM_IN_CELL,
|
||||
MAX_CPUS_IN_CELL, cell_cpus,
|
||||
0, NULL,
|
||||
0, NULL) < 0)
|
||||
VIR_ARCH_NONE, NULL,
|
||||
VIR_ARCH_NONE, NULL) < 0)
|
||||
goto error;
|
||||
|
||||
cell_cpus = NULL;
|
||||
@ -101,7 +104,7 @@ test_virCapabilitiesGetCpusForNodemask(const void *data ATTRIBUTE_UNUSED)
|
||||
if (!(caps = buildNUMATopology(3)))
|
||||
goto error;
|
||||
|
||||
if (virBitmapParse(nodestr, 0, &nodemask, mask_size) < 0)
|
||||
if (virBitmapParse(nodestr, VIR_ARCH_NONE, &nodemask, mask_size) < 0)
|
||||
goto error;
|
||||
|
||||
if (!(cpumap = virCapabilitiesGetCpusForNodemask(caps, nodemask)))
|
||||
@ -118,6 +121,197 @@ test_virCapabilitiesGetCpusForNodemask(const void *data ATTRIBUTE_UNUSED)
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
doCapsExpectFailure(virCapsPtr caps,
|
||||
int ostype,
|
||||
virArch arch,
|
||||
int domaintype,
|
||||
const char *emulator,
|
||||
const char *machinetype)
|
||||
{
|
||||
virCapsDomainDataPtr data = virCapabilitiesDomainDataLookup(caps, ostype,
|
||||
arch, domaintype, emulator, machinetype);
|
||||
|
||||
if (data) {
|
||||
VIR_FREE(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
doCapsCompare(virCapsPtr caps,
|
||||
int ostype,
|
||||
virArch arch,
|
||||
int domaintype,
|
||||
const char *emulator,
|
||||
const char *machinetype,
|
||||
int expect_ostype,
|
||||
virArch expect_arch,
|
||||
int expect_domaintype,
|
||||
const char *expect_emulator,
|
||||
const char *expect_machinetype)
|
||||
{
|
||||
bool ret = false;
|
||||
virCapsDomainDataPtr data = virCapabilitiesDomainDataLookup(caps, ostype,
|
||||
arch, domaintype, emulator, machinetype);
|
||||
|
||||
if (!data)
|
||||
goto error;
|
||||
|
||||
if (data->ostype != expect_ostype) {
|
||||
fprintf(stderr, "data->ostype=%s doesn't match expect_ostype=%s\n",
|
||||
virDomainOSTypeToString(data->ostype),
|
||||
virDomainOSTypeToString(expect_ostype));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (data->arch != expect_arch) {
|
||||
fprintf(stderr, "data->arch=%s doesn't match expect_arch=%s\n",
|
||||
virArchToString(data->arch),
|
||||
virArchToString(expect_arch));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (data->domaintype != expect_domaintype) {
|
||||
fprintf(stderr, "data->domaintype=%s doesn't match "
|
||||
"expect_domaintype=%s\n",
|
||||
virDomainVirtTypeToString(data->domaintype),
|
||||
virDomainVirtTypeToString(expect_domaintype));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (STRNEQ(data->emulator, expect_emulator)) {
|
||||
fprintf(stderr, "data->emulator=%s doesn't match expect_emulator=%s\n",
|
||||
data->emulator, expect_emulator);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (data->machinetype != expect_machinetype &&
|
||||
STRNEQ(data->machinetype, expect_machinetype)) {
|
||||
fprintf(stderr, "data->machinetype=%s doesn't match "
|
||||
"expect_machinetype=%s\n",
|
||||
data->machinetype, expect_machinetype);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = true;
|
||||
error:
|
||||
VIR_FREE(data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define CAPSCOMP(o, a, d, e, m, fo, fa, fd, fe, fm) \
|
||||
if (!doCapsCompare(caps, o, a, d, e, m, fo, fa, fd, fe, fm)) \
|
||||
ret = 1;
|
||||
|
||||
#define CAPS_EXPECT_ERR(o, a, d, e, m) \
|
||||
if (!doCapsExpectFailure(caps, o, a, d, e, m)) \
|
||||
ret = 1;
|
||||
|
||||
static int
|
||||
test_virCapsDomainDataLookupQEMU(const void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int ret = 0;
|
||||
virCapsPtr caps = NULL;
|
||||
|
||||
if (!(caps = testQemuCapsInit())) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Checking each parameter individually */
|
||||
CAPSCOMP(-1, VIR_ARCH_NONE, -1, NULL, NULL,
|
||||
VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_I686,
|
||||
VIR_DOMAIN_VIRT_QEMU, "/usr/bin/qemu", "pc");
|
||||
CAPSCOMP(VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_NONE, -1, NULL, NULL,
|
||||
VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_I686,
|
||||
VIR_DOMAIN_VIRT_QEMU, "/usr/bin/qemu", "pc");
|
||||
CAPSCOMP(-1, VIR_ARCH_AARCH64, -1, NULL, NULL,
|
||||
VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_AARCH64,
|
||||
VIR_DOMAIN_VIRT_QEMU, "/usr/bin/qemu-system-aarch64", "virt");
|
||||
CAPSCOMP(-1, VIR_ARCH_NONE, VIR_DOMAIN_VIRT_KVM, NULL, NULL,
|
||||
VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_X86_64,
|
||||
VIR_DOMAIN_VIRT_KVM, "/usr/bin/kvm", "pc");
|
||||
CAPSCOMP(-1, VIR_ARCH_NONE, -1, "/usr/bin/qemu-system-ppc64", NULL,
|
||||
VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_PPC64,
|
||||
VIR_DOMAIN_VIRT_QEMU, "/usr/bin/qemu-system-ppc64", "pseries");
|
||||
CAPSCOMP(-1, VIR_ARCH_NONE, -1, NULL, "s390-virtio",
|
||||
VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_S390X,
|
||||
VIR_DOMAIN_VIRT_QEMU, "/usr/bin/qemu-system-s390x",
|
||||
"s390-virtio");
|
||||
|
||||
CAPSCOMP(-1, VIR_ARCH_NONE, -1, NULL, "pseries",
|
||||
VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_PPC64,
|
||||
VIR_DOMAIN_VIRT_QEMU, "/usr/bin/qemu-system-ppc64", "pseries");
|
||||
CAPSCOMP(-1, VIR_ARCH_PPC64LE, -1, NULL, "pseries",
|
||||
VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_PPC64LE,
|
||||
VIR_DOMAIN_VIRT_QEMU, "/usr/bin/qemu-system-ppc64", "pseries");
|
||||
|
||||
CAPS_EXPECT_ERR(VIR_DOMAIN_OSTYPE_AIX, VIR_ARCH_NONE, -1, NULL, NULL);
|
||||
CAPS_EXPECT_ERR(-1, VIR_ARCH_PPC64LE, -1, NULL, "pc");
|
||||
CAPS_EXPECT_ERR(-1, VIR_ARCH_MIPS, -1, NULL, NULL);
|
||||
CAPS_EXPECT_ERR(-1, VIR_ARCH_AARCH64, VIR_DOMAIN_VIRT_KVM,
|
||||
"/usr/bin/qemu-system-aarch64", NULL);
|
||||
CAPS_EXPECT_ERR(-1, VIR_ARCH_NONE, -1,
|
||||
"/usr/bin/qemu-system-aarch64", "pc");
|
||||
CAPS_EXPECT_ERR(-1, VIR_ARCH_NONE, VIR_DOMAIN_VIRT_VMWARE, NULL, "pc");
|
||||
|
||||
out:
|
||||
virObjectUnref(caps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
test_virCapsDomainDataLookupXen(const void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int ret = -1;
|
||||
virCapsPtr caps = NULL;
|
||||
|
||||
if (!(caps = testXenCapsInit())) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
CAPSCOMP(-1, VIR_ARCH_NONE, -1, NULL, NULL,
|
||||
VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_I686, VIR_DOMAIN_VIRT_XEN,
|
||||
"/usr/lib/xen/bin/qemu-dm", "xenfv");
|
||||
CAPSCOMP(VIR_DOMAIN_OSTYPE_XEN, VIR_ARCH_NONE, -1, NULL, NULL,
|
||||
VIR_DOMAIN_OSTYPE_XEN, VIR_ARCH_I686, VIR_DOMAIN_VIRT_XEN,
|
||||
"/usr/lib/xen/bin/qemu-dm", "xenpv");
|
||||
|
||||
CAPS_EXPECT_ERR(VIR_DOMAIN_OSTYPE_XEN, VIR_ARCH_NONE, -1, NULL, "xenfv");
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
virObjectUnref(caps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
test_virCapsDomainDataLookupLXC(const void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int ret = 0;
|
||||
virCapsPtr caps = NULL;
|
||||
|
||||
if (!(caps = testLXCCapsInit())) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
CAPSCOMP(-1, VIR_ARCH_NONE, -1, NULL, NULL,
|
||||
VIR_DOMAIN_OSTYPE_EXE, VIR_ARCH_I686,
|
||||
VIR_DOMAIN_VIRT_LXC, "/usr/libexec/libvirt_lxc", NULL);
|
||||
CAPSCOMP(-1, VIR_ARCH_X86_64, -1, NULL, NULL,
|
||||
VIR_DOMAIN_OSTYPE_EXE, VIR_ARCH_X86_64,
|
||||
VIR_DOMAIN_VIRT_LXC, "/usr/libexec/libvirt_lxc", NULL);
|
||||
|
||||
out:
|
||||
virObjectUnref(caps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
mymain(void)
|
||||
{
|
||||
@ -126,6 +320,15 @@ mymain(void)
|
||||
if (virtTestRun("virCapabilitiesGetCpusForNodemask",
|
||||
test_virCapabilitiesGetCpusForNodemask, NULL) < 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("virCapsDomainDataLookupQEMU",
|
||||
test_virCapsDomainDataLookupQEMU, NULL) < 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("virCapsDomainDataLookupXen",
|
||||
test_virCapsDomainDataLookupXen, NULL) < 0)
|
||||
ret = -1;
|
||||
if (virtTestRun("virCapsDomainDataLookupLXC",
|
||||
test_virCapsDomainDataLookupLXC, NULL) < 0)
|
||||
ret = -1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user