mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-13 08:58:33 +03:00
Add virCapsGuestMachine structure
A subsequent commit will add a "canonical" field to this structure, this patch basically just prepares the way for that. The new type is added, along with virCapabilitiesAlloc/FreeMachines() helpers and a whole bunch of code to make the transition. One quirk is that virCapabilitiesAddGuestDomain() and virCapabilitiesAddGuest() take ownership of the machine list rather than duping it. This makes sense to avoid needless copying. * src/capabilities.h: add the virCapsGuestMachine struct and use it in virCapsGuestDomainInfo, add prototypes for new functions and update the AddGuest() prototypes * src/capabilities.c: add code for allocating and freeing the new type, change the machines parameter to AddGuest() etc. * src/libvirt_private.syms: export the new helpers * src/qemu_conf.c: update all the machine type code to use the new struct * src/xen_internal.c: ditto * tests/testutilsqemu.c: ditto
This commit is contained in:
parent
d412487eb7
commit
38fd207e53
@ -68,6 +68,16 @@ virCapabilitiesFreeHostNUMACell(virCapsHostNUMACellPtr cell)
|
||||
VIR_FREE(cell);
|
||||
}
|
||||
|
||||
static void
|
||||
virCapabilitiesFreeGuestMachine(virCapsGuestMachinePtr machine)
|
||||
{
|
||||
if (machine == NULL)
|
||||
return;
|
||||
VIR_FREE(machine->name);
|
||||
VIR_FREE(machine->canonical);
|
||||
VIR_FREE(machine);
|
||||
}
|
||||
|
||||
static void
|
||||
virCapabilitiesFreeGuestDomain(virCapsGuestDomainPtr dom)
|
||||
{
|
||||
@ -78,7 +88,7 @@ virCapabilitiesFreeGuestDomain(virCapsGuestDomainPtr dom)
|
||||
VIR_FREE(dom->info.emulator);
|
||||
VIR_FREE(dom->info.loader);
|
||||
for (i = 0 ; i < dom->info.nmachines ; i++)
|
||||
VIR_FREE(dom->info.machines[i]);
|
||||
virCapabilitiesFreeGuestMachine(dom->info.machines[i]);
|
||||
VIR_FREE(dom->info.machines);
|
||||
VIR_FREE(dom->type);
|
||||
|
||||
@ -107,7 +117,7 @@ virCapabilitiesFreeGuest(virCapsGuestPtr guest)
|
||||
VIR_FREE(guest->arch.defaultInfo.emulator);
|
||||
VIR_FREE(guest->arch.defaultInfo.loader);
|
||||
for (i = 0 ; i < guest->arch.defaultInfo.nmachines ; i++)
|
||||
VIR_FREE(guest->arch.defaultInfo.machines[i]);
|
||||
virCapabilitiesFreeGuestMachine(guest->arch.defaultInfo.machines[i]);
|
||||
VIR_FREE(guest->arch.defaultInfo.machines);
|
||||
|
||||
for (i = 0 ; i < guest->arch.ndomains ; i++)
|
||||
@ -252,6 +262,53 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* virCapabilitiesAllocMachines:
|
||||
* @machines: machine variants for emulator ('pc', or 'isapc', etc)
|
||||
* @nmachines: number of machine variants for emulator
|
||||
*
|
||||
* Allocate a table of virCapsGuestMachinePtr from the supplied table
|
||||
* of machine names.
|
||||
*/
|
||||
virCapsGuestMachinePtr *
|
||||
virCapabilitiesAllocMachines(const char *const *names, int nnames)
|
||||
{
|
||||
virCapsGuestMachinePtr *machines;
|
||||
int i;
|
||||
|
||||
if (VIR_ALLOC_N(machines, nnames) < 0)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < nnames; i++) {
|
||||
if (VIR_ALLOC(machines[i]) < 0 ||
|
||||
!(machines[i]->name = strdup(names[i]))) {
|
||||
virCapabilitiesFreeMachines(machines, nnames);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return machines;
|
||||
}
|
||||
|
||||
/**
|
||||
* virCapabilitiesFreeMachines:
|
||||
* @machines: table of vircapsGuestMachinePtr
|
||||
*
|
||||
* Free a table of virCapsGuestMachinePtr
|
||||
*/
|
||||
void
|
||||
virCapabilitiesFreeMachines(virCapsGuestMachinePtr *machines,
|
||||
int nmachines)
|
||||
{
|
||||
int i;
|
||||
if (!machines)
|
||||
return;
|
||||
for (i = 0; i < nmachines && machines[i]; i++) {
|
||||
virCapabilitiesFreeGuestMachine(machines[i]);
|
||||
machines[i] = NULL;
|
||||
}
|
||||
VIR_FREE(machines);
|
||||
}
|
||||
|
||||
/**
|
||||
* virCapabilitiesAddGuest:
|
||||
@ -276,10 +333,9 @@ virCapabilitiesAddGuest(virCapsPtr caps,
|
||||
const char *emulator,
|
||||
const char *loader,
|
||||
int nmachines,
|
||||
const char *const *machines)
|
||||
virCapsGuestMachinePtr *machines)
|
||||
{
|
||||
virCapsGuestPtr guest;
|
||||
int i;
|
||||
|
||||
if (VIR_ALLOC(guest) < 0)
|
||||
goto no_memory;
|
||||
@ -298,14 +354,8 @@ virCapabilitiesAddGuest(virCapsPtr caps,
|
||||
(guest->arch.defaultInfo.loader = strdup(loader)) == NULL)
|
||||
goto no_memory;
|
||||
if (nmachines) {
|
||||
if (VIR_ALLOC_N(guest->arch.defaultInfo.machines,
|
||||
nmachines) < 0)
|
||||
goto no_memory;
|
||||
for (i = 0 ; i < nmachines ; i++) {
|
||||
if ((guest->arch.defaultInfo.machines[i] = strdup(machines[i])) == NULL)
|
||||
goto no_memory;
|
||||
guest->arch.defaultInfo.nmachines++;
|
||||
}
|
||||
guest->arch.defaultInfo.nmachines = nmachines;
|
||||
guest->arch.defaultInfo.machines = machines;
|
||||
}
|
||||
|
||||
if (VIR_REALLOC_N(caps->guests,
|
||||
@ -340,10 +390,9 @@ virCapabilitiesAddGuestDomain(virCapsGuestPtr guest,
|
||||
const char *emulator,
|
||||
const char *loader,
|
||||
int nmachines,
|
||||
const char *const *machines)
|
||||
virCapsGuestMachinePtr *machines)
|
||||
{
|
||||
virCapsGuestDomainPtr dom;
|
||||
int i;
|
||||
|
||||
if (VIR_ALLOC(dom) < 0)
|
||||
goto no_memory;
|
||||
@ -358,13 +407,8 @@ virCapabilitiesAddGuestDomain(virCapsGuestPtr guest,
|
||||
(dom->info.loader = strdup(loader)) == NULL)
|
||||
goto no_memory;
|
||||
if (nmachines) {
|
||||
if (VIR_ALLOC_N(dom->info.machines, nmachines) < 0)
|
||||
goto no_memory;
|
||||
for (i = 0 ; i < nmachines ; i++) {
|
||||
if ((dom->info.machines[i] = strdup(machines[i])) == NULL)
|
||||
goto no_memory;
|
||||
dom->info.nmachines++;
|
||||
}
|
||||
dom->info.nmachines = nmachines;
|
||||
dom->info.machines = machines;
|
||||
}
|
||||
|
||||
if (VIR_REALLOC_N(guest->arch.domains,
|
||||
@ -517,7 +561,7 @@ virCapabilitiesDefaultGuestMachine(virCapsPtr caps,
|
||||
if (STREQ(caps->guests[i]->ostype, ostype) &&
|
||||
STREQ(caps->guests[i]->arch.name, arch) &&
|
||||
caps->guests[i]->arch.defaultInfo.nmachines)
|
||||
return caps->guests[i]->arch.defaultInfo.machines[0];
|
||||
return caps->guests[i]->arch.defaultInfo.machines[0]->name;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -649,7 +693,7 @@ virCapabilitiesFormatXML(virCapsPtr caps)
|
||||
|
||||
for (j = 0 ; j < caps->guests[i]->arch.defaultInfo.nmachines ; j++) {
|
||||
virBufferVSprintf(&xml, " <machine>%s</machine>\n",
|
||||
caps->guests[i]->arch.defaultInfo.machines[j]);
|
||||
caps->guests[i]->arch.defaultInfo.machines[j]->name);
|
||||
}
|
||||
|
||||
for (j = 0 ; j < caps->guests[i]->arch.ndomains ; j++) {
|
||||
@ -664,7 +708,7 @@ virCapabilitiesFormatXML(virCapsPtr caps)
|
||||
|
||||
for (k = 0 ; k < caps->guests[i]->arch.domains[j]->info.nmachines ; k++) {
|
||||
virBufferVSprintf(&xml, " <machine>%s</machine>\n",
|
||||
caps->guests[i]->arch.domains[j]->info.machines[k]);
|
||||
caps->guests[i]->arch.domains[j]->info.machines[k]->name);
|
||||
}
|
||||
virBufferAddLit(&xml, " </domain>\n");
|
||||
}
|
||||
|
@ -35,13 +35,20 @@ struct _virCapsGuestFeature {
|
||||
int toggle;
|
||||
};
|
||||
|
||||
typedef struct _virCapsGuestMachine virCapsGuestMachine;
|
||||
typedef virCapsGuestMachine *virCapsGuestMachinePtr;
|
||||
struct _virCapsGuestMachine {
|
||||
char *name;
|
||||
char *canonical;
|
||||
};
|
||||
|
||||
typedef struct _virCapsGuestDomainInfo virCapsGuestDomainInfo;
|
||||
typedef virCapsGuestDomainInfo *virCapsGuestDomainInfoPtr;
|
||||
struct _virCapsGuestDomainInfo {
|
||||
char *emulator;
|
||||
char *loader;
|
||||
int nmachines;
|
||||
char **machines;
|
||||
virCapsGuestMachinePtr *machines;
|
||||
};
|
||||
|
||||
typedef struct _virCapsGuestDomain virCapsGuestDomain;
|
||||
@ -152,6 +159,13 @@ virCapabilitiesAddHostNUMACell(virCapsPtr caps,
|
||||
|
||||
|
||||
|
||||
extern virCapsGuestMachinePtr *
|
||||
virCapabilitiesAllocMachines(const char *const *names,
|
||||
int nnames);
|
||||
extern void
|
||||
virCapabilitiesFreeMachines(virCapsGuestMachinePtr *machines,
|
||||
int nmachines);
|
||||
|
||||
extern virCapsGuestPtr
|
||||
virCapabilitiesAddGuest(virCapsPtr caps,
|
||||
const char *ostype,
|
||||
@ -160,7 +174,7 @@ virCapabilitiesAddGuest(virCapsPtr caps,
|
||||
const char *emulator,
|
||||
const char *loader,
|
||||
int nmachines,
|
||||
const char *const *machines);
|
||||
virCapsGuestMachinePtr *machines);
|
||||
|
||||
extern virCapsGuestDomainPtr
|
||||
virCapabilitiesAddGuestDomain(virCapsGuestPtr guest,
|
||||
@ -168,7 +182,7 @@ virCapabilitiesAddGuestDomain(virCapsGuestPtr guest,
|
||||
const char *emulator,
|
||||
const char *loader,
|
||||
int nmachines,
|
||||
const char *const *machines);
|
||||
virCapsGuestMachinePtr *machines);
|
||||
|
||||
extern virCapsGuestFeaturePtr
|
||||
virCapabilitiesAddGuestFeature(virCapsGuestPtr guest,
|
||||
|
@ -30,6 +30,8 @@ virCapabilitiesSetMacPrefix;
|
||||
virCapabilitiesGenerateMac;
|
||||
virCapabilitiesSetEmulatorRequired;
|
||||
virCapabilitiesIsEmulatorRequired;
|
||||
virCapabilitiesAllocMachines;
|
||||
virCapabilitiesFreeMachines;
|
||||
|
||||
|
||||
# conf.h
|
||||
|
@ -336,17 +336,17 @@ static const struct qemu_arch_info const arch_info_xen[] = {
|
||||
*/
|
||||
static int
|
||||
qemudParseMachineTypesStr(const char *output,
|
||||
char ***machines,
|
||||
virCapsGuestMachinePtr **machines,
|
||||
int *nmachines)
|
||||
{
|
||||
const char *p = output;
|
||||
const char *next;
|
||||
char **list = NULL;
|
||||
int i, nitems = 0;
|
||||
virCapsGuestMachinePtr *list = NULL;
|
||||
int nitems = 0;
|
||||
|
||||
do {
|
||||
const char *t;
|
||||
char *machine;
|
||||
virCapsGuestMachinePtr machine;
|
||||
|
||||
if ((next = strchr(p, '\n')))
|
||||
++next;
|
||||
@ -357,10 +357,16 @@ qemudParseMachineTypesStr(const char *output,
|
||||
if (!(t = strchr(p, ' ')) || (next && t >= next))
|
||||
continue;
|
||||
|
||||
if (!(machine = strndup(p, t - p)))
|
||||
if (VIR_ALLOC(machine) < 0)
|
||||
goto error;
|
||||
|
||||
if (!(machine->name = strndup(p, t - p))) {
|
||||
VIR_FREE(machine);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (VIR_REALLOC_N(list, nitems + 1) < 0) {
|
||||
VIR_FREE(machine->name);
|
||||
VIR_FREE(machine);
|
||||
goto error;
|
||||
}
|
||||
@ -382,15 +388,13 @@ qemudParseMachineTypesStr(const char *output,
|
||||
return 0;
|
||||
|
||||
error:
|
||||
for (i = 0; i < nitems; i++)
|
||||
VIR_FREE(list[i]);
|
||||
VIR_FREE(list);
|
||||
virCapabilitiesFreeMachines(list, nitems);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
qemudProbeMachineTypes(const char *binary,
|
||||
char ***machines,
|
||||
virCapsGuestMachinePtr **machines,
|
||||
int *nmachines)
|
||||
{
|
||||
const char *const qemuarg[] = { binary, "-M", "?", NULL };
|
||||
@ -454,7 +458,7 @@ qemudCapsInitGuest(virCapsPtr caps,
|
||||
int haskqemu = 0;
|
||||
const char *kvmbin = NULL;
|
||||
const char *binary = NULL;
|
||||
char **machines = NULL;
|
||||
virCapsGuestMachinePtr *machines = NULL;
|
||||
int nmachines = 0;
|
||||
|
||||
/* Check for existance of base emulator, or alternate base
|
||||
@ -495,12 +499,18 @@ qemudCapsInitGuest(virCapsPtr caps,
|
||||
return 0;
|
||||
|
||||
if (info->machine) {
|
||||
char *machine;
|
||||
virCapsGuestMachinePtr machine;
|
||||
|
||||
if (!(machine = strdup(info->machine)))
|
||||
if (VIR_ALLOC(machine) < 0)
|
||||
return -1;
|
||||
|
||||
if (!(machine->name = strdup(info->machine))) {
|
||||
VIR_FREE(machine);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (VIR_ALLOC_N(machines, nmachines) < 0) {
|
||||
VIR_FREE(machine->name);
|
||||
VIR_FREE(machine);
|
||||
return -1;
|
||||
}
|
||||
@ -520,17 +530,15 @@ qemudCapsInitGuest(virCapsPtr caps,
|
||||
binary,
|
||||
NULL,
|
||||
nmachines,
|
||||
(const char *const *)machines)) == NULL) {
|
||||
for (i = 0; i < nmachines; i++)
|
||||
machines)) == NULL) {
|
||||
for (i = 0; i < nmachines; i++) {
|
||||
VIR_FREE(machines[i]->name);
|
||||
VIR_FREE(machines[i]);
|
||||
}
|
||||
VIR_FREE(machines);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < nmachines; i++)
|
||||
VIR_FREE(machines[i]);
|
||||
VIR_FREE(machines);
|
||||
|
||||
if (hvm) {
|
||||
if (virCapabilitiesAddGuestDomain(guest,
|
||||
"qemu",
|
||||
|
@ -2202,7 +2202,11 @@ xenHypervisorBuildCapabilities(virConnectPtr conn,
|
||||
|
||||
for (i = 0; i < nr_guest_archs; ++i) {
|
||||
virCapsGuestPtr guest;
|
||||
char const *const machines[] = {guest_archs[i].hvm ? "xenfv" : "xenpv"};
|
||||
char const *const xen_machines[] = {guest_archs[i].hvm ? "xenfv" : "xenpv"};
|
||||
virCapsGuestMachinePtr *machines;
|
||||
|
||||
if ((machines = virCapabiltiesAllocMachines(xen_machines, 1)) == NULL)
|
||||
goto no_memory;
|
||||
|
||||
if ((guest = virCapabilitiesAddGuest(caps,
|
||||
guest_archs[i].hvm ? "hvm" : "xen",
|
||||
@ -2215,8 +2219,12 @@ xenHypervisorBuildCapabilities(virConnectPtr conn,
|
||||
"/usr/lib/xen/boot/hvmloader" :
|
||||
NULL),
|
||||
1,
|
||||
machines)) == NULL)
|
||||
machines)) == NULL) {
|
||||
virCapabilitiesFreeMachines(machines, 1);
|
||||
goto no_memory;
|
||||
}
|
||||
|
||||
virCapabilitiesFreeMachines(machines, 1);
|
||||
|
||||
if (virCapabilitiesAddGuestDomain(guest,
|
||||
"xen",
|
||||
|
@ -9,6 +9,8 @@ virCapsPtr testQemuCapsInit(void) {
|
||||
struct utsname utsname;
|
||||
virCapsPtr caps;
|
||||
virCapsGuestPtr guest;
|
||||
virCapsGuestMachinePtr *machines;
|
||||
int nmachines;
|
||||
static const char *const x86_machines[] = {
|
||||
"pc", "isapc"
|
||||
};
|
||||
@ -21,10 +23,16 @@ virCapsPtr testQemuCapsInit(void) {
|
||||
0, 0)) == NULL)
|
||||
return NULL;
|
||||
|
||||
nmachines = 2;
|
||||
if ((machines = virCapabilitiesAllocMachines(x86_machines, nmachines)) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if ((guest = virCapabilitiesAddGuest(caps, "hvm", "i686", 32,
|
||||
"/usr/bin/qemu", NULL,
|
||||
2, x86_machines)) == NULL)
|
||||
nmachines, machines)) == NULL)
|
||||
goto cleanup;
|
||||
machines = NULL;
|
||||
|
||||
if (virCapabilitiesAddGuestDomain(guest,
|
||||
"qemu",
|
||||
NULL,
|
||||
@ -33,10 +41,16 @@ virCapsPtr testQemuCapsInit(void) {
|
||||
NULL) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
nmachines = 2;
|
||||
if ((machines = virCapabilitiesAllocMachines(x86_machines, nmachines)) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if ((guest = virCapabilitiesAddGuest(caps, "hvm", "x86_64", 64,
|
||||
"/usr/bin/qemu-system-x86_64", NULL,
|
||||
2, x86_machines)) == NULL)
|
||||
nmachines, machines)) == NULL)
|
||||
goto cleanup;
|
||||
machines = NULL;
|
||||
|
||||
if (virCapabilitiesAddGuestDomain(guest,
|
||||
"qemu",
|
||||
NULL,
|
||||
@ -52,10 +66,16 @@ virCapsPtr testQemuCapsInit(void) {
|
||||
NULL) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
nmachines = 1;
|
||||
if ((machines = virCapabilitiesAllocMachines(xen_machines, nmachines)) == NULL)
|
||||
goto cleanup;
|
||||
|
||||
if ((guest = virCapabilitiesAddGuest(caps, "xen", "x86_64", 64,
|
||||
"/usr/bin/xenner", NULL,
|
||||
1, xen_machines)) == NULL)
|
||||
1, machines)) == NULL)
|
||||
goto cleanup;
|
||||
machines = NULL;
|
||||
|
||||
if (virCapabilitiesAddGuestDomain(guest,
|
||||
"kvm",
|
||||
"/usr/bin/kvm",
|
||||
@ -67,6 +87,7 @@ virCapsPtr testQemuCapsInit(void) {
|
||||
return caps;
|
||||
|
||||
cleanup:
|
||||
virCapabilitiesFreeMachines(machines, nmachines);
|
||||
virCapabilitiesFree(caps);
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user