提交 a6936523 编写于 作者: C Cole Robinson

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.
上级 4fa6f9b4
......@@ -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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册