2008-05-23 00:18:40 +08:00
|
|
|
#include <config.h>
|
2008-06-26 17:37:51 +08:00
|
|
|
#ifdef WITH_QEMU
|
2010-03-10 02:22:22 +08:00
|
|
|
# include <stdlib.h>
|
2008-05-17 00:51:30 +08:00
|
|
|
|
2010-03-10 02:22:22 +08:00
|
|
|
# include "testutilsqemu.h"
|
|
|
|
# include "testutils.h"
|
2012-12-13 02:06:53 +08:00
|
|
|
# include "viralloc.h"
|
2010-04-16 14:01:59 +08:00
|
|
|
# include "cpu_conf.h"
|
2010-04-21 05:22:49 +08:00
|
|
|
# include "qemu/qemu_driver.h"
|
2010-12-18 00:41:51 +08:00
|
|
|
# include "qemu/qemu_domain.h"
|
2013-05-03 20:52:21 +08:00
|
|
|
# include "virstring.h"
|
|
|
|
|
|
|
|
# define VIR_FROM_THIS VIR_FROM_QEMU
|
2008-05-17 00:51:30 +08:00
|
|
|
|
2009-09-10 17:16:27 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2009-09-10 18:19:12 +08:00
|
|
|
/* 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"
|
|
|
|
};
|
|
|
|
|
2013-05-03 20:52:21 +08:00
|
|
|
if (VIR_STRDUP(canonical, x86_machines[0]) < 0)
|
2009-09-10 18:19:12 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
Fix default console type setting
The default console type may vary based on the OS type. ie a Xen
paravirt guests wants a 'xen' console, while a fullvirt guests
wants a 'serial' console.
A plain integer default console type in the capabilities does
not suffice. Instead introduce a callback that is passed the
OS type.
* src/conf/capabilities.h: Use a callback for default console
type
* src/conf/domain_conf.c, src/conf/domain_conf.h: Use callback
for default console type. Add missing LXC/OpenVZ console types.
* src/esx/esx_driver.c, src/libxl/libxl_conf.c,
src/lxc/lxc_conf.c, src/openvz/openvz_conf.c,
src/phyp/phyp_driver.c, src/qemu/qemu_capabilities.c,
src/uml/uml_conf.c, src/vbox/vbox_tmpl.c,
src/vmware/vmware_conf.c, src/xen/xen_hypervisor.c,
src/xenapi/xenapi_driver.c: Set default console type callback
2011-10-20 21:56:20 +08:00
|
|
|
|
2011-12-13 07:39:33 +08:00
|
|
|
static int testQemuAddPPC64Guest(virCapsPtr caps)
|
|
|
|
{
|
|
|
|
static const char *machine[] = { "pseries" };
|
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
machines = virCapabilitiesAllocMachines(machine, 1);
|
|
|
|
if (!machines)
|
|
|
|
goto error;
|
|
|
|
|
2012-12-19 03:32:23 +08:00
|
|
|
guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_PPC64,
|
2011-12-13 07:39:33 +08:00
|
|
|
"/usr/bin/qemu-system-ppc64", NULL,
|
|
|
|
1, machines);
|
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, "qemu", NULL, NULL, 0, NULL))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 14:53:44 +08:00
|
|
|
error:
|
2011-12-13 07:39:33 +08:00
|
|
|
/* No way to free a guest? */
|
|
|
|
virCapabilitiesFreeMachines(machines, 1);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-03-14 12:49:43 +08:00
|
|
|
static int testQemuAddPPCGuest(virCapsPtr caps)
|
|
|
|
{
|
|
|
|
static const char *machine[] = { "g3beige",
|
|
|
|
"mac99",
|
|
|
|
"prep",
|
|
|
|
"ppce500v2" };
|
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
machines = virCapabilitiesAllocMachines(machine, 1);
|
|
|
|
if (!machines)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_PPC,
|
|
|
|
"/usr/bin/qemu-system-ppc", NULL,
|
|
|
|
1, machines);
|
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, "qemu", NULL, NULL, 0, NULL))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 14:53:44 +08:00
|
|
|
error:
|
2013-03-14 12:49:43 +08:00
|
|
|
/* No way to free a guest? */
|
|
|
|
virCapabilitiesFreeMachines(machines, 1);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-06-29 23:02:07 +08:00
|
|
|
static int testQemuAddS390Guest(virCapsPtr caps)
|
|
|
|
{
|
2013-03-05 23:44:23 +08:00
|
|
|
static const char *s390_machines[] = { "s390-virtio",
|
|
|
|
"s390-ccw-virtio" };
|
2012-06-29 23:02:07 +08:00
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
machines = virCapabilitiesAllocMachines(s390_machines,
|
|
|
|
ARRAY_CARDINALITY(s390_machines));
|
|
|
|
if (!machines)
|
|
|
|
goto error;
|
|
|
|
|
2012-12-19 03:32:23 +08:00
|
|
|
guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_S390X,
|
2012-06-29 23:02:07 +08:00
|
|
|
"/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;
|
|
|
|
|
2014-03-25 14:53:44 +08:00
|
|
|
error:
|
2012-06-29 23:02:07 +08:00
|
|
|
virCapabilitiesFreeMachines(machines, ARRAY_CARDINALITY(s390_machines));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-07-31 03:41:14 +08:00
|
|
|
static int testQemuAddArmGuest(virCapsPtr caps)
|
|
|
|
{
|
|
|
|
static const char *machines[] = { "vexpress-a9",
|
|
|
|
"vexpress-a15",
|
|
|
|
"versatilepb" };
|
|
|
|
virCapsGuestMachinePtr *capsmachines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
capsmachines = virCapabilitiesAllocMachines(machines,
|
|
|
|
ARRAY_CARDINALITY(machines));
|
|
|
|
if (!capsmachines)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_ARMV7L,
|
|
|
|
"/usr/bin/qemu-system-arm", NULL,
|
|
|
|
ARRAY_CARDINALITY(machines),
|
|
|
|
capsmachines);
|
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, "qemu", NULL, NULL, 0, NULL))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 14:53:44 +08:00
|
|
|
error:
|
2013-07-31 03:41:14 +08:00
|
|
|
virCapabilitiesFreeMachines(capsmachines, ARRAY_CARDINALITY(machines));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-01-02 18:42:56 +08:00
|
|
|
static int testQemuAddAARCH64Guest(virCapsPtr caps)
|
|
|
|
{
|
|
|
|
static const char *machines[] = { "virt"};
|
|
|
|
virCapsGuestMachinePtr *capsmachines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
capsmachines = virCapabilitiesAllocMachines(machines,
|
|
|
|
ARRAY_CARDINALITY(machines));
|
|
|
|
if (!capsmachines)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_AARCH64,
|
|
|
|
"/usr/bin/qemu-system-aarch64", NULL,
|
|
|
|
ARRAY_CARDINALITY(machines),
|
|
|
|
capsmachines);
|
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, "qemu", NULL, NULL, 0, NULL))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 14:53:44 +08:00
|
|
|
error:
|
2014-01-02 18:42:56 +08:00
|
|
|
virCapabilitiesFreeMachines(capsmachines, ARRAY_CARDINALITY(machines));
|
|
|
|
return -1;
|
|
|
|
}
|
2013-03-05 23:17:24 +08:00
|
|
|
|
2014-03-18 16:13:43 +08:00
|
|
|
virCapsPtr testQemuCapsInit(void)
|
|
|
|
{
|
2008-05-17 00:51:30 +08:00
|
|
|
virCapsPtr caps;
|
|
|
|
virCapsGuestPtr guest;
|
2010-04-22 23:00:30 +08:00
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
int nmachines = 0;
|
2008-05-17 00:51:30 +08:00
|
|
|
static const char *const xen_machines[] = {
|
|
|
|
"xenner"
|
|
|
|
};
|
2010-04-16 14:01:59 +08:00
|
|
|
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 */
|
2011-08-18 18:14:36 +08:00
|
|
|
0, /* mode */
|
2010-04-16 14:01:59 +08:00
|
|
|
0, /* match */
|
2012-12-19 03:32:23 +08:00
|
|
|
VIR_ARCH_X86_64, /* arch */
|
2010-04-16 14:01:59 +08:00
|
|
|
(char *) "core2duo", /* model */
|
2012-06-28 18:21:17 +08:00
|
|
|
NULL, /* vendor_id */
|
2011-12-21 21:27:16 +08:00
|
|
|
0, /* fallback */
|
2010-07-02 23:51:59 +08:00
|
|
|
(char *) "Intel", /* vendor */
|
2010-04-16 14:01:59 +08:00
|
|
|
1, /* sockets */
|
|
|
|
2, /* cores */
|
|
|
|
1, /* threads */
|
|
|
|
ARRAY_CARDINALITY(host_cpu_features), /* nfeatures */
|
2010-08-18 05:41:51 +08:00
|
|
|
ARRAY_CARDINALITY(host_cpu_features), /* nfeatures_max */
|
2012-04-06 10:04:23 +08:00
|
|
|
host_cpu_features, /* features */
|
|
|
|
0, /* ncells */
|
|
|
|
0, /* ncells_max */
|
|
|
|
NULL, /* cells */
|
|
|
|
0, /* cells_cpus */
|
2010-04-16 14:01:59 +08:00
|
|
|
};
|
2008-05-17 00:51:30 +08:00
|
|
|
|
2011-02-15 22:24:39 +08:00
|
|
|
if ((caps = virCapabilitiesNew(host_cpu.arch,
|
2008-05-17 00:51:30 +08:00
|
|
|
0, 0)) == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
2010-04-16 14:01:59 +08:00
|
|
|
if ((caps->host.cpu = virCPUDefCopy(&host_cpu)) == NULL ||
|
|
|
|
(machines = testQemuAllocMachines(&nmachines)) == NULL)
|
2009-07-24 01:31:34 +08:00
|
|
|
goto cleanup;
|
|
|
|
|
2012-12-19 03:32:23 +08:00
|
|
|
if ((guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_I686,
|
2008-05-17 00:51:30 +08:00
|
|
|
"/usr/bin/qemu", NULL,
|
2011-02-15 22:24:39 +08:00
|
|
|
nmachines, machines)) == NULL ||
|
|
|
|
!virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0))
|
2008-05-17 00:51:30 +08:00
|
|
|
goto cleanup;
|
2009-07-24 01:31:34 +08:00
|
|
|
machines = NULL;
|
|
|
|
|
2008-05-17 00:51:30 +08:00
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"qemu",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL) == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2009-09-10 18:19:12 +08:00
|
|
|
if ((machines = testQemuAllocNewerMachines(&nmachines)) == NULL)
|
2009-07-24 01:31:34 +08:00
|
|
|
goto cleanup;
|
|
|
|
|
2012-12-19 03:32:23 +08:00
|
|
|
if ((guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_X86_64,
|
2008-05-17 00:51:30 +08:00
|
|
|
"/usr/bin/qemu-system-x86_64", NULL,
|
2011-02-15 22:24:39 +08:00
|
|
|
nmachines, machines)) == NULL ||
|
|
|
|
!virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0))
|
2008-05-17 00:51:30 +08:00
|
|
|
goto cleanup;
|
2009-07-24 01:31:34 +08:00
|
|
|
machines = NULL;
|
|
|
|
|
2008-05-17 00:51:30 +08:00
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"qemu",
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL) == NULL)
|
|
|
|
goto cleanup;
|
2009-09-10 18:22:32 +08:00
|
|
|
|
|
|
|
if ((machines = testQemuAllocMachines(&nmachines)) == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2008-05-17 00:51:30 +08:00
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"kvm",
|
|
|
|
"/usr/bin/kvm",
|
|
|
|
NULL,
|
2009-09-10 18:22:32 +08:00
|
|
|
nmachines,
|
|
|
|
machines) == NULL)
|
2008-05-17 00:51:30 +08:00
|
|
|
goto cleanup;
|
2009-09-10 18:22:32 +08:00
|
|
|
machines = NULL;
|
2008-05-17 00:51:30 +08:00
|
|
|
|
2009-09-10 17:16:27 +08:00
|
|
|
nmachines = ARRAY_CARDINALITY(xen_machines);
|
2009-07-24 01:31:34 +08:00
|
|
|
if ((machines = virCapabilitiesAllocMachines(xen_machines, nmachines)) == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2012-12-19 03:32:23 +08:00
|
|
|
if ((guest = virCapabilitiesAddGuest(caps, "xen", VIR_ARCH_X86_64,
|
2008-05-17 00:51:30 +08:00
|
|
|
"/usr/bin/xenner", NULL,
|
2009-09-10 17:16:27 +08:00
|
|
|
nmachines, machines)) == NULL)
|
2008-05-17 00:51:30 +08:00
|
|
|
goto cleanup;
|
2009-07-24 01:31:34 +08:00
|
|
|
machines = NULL;
|
|
|
|
|
2008-05-17 00:51:30 +08:00
|
|
|
if (virCapabilitiesAddGuestDomain(guest,
|
|
|
|
"kvm",
|
|
|
|
"/usr/bin/kvm",
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL) == NULL)
|
|
|
|
goto cleanup;
|
|
|
|
|
2011-12-13 07:39:33 +08:00
|
|
|
if (testQemuAddPPC64Guest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2013-03-14 12:49:43 +08:00
|
|
|
if (testQemuAddPPCGuest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2012-06-29 23:02:07 +08:00
|
|
|
if (testQemuAddS390Guest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2013-07-31 03:41:14 +08:00
|
|
|
if (testQemuAddArmGuest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2014-01-02 18:42:56 +08:00
|
|
|
if (testQemuAddAARCH64Guest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2009-12-01 03:01:31 +08:00
|
|
|
if (virTestGetDebug()) {
|
2009-09-10 18:07:20 +08:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2008-05-17 00:51:30 +08:00
|
|
|
return caps;
|
|
|
|
|
2014-03-25 14:53:44 +08:00
|
|
|
cleanup:
|
2009-07-24 01:31:34 +08:00
|
|
|
virCapabilitiesFreeMachines(machines, nmachines);
|
2013-02-01 20:26:18 +08:00
|
|
|
virObjectUnref(caps);
|
2008-05-17 00:51:30 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2013-05-17 18:34:24 +08:00
|
|
|
|
|
|
|
|
|
|
|
static char *
|
2014-01-30 15:05:59 +08:00
|
|
|
testSCSIDeviceGetSgName(const char *sysfs_prefix ATTRIBUTE_UNUSED,
|
|
|
|
const char *adapter ATTRIBUTE_UNUSED,
|
2013-05-17 18:34:24 +08:00
|
|
|
unsigned int bus ATTRIBUTE_UNUSED,
|
|
|
|
unsigned int target ATTRIBUTE_UNUSED,
|
|
|
|
unsigned int unit ATTRIBUTE_UNUSED)
|
|
|
|
{
|
|
|
|
char *sg = NULL;
|
|
|
|
|
|
|
|
if (VIR_STRDUP(sg, "sg0") < 0)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return sg;
|
|
|
|
}
|
|
|
|
|
|
|
|
qemuBuildCommandLineCallbacks testCallbacks = {
|
|
|
|
.qemuGetSCSIDeviceSgName = testSCSIDeviceGetSgName,
|
|
|
|
};
|
2008-06-26 17:37:51 +08:00
|
|
|
#endif
|