mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
For S390, the default console target type cannot be of type 'serial'. It is necessary to at least interpret the 'arch' attribute value of the os/type element to produce the correct default type. Therefore we need to extend the signature of defaultConsoleTargetType to account for architecture. As a consequence all the drivers supporting this capability function must be updated. Despite the amount of changed files, the only change in behavior is that for S390 the default console target type will be 'virtio'. N.B.: A more future-proof approach could be to to use hypervisor specific capabilities to determine the best possible console type. For instance one could add an opaque private data pointer to the virCaps structure (in case of QEMU to hold capsCache) which could then be passed to the defaultConsoleTargetType callback to determine the console target type. Seems to be however a bit overengineered for the use case... Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
267 lines
8.2 KiB
C
267 lines
8.2 KiB
C
#include <config.h>
|
|
#ifdef WITH_QEMU
|
|
# include <stdlib.h>
|
|
|
|
# include "testutilsqemu.h"
|
|
# include "testutils.h"
|
|
# include "memory.h"
|
|
# include "cpu_conf.h"
|
|
# include "qemu/qemu_driver.h"
|
|
# include "qemu/qemu_domain.h"
|
|
|
|
static virCapsGuestMachinePtr *testQemuAllocMachines(int *nmachines)
|
|
{
|
|
virCapsGuestMachinePtr *machines;
|
|
static const char *const x86_machines[] = {
|
|
"pc", "isapc"
|
|
};
|
|
|
|
machines = virCapabilitiesAllocMachines(x86_machines,
|
|
ARRAY_CARDINALITY(x86_machines));
|
|
if (machines == NULL)
|
|
return NULL;
|
|
|
|
*nmachines = ARRAY_CARDINALITY(x86_machines);
|
|
|
|
return machines;
|
|
}
|
|
|
|
/* Newer versions of qemu have versioned machine types to allow
|
|
* compatibility with older releases.
|
|
* The 'pc' machine type is an alias of the newest machine type.
|
|
*/
|
|
static virCapsGuestMachinePtr *testQemuAllocNewerMachines(int *nmachines)
|
|
{
|
|
virCapsGuestMachinePtr *machines;
|
|
char *canonical;
|
|
static const char *const x86_machines[] = {
|
|
"pc-0.11", "pc", "pc-0.10", "isapc"
|
|
};
|
|
|
|
if ((canonical = strdup(x86_machines[0])) == NULL)
|
|
return NULL;
|
|
|
|
machines = virCapabilitiesAllocMachines(x86_machines,
|
|
ARRAY_CARDINALITY(x86_machines));
|
|
if (machines == NULL) {
|
|
VIR_FREE(canonical);
|
|
return NULL;
|
|
}
|
|
|
|
machines[1]->canonical = canonical;
|
|
|
|
*nmachines = ARRAY_CARDINALITY(x86_machines);
|
|
|
|
return machines;
|
|
}
|
|
|
|
static int testQemuDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED,
|
|
const char *arch)
|
|
{
|
|
if (STRPREFIX(arch, "s390"))
|
|
return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO;
|
|
else
|
|
return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
|
|
}
|
|
|
|
static int testQemuAddPPC64Guest(virCapsPtr caps)
|
|
{
|
|
static const char *machine[] = { "pseries" };
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
virCapsGuestPtr guest;
|
|
|
|
machines = virCapabilitiesAllocMachines(machine, 1);
|
|
if (!machines)
|
|
goto error;
|
|
|
|
guest = virCapabilitiesAddGuest(caps, "hvm", "ppc64", 64,
|
|
"/usr/bin/qemu-system-ppc64", NULL,
|
|
1, machines);
|
|
if (!guest)
|
|
goto error;
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, "qemu", NULL, NULL, 0, NULL))
|
|
goto error;
|
|
|
|
return 0;
|
|
|
|
error:
|
|
/* No way to free a guest? */
|
|
virCapabilitiesFreeMachines(machines, 1);
|
|
return -1;
|
|
}
|
|
|
|
static int testQemuAddS390Guest(virCapsPtr caps)
|
|
{
|
|
static const char *s390_machines[] = { "s390-virtio"};
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
virCapsGuestPtr guest;
|
|
|
|
machines = virCapabilitiesAllocMachines(s390_machines,
|
|
ARRAY_CARDINALITY(s390_machines));
|
|
if (!machines)
|
|
goto error;
|
|
|
|
guest = virCapabilitiesAddGuest(caps, "hvm", "s390x", 64,
|
|
"/usr/bin/qemu-system-s390x", NULL,
|
|
ARRAY_CARDINALITY(s390_machines),
|
|
machines);
|
|
if (!guest)
|
|
goto error;
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, "qemu", NULL, NULL, 0, NULL))
|
|
goto error;
|
|
|
|
return 0;
|
|
|
|
error:
|
|
virCapabilitiesFreeMachines(machines, ARRAY_CARDINALITY(s390_machines));
|
|
return -1;
|
|
}
|
|
|
|
virCapsPtr testQemuCapsInit(void) {
|
|
virCapsPtr caps;
|
|
virCapsGuestPtr guest;
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
int nmachines = 0;
|
|
static const char *const xen_machines[] = {
|
|
"xenner"
|
|
};
|
|
static virCPUFeatureDef host_cpu_features[] = {
|
|
{ (char *) "lahf_lm", -1 },
|
|
{ (char *) "xtpr", -1 },
|
|
{ (char *) "cx16", -1 },
|
|
{ (char *) "tm2", -1 },
|
|
{ (char *) "est", -1 },
|
|
{ (char *) "vmx", -1 },
|
|
{ (char *) "ds_cpl", -1 },
|
|
{ (char *) "pbe", -1 },
|
|
{ (char *) "tm", -1 },
|
|
{ (char *) "ht", -1 },
|
|
{ (char *) "ss", -1 },
|
|
{ (char *) "acpi", -1 },
|
|
{ (char *) "ds", -1 }
|
|
};
|
|
static virCPUDef host_cpu = {
|
|
VIR_CPU_TYPE_HOST, /* type */
|
|
0, /* mode */
|
|
0, /* match */
|
|
(char *) "x86_64", /* arch */
|
|
(char *) "core2duo", /* model */
|
|
NULL, /* vendor_id */
|
|
0, /* fallback */
|
|
(char *) "Intel", /* vendor */
|
|
1, /* sockets */
|
|
2, /* cores */
|
|
1, /* threads */
|
|
ARRAY_CARDINALITY(host_cpu_features), /* nfeatures */
|
|
ARRAY_CARDINALITY(host_cpu_features), /* nfeatures_max */
|
|
host_cpu_features, /* features */
|
|
0, /* ncells */
|
|
0, /* ncells_max */
|
|
NULL, /* cells */
|
|
0, /* cells_cpus */
|
|
};
|
|
|
|
if ((caps = virCapabilitiesNew(host_cpu.arch,
|
|
0, 0)) == NULL)
|
|
return NULL;
|
|
|
|
caps->defaultConsoleTargetType = testQemuDefaultConsoleType;
|
|
|
|
if ((caps->host.cpu = virCPUDefCopy(&host_cpu)) == NULL ||
|
|
(machines = testQemuAllocMachines(&nmachines)) == NULL)
|
|
goto cleanup;
|
|
|
|
qemuDomainSetNamespaceHooks(caps);
|
|
|
|
if ((guest = virCapabilitiesAddGuest(caps, "hvm", "i686", 32,
|
|
"/usr/bin/qemu", NULL,
|
|
nmachines, machines)) == NULL ||
|
|
!virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0))
|
|
goto cleanup;
|
|
machines = NULL;
|
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
"qemu",
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL) == NULL)
|
|
goto cleanup;
|
|
|
|
if ((machines = testQemuAllocNewerMachines(&nmachines)) == NULL)
|
|
goto cleanup;
|
|
|
|
if ((guest = virCapabilitiesAddGuest(caps, "hvm", "x86_64", 64,
|
|
"/usr/bin/qemu-system-x86_64", NULL,
|
|
nmachines, machines)) == NULL ||
|
|
!virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0))
|
|
goto cleanup;
|
|
machines = NULL;
|
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
"qemu",
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
NULL) == NULL)
|
|
goto cleanup;
|
|
|
|
if ((machines = testQemuAllocMachines(&nmachines)) == NULL)
|
|
goto cleanup;
|
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
"kvm",
|
|
"/usr/bin/kvm",
|
|
NULL,
|
|
nmachines,
|
|
machines) == NULL)
|
|
goto cleanup;
|
|
machines = NULL;
|
|
|
|
nmachines = ARRAY_CARDINALITY(xen_machines);
|
|
if ((machines = virCapabilitiesAllocMachines(xen_machines, nmachines)) == NULL)
|
|
goto cleanup;
|
|
|
|
if ((guest = virCapabilitiesAddGuest(caps, "xen", "x86_64", 64,
|
|
"/usr/bin/xenner", NULL,
|
|
nmachines, machines)) == NULL)
|
|
goto cleanup;
|
|
machines = NULL;
|
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
"kvm",
|
|
"/usr/bin/kvm",
|
|
NULL,
|
|
0,
|
|
NULL) == NULL)
|
|
goto cleanup;
|
|
|
|
if (testQemuAddPPC64Guest(caps))
|
|
goto cleanup;
|
|
|
|
if (testQemuAddS390Guest(caps))
|
|
goto cleanup;
|
|
|
|
if (virTestGetDebug()) {
|
|
char *caps_str;
|
|
|
|
caps_str = virCapabilitiesFormatXML(caps);
|
|
if (!caps_str)
|
|
goto cleanup;
|
|
|
|
fprintf(stderr, "QEMU driver capabilities:\n%s", caps_str);
|
|
|
|
VIR_FREE(caps_str);
|
|
}
|
|
|
|
return caps;
|
|
|
|
cleanup:
|
|
virCapabilitiesFreeMachines(machines, nmachines);
|
|
virCapabilitiesFree(caps);
|
|
return NULL;
|
|
}
|
|
#endif
|