2008-05-22 16:18:40 +00:00
|
|
|
#include <config.h>
|
2008-06-26 09:37:51 +00:00
|
|
|
#ifdef WITH_QEMU
|
2010-03-09 19:22:22 +01:00
|
|
|
# include <stdlib.h>
|
2008-05-16 16:51:30 +00:00
|
|
|
|
2010-03-09 19:22:22 +01:00
|
|
|
# include "testutilsqemu.h"
|
2017-07-21 14:24:51 +02:00
|
|
|
# include "testutilshostcpus.h"
|
2010-03-09 19:22:22 +01:00
|
|
|
# include "testutils.h"
|
2012-12-12 18:06:53 +00:00
|
|
|
# include "viralloc.h"
|
2010-04-16 08:01:59 +02:00
|
|
|
# include "cpu_conf.h"
|
2010-04-20 17:22:49 -04:00
|
|
|
# include "qemu/qemu_driver.h"
|
2010-12-17 16:41:51 +00:00
|
|
|
# include "qemu/qemu_domain.h"
|
2017-03-22 16:22:15 +01:00
|
|
|
# define __QEMU_CAPSPRIV_H_ALLOW__
|
2015-09-09 17:03:14 +03:00
|
|
|
# include "qemu/qemu_capspriv.h"
|
2013-05-03 14:52:21 +02:00
|
|
|
# include "virstring.h"
|
2017-07-19 17:01:56 +02:00
|
|
|
# include "virfilecache.h"
|
2013-05-03 14:52:21 +02:00
|
|
|
|
|
|
|
# define VIR_FROM_THIS VIR_FROM_QEMU
|
2008-05-16 16:51:30 +00:00
|
|
|
|
2015-03-23 17:19:28 +01:00
|
|
|
virCPUDefPtr cpuDefault;
|
|
|
|
virCPUDefPtr cpuHaswell;
|
2016-09-13 22:27:09 +02:00
|
|
|
virCPUDefPtr cpuPower8;
|
2017-05-17 16:39:16 +02:00
|
|
|
virCPUDefPtr cpuPower9;
|
2015-03-23 17:19:28 +01:00
|
|
|
|
2016-12-20 10:10:05 +01:00
|
|
|
typedef enum {
|
2017-04-06 18:33:52 +02:00
|
|
|
TEST_UTILS_QEMU_BIN_I686,
|
|
|
|
TEST_UTILS_QEMU_BIN_X86_64,
|
|
|
|
TEST_UTILS_QEMU_BIN_AARCH64,
|
|
|
|
TEST_UTILS_QEMU_BIN_ARM,
|
|
|
|
TEST_UTILS_QEMU_BIN_PPC64,
|
|
|
|
TEST_UTILS_QEMU_BIN_PPC,
|
|
|
|
TEST_UTILS_QEMU_BIN_S390X
|
2016-12-20 10:10:05 +01:00
|
|
|
} QEMUBinType;
|
|
|
|
|
|
|
|
static const char *QEMUBinList[] = {
|
2017-04-06 18:33:52 +02:00
|
|
|
"/usr/bin/qemu-system-i686",
|
2016-12-20 10:10:05 +01:00
|
|
|
"/usr/bin/qemu-system-x86_64",
|
|
|
|
"/usr/bin/qemu-system-aarch64",
|
|
|
|
"/usr/bin/qemu-system-arm",
|
|
|
|
"/usr/bin/qemu-system-ppc64",
|
|
|
|
"/usr/bin/qemu-system-ppc",
|
|
|
|
"/usr/bin/qemu-system-s390x"
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2009-09-10 10:16:27 +01: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 11:19:12 +01: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 14:52:21 +02:00
|
|
|
if (VIR_STRDUP(canonical, x86_machines[0]) < 0)
|
2009-09-10 11:19:12 +01: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 14:56:20 +01:00
|
|
|
|
2016-12-19 23:52:33 +01:00
|
|
|
static int
|
|
|
|
testQemuAddI686Guest(virCapsPtr caps)
|
|
|
|
{
|
|
|
|
int nmachines = 0;
|
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
if (!(machines = testQemuAllocMachines(&nmachines)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(guest = virCapabilitiesAddGuest(caps,
|
|
|
|
VIR_DOMAIN_OSTYPE_HVM,
|
|
|
|
VIR_ARCH_I686,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_I686],
|
2016-12-19 23:52:33 +01:00
|
|
|
NULL,
|
|
|
|
nmachines,
|
|
|
|
machines)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
machines = NULL;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest,
|
|
|
|
VIR_DOMAIN_VIRT_QEMU,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(machines = testQemuAllocMachines(&nmachines)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest,
|
|
|
|
VIR_DOMAIN_VIRT_KVM,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_I686],
|
2016-12-19 23:52:33 +01:00
|
|
|
NULL,
|
|
|
|
nmachines,
|
|
|
|
machines))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virCapabilitiesFreeMachines(machines, nmachines);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
testQemuAddX86_64Guest(virCapsPtr caps)
|
|
|
|
{
|
|
|
|
int nmachines = 0;
|
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
if (!(machines = testQemuAllocNewerMachines(&nmachines)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(guest = virCapabilitiesAddGuest(caps,
|
|
|
|
VIR_DOMAIN_OSTYPE_HVM,
|
|
|
|
VIR_ARCH_X86_64,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_X86_64],
|
2016-12-19 23:52:33 +01:00
|
|
|
NULL,
|
|
|
|
nmachines,
|
|
|
|
machines)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestFeature(guest, "cpuselection", true, false))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
machines = NULL;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest,
|
|
|
|
VIR_DOMAIN_VIRT_QEMU,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!(machines = testQemuAllocMachines(&nmachines)))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest,
|
|
|
|
VIR_DOMAIN_VIRT_KVM,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_X86_64],
|
2016-12-19 23:52:33 +01:00
|
|
|
NULL,
|
|
|
|
nmachines,
|
|
|
|
machines))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
machines = NULL;
|
|
|
|
|
|
|
|
if (!virCapabilitiesAddGuestDomain(guest,
|
|
|
|
VIR_DOMAIN_VIRT_KVM,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_X86_64],
|
2016-12-19 23:52:33 +01:00
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
NULL))
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virCapabilitiesFreeMachines(machines, nmachines);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-13 10:39:33 +11:00
|
|
|
static int testQemuAddPPC64Guest(virCapsPtr caps)
|
|
|
|
{
|
|
|
|
static const char *machine[] = { "pseries" };
|
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
machines = virCapabilitiesAllocMachines(machine, 1);
|
|
|
|
if (!machines)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:09:16 -04:00
|
|
|
guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_PPC64,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_PPC64],
|
2016-12-20 10:10:05 +01:00
|
|
|
NULL, 1, machines);
|
2011-12-13 10:39:33 +11:00
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:38:10 -04:00
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
|
2011-12-13 10:39:33 +11:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 07:53:44 +01:00
|
|
|
error:
|
2011-12-13 10:39:33 +11:00
|
|
|
/* No way to free a guest? */
|
|
|
|
virCapabilitiesFreeMachines(machines, 1);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-02-26 22:45:54 +05:30
|
|
|
static int testQemuAddPPC64LEGuest(virCapsPtr caps)
|
|
|
|
{
|
|
|
|
static const char *machine[] = { "pseries" };
|
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
machines = virCapabilitiesAllocMachines(machine, 1);
|
|
|
|
if (!machines)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:09:16 -04:00
|
|
|
guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_PPC64LE,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_PPC64],
|
2016-12-20 10:10:05 +01:00
|
|
|
NULL, 1, machines);
|
2015-02-26 22:45:54 +05:30
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:38:10 -04:00
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
|
2015-02-26 22:45:54 +05:30
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
|
|
|
/* 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",
|
2014-05-27 13:44:13 +08:00
|
|
|
"ppce500" };
|
2013-03-14 12:49:43 +08:00
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
machines = virCapabilitiesAllocMachines(machine, 1);
|
|
|
|
if (!machines)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:09:16 -04:00
|
|
|
guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_PPC,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_PPC],
|
2016-12-20 10:10:05 +01:00
|
|
|
NULL, 1, machines);
|
2013-03-14 12:49:43 +08:00
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:38:10 -04:00
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
|
2013-03-14 12:49:43 +08:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 07:53:44 +01:00
|
|
|
error:
|
2013-03-14 12:49:43 +08:00
|
|
|
/* No way to free a guest? */
|
|
|
|
virCapabilitiesFreeMachines(machines, 1);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2012-06-29 17:02:07 +02:00
|
|
|
static int testQemuAddS390Guest(virCapsPtr caps)
|
|
|
|
{
|
2013-03-05 16:44:23 +01:00
|
|
|
static const char *s390_machines[] = { "s390-virtio",
|
|
|
|
"s390-ccw-virtio" };
|
2012-06-29 17:02:07 +02:00
|
|
|
virCapsGuestMachinePtr *machines = NULL;
|
|
|
|
virCapsGuestPtr guest;
|
|
|
|
|
|
|
|
machines = virCapabilitiesAllocMachines(s390_machines,
|
|
|
|
ARRAY_CARDINALITY(s390_machines));
|
|
|
|
if (!machines)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:09:16 -04:00
|
|
|
guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_S390X,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_S390X],
|
2016-12-20 10:10:05 +01:00
|
|
|
NULL,
|
2012-06-29 17:02:07 +02:00
|
|
|
ARRAY_CARDINALITY(s390_machines),
|
|
|
|
machines);
|
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:38:10 -04:00
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
|
2012-06-29 17:02:07 +02:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 07:53:44 +01:00
|
|
|
error:
|
2012-06-29 17:02:07 +02:00
|
|
|
virCapabilitiesFreeMachines(machines, ARRAY_CARDINALITY(s390_machines));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2013-07-30 15:41:14 -04: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;
|
|
|
|
|
2015-04-17 18:09:16 -04:00
|
|
|
guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_ARMV7L,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_ARM],
|
2016-12-20 10:10:05 +01:00
|
|
|
NULL,
|
2013-07-30 15:41:14 -04:00
|
|
|
ARRAY_CARDINALITY(machines),
|
|
|
|
capsmachines);
|
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:38:10 -04:00
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
|
2013-07-30 15:41:14 -04:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 07:53:44 +01:00
|
|
|
error:
|
2013-07-30 15:41:14 -04:00
|
|
|
virCapabilitiesFreeMachines(capsmachines, ARRAY_CARDINALITY(machines));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2014-01-02 16:12:56 +05:30
|
|
|
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;
|
|
|
|
|
2015-04-17 18:09:16 -04:00
|
|
|
guest = virCapabilitiesAddGuest(caps, VIR_DOMAIN_OSTYPE_HVM, VIR_ARCH_AARCH64,
|
2017-04-06 18:33:52 +02:00
|
|
|
QEMUBinList[TEST_UTILS_QEMU_BIN_AARCH64],
|
2016-12-20 10:10:05 +01:00
|
|
|
NULL,
|
2014-01-02 16:12:56 +05:30
|
|
|
ARRAY_CARDINALITY(machines),
|
|
|
|
capsmachines);
|
|
|
|
if (!guest)
|
|
|
|
goto error;
|
|
|
|
|
2015-04-17 18:38:10 -04:00
|
|
|
if (!virCapabilitiesAddGuestDomain(guest, VIR_DOMAIN_VIRT_QEMU, NULL, NULL, 0, NULL))
|
2014-01-02 16:12:56 +05:30
|
|
|
goto error;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 07:53:44 +01:00
|
|
|
error:
|
2014-01-02 16:12:56 +05:30
|
|
|
virCapabilitiesFreeMachines(capsmachines, ARRAY_CARDINALITY(machines));
|
|
|
|
return -1;
|
|
|
|
}
|
2013-03-05 16:17:24 +01:00
|
|
|
|
2014-03-18 09:13:43 +01:00
|
|
|
virCapsPtr testQemuCapsInit(void)
|
|
|
|
{
|
2008-05-16 16:51:30 +00:00
|
|
|
virCapsPtr caps;
|
|
|
|
|
2015-03-23 17:19:28 +01:00
|
|
|
if (!(caps = virCapabilitiesNew(VIR_ARCH_X86_64, false, false)))
|
2008-05-16 16:51:30 +00:00
|
|
|
return NULL;
|
|
|
|
|
2014-09-03 19:06:55 +02:00
|
|
|
/* Add dummy 'none' security_driver. This is equal to setting
|
|
|
|
* security_driver = "none" in qemu.conf. */
|
|
|
|
if (VIR_ALLOC_N(caps->host.secModels, 1) < 0)
|
|
|
|
goto cleanup;
|
|
|
|
caps->host.nsecModels = 1;
|
|
|
|
|
|
|
|
if (VIR_STRDUP(caps->host.secModels[0].model, "none") < 0 ||
|
|
|
|
VIR_STRDUP(caps->host.secModels[0].doi, "0") < 0)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-03-23 17:19:28 +01:00
|
|
|
if (!(cpuDefault = virCPUDefCopy(&cpuDefaultData)) ||
|
2016-09-13 22:27:09 +02:00
|
|
|
!(cpuHaswell = virCPUDefCopy(&cpuHaswellData)) ||
|
2017-05-17 16:39:16 +02:00
|
|
|
!(cpuPower8 = virCPUDefCopy(&cpuPower8Data)) ||
|
|
|
|
!(cpuPower9 = virCPUDefCopy(&cpuPower9Data)))
|
2015-03-23 17:19:28 +01:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-08-04 13:16:55 +02:00
|
|
|
qemuTestSetHostCPU(caps, NULL);
|
2015-03-23 17:19:28 +01:00
|
|
|
|
2015-07-24 16:06:33 +02:00
|
|
|
caps->host.nnumaCell_max = 4;
|
|
|
|
|
2016-12-19 23:52:33 +01:00
|
|
|
if (testQemuAddI686Guest(caps) < 0)
|
2008-05-16 16:51:30 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2016-12-19 23:52:33 +01:00
|
|
|
if (testQemuAddX86_64Guest(caps) < 0)
|
2008-05-16 16:51:30 +00:00
|
|
|
goto cleanup;
|
|
|
|
|
2011-12-13 10:39:33 +11:00
|
|
|
if (testQemuAddPPC64Guest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-02-26 22:45:54 +05:30
|
|
|
if (testQemuAddPPC64LEGuest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2013-03-14 12:49:43 +08:00
|
|
|
if (testQemuAddPPCGuest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2012-06-29 17:02:07 +02:00
|
|
|
if (testQemuAddS390Guest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2013-07-30 15:41:14 -04:00
|
|
|
if (testQemuAddArmGuest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2014-01-02 16:12:56 +05:30
|
|
|
if (testQemuAddAARCH64Guest(caps))
|
|
|
|
goto cleanup;
|
|
|
|
|
2009-11-30 19:01:31 +00:00
|
|
|
if (virTestGetDebug()) {
|
2009-09-10 11:07:20 +01:00
|
|
|
char *caps_str;
|
|
|
|
|
|
|
|
caps_str = virCapabilitiesFormatXML(caps);
|
|
|
|
if (!caps_str)
|
|
|
|
goto cleanup;
|
|
|
|
|
2015-04-23 13:38:00 -04:00
|
|
|
VIR_TEST_DEBUG("QEMU driver capabilities:\n%s", caps_str);
|
2009-09-10 11:07:20 +01:00
|
|
|
|
|
|
|
VIR_FREE(caps_str);
|
|
|
|
}
|
|
|
|
|
2008-05-16 16:51:30 +00:00
|
|
|
return caps;
|
|
|
|
|
2014-03-25 07:53:44 +01:00
|
|
|
cleanup:
|
2016-08-04 13:16:55 +02:00
|
|
|
caps->host.cpu = NULL;
|
|
|
|
virCPUDefFree(cpuDefault);
|
|
|
|
virCPUDefFree(cpuHaswell);
|
2016-09-13 22:27:09 +02:00
|
|
|
virCPUDefFree(cpuPower8);
|
2013-02-01 12:26:18 +00:00
|
|
|
virObjectUnref(caps);
|
2008-05-16 16:51:30 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2013-05-17 18:34:24 +08:00
|
|
|
|
|
|
|
|
2016-08-04 13:16:55 +02:00
|
|
|
void
|
|
|
|
qemuTestSetHostArch(virCapsPtr caps,
|
|
|
|
virArch arch)
|
|
|
|
{
|
|
|
|
if (arch == VIR_ARCH_NONE)
|
|
|
|
arch = VIR_ARCH_X86_64;
|
|
|
|
caps->host.arch = arch;
|
|
|
|
qemuTestSetHostCPU(caps, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
qemuTestSetHostCPU(virCapsPtr caps,
|
|
|
|
virCPUDefPtr cpu)
|
|
|
|
{
|
|
|
|
virArch arch = caps->host.arch;
|
|
|
|
|
|
|
|
if (!cpu) {
|
|
|
|
if (ARCH_IS_X86(arch))
|
|
|
|
cpu = cpuDefault;
|
2016-09-13 22:27:09 +02:00
|
|
|
else if (ARCH_IS_PPC64(arch))
|
|
|
|
cpu = cpuPower8;
|
2016-08-04 13:16:55 +02:00
|
|
|
}
|
|
|
|
|
2017-07-21 14:24:51 +02:00
|
|
|
if (cpu) {
|
2016-08-04 13:16:55 +02:00
|
|
|
caps->host.arch = cpu->arch;
|
2017-07-21 14:24:51 +02:00
|
|
|
if (cpu->model)
|
|
|
|
setenv("VIR_TEST_MOCK_FAKE_HOST_CPU", cpu->model, 1);
|
|
|
|
else
|
|
|
|
unsetenv("VIR_TEST_MOCK_FAKE_HOST_CPU");
|
|
|
|
}
|
2016-08-04 13:16:55 +02:00
|
|
|
caps->host.cpu = cpu;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-06-27 16:39:27 +02:00
|
|
|
virQEMUCapsPtr
|
2016-06-15 14:35:18 +02:00
|
|
|
qemuTestParseCapabilities(virCapsPtr caps,
|
|
|
|
const char *capsFile)
|
2014-06-27 16:39:27 +02:00
|
|
|
{
|
|
|
|
virQEMUCapsPtr qemuCaps = NULL;
|
|
|
|
|
2017-07-21 15:09:54 +02:00
|
|
|
if (!caps)
|
|
|
|
return NULL;
|
|
|
|
|
2016-04-28 17:02:38 +02:00
|
|
|
if (!(qemuCaps = virQEMUCapsNew()) ||
|
2017-07-21 15:09:54 +02:00
|
|
|
virQEMUCapsLoadCache(caps->host.arch, qemuCaps, capsFile) < 0)
|
2014-06-27 16:39:27 +02:00
|
|
|
goto error;
|
|
|
|
|
|
|
|
return qemuCaps;
|
|
|
|
|
|
|
|
error:
|
|
|
|
virObjectUnref(qemuCaps);
|
|
|
|
return NULL;
|
|
|
|
}
|
2015-09-15 08:16:02 +02:00
|
|
|
|
|
|
|
void qemuTestDriverFree(virQEMUDriver *driver)
|
|
|
|
{
|
2015-09-22 16:12:39 +02:00
|
|
|
virMutexDestroy(&driver->lock);
|
2017-03-06 08:27:23 +01:00
|
|
|
if (driver->config) {
|
|
|
|
virFileDeleteTree(driver->config->stateDir);
|
|
|
|
virFileDeleteTree(driver->config->configDir);
|
|
|
|
}
|
2017-07-19 17:01:56 +02:00
|
|
|
virObjectUnref(driver->qemuCapsCache);
|
2015-09-15 08:16:02 +02:00
|
|
|
virObjectUnref(driver->xmlopt);
|
|
|
|
virObjectUnref(driver->caps);
|
|
|
|
virObjectUnref(driver->config);
|
2016-07-29 18:06:51 +02:00
|
|
|
virObjectUnref(driver->securityManager);
|
2015-09-15 08:16:02 +02:00
|
|
|
}
|
|
|
|
|
2017-07-19 17:01:56 +02:00
|
|
|
int qemuTestCapsCacheInsert(virFileCachePtr cache,
|
2015-09-09 17:03:14 +03:00
|
|
|
virQEMUCapsPtr caps)
|
|
|
|
{
|
2017-04-11 14:02:06 +02:00
|
|
|
size_t i;
|
|
|
|
virQEMUCapsPtr tmpCaps;
|
2015-09-09 17:03:14 +03:00
|
|
|
|
|
|
|
if (caps) {
|
2017-04-11 14:02:06 +02:00
|
|
|
tmpCaps = caps;
|
2015-09-09 17:03:14 +03:00
|
|
|
} else {
|
2017-04-11 14:02:06 +02:00
|
|
|
if (!(tmpCaps = virQEMUCapsNew()))
|
2015-09-09 17:03:14 +03:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
|
|
|
|
2017-04-11 14:02:06 +02:00
|
|
|
for (i = 0; i < ARRAY_CARDINALITY(QEMUBinList); i++) {
|
|
|
|
virObjectRef(tmpCaps);
|
2017-07-19 17:01:56 +02:00
|
|
|
if (virFileCacheInsertData(cache, QEMUBinList[i], tmpCaps) < 0) {
|
2017-04-11 14:02:06 +02:00
|
|
|
virObjectUnref(tmpCaps);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2015-09-09 17:03:14 +03:00
|
|
|
|
2017-04-11 14:02:06 +02:00
|
|
|
if (!caps)
|
|
|
|
virObjectUnref(tmpCaps);
|
2015-09-09 17:03:14 +03:00
|
|
|
|
2017-04-11 14:02:06 +02:00
|
|
|
return 0;
|
2015-09-09 17:03:14 +03:00
|
|
|
}
|
|
|
|
|
2017-04-11 14:02:06 +02:00
|
|
|
|
2017-03-06 08:27:23 +01:00
|
|
|
# define STATEDIRTEMPLATE abs_builddir "/qemustatedir-XXXXXX"
|
|
|
|
# define CONFIGDIRTEMPLATE abs_builddir "/qemuconfigdir-XXXXXX"
|
|
|
|
|
2015-09-15 08:16:02 +02:00
|
|
|
int qemuTestDriverInit(virQEMUDriver *driver)
|
|
|
|
{
|
2016-03-23 16:19:26 +01:00
|
|
|
virSecurityManagerPtr mgr = NULL;
|
2017-03-06 08:27:23 +01:00
|
|
|
char statedir[] = STATEDIRTEMPLATE;
|
|
|
|
char configdir[] = CONFIGDIRTEMPLATE;
|
2016-03-23 16:19:26 +01:00
|
|
|
|
2016-01-18 09:11:19 +01:00
|
|
|
memset(driver, 0, sizeof(*driver));
|
|
|
|
|
2015-09-22 16:12:39 +02:00
|
|
|
if (virMutexInit(&driver->lock) < 0)
|
|
|
|
return -1;
|
|
|
|
|
2015-09-15 08:16:02 +02:00
|
|
|
driver->config = virQEMUDriverConfigNew(false);
|
|
|
|
if (!driver->config)
|
2015-09-22 16:12:39 +02:00
|
|
|
goto error;
|
2015-09-15 08:16:02 +02:00
|
|
|
|
2017-03-06 08:27:23 +01:00
|
|
|
/* Do this early so that qemuTestDriverFree() doesn't see (unlink) the real
|
|
|
|
* dirs. */
|
|
|
|
VIR_FREE(driver->config->stateDir);
|
|
|
|
VIR_FREE(driver->config->configDir);
|
|
|
|
|
2016-03-15 13:54:24 +01:00
|
|
|
/* Overwrite some default paths so it's consistent for tests. */
|
|
|
|
VIR_FREE(driver->config->libDir);
|
|
|
|
VIR_FREE(driver->config->channelTargetDir);
|
|
|
|
if (VIR_STRDUP(driver->config->libDir, "/tmp/lib") < 0 ||
|
|
|
|
VIR_STRDUP(driver->config->channelTargetDir, "/tmp/channel") < 0)
|
|
|
|
goto error;
|
|
|
|
|
2017-03-06 08:27:23 +01:00
|
|
|
if (!mkdtemp(statedir)) {
|
|
|
|
virFilePrintf(stderr, "Cannot create fake stateDir");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_STRDUP(driver->config->stateDir, statedir) < 0) {
|
|
|
|
rmdir(statedir);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!mkdtemp(configdir)) {
|
|
|
|
virFilePrintf(stderr, "Cannot create fake configDir");
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VIR_STRDUP(driver->config->configDir, configdir) < 0) {
|
|
|
|
rmdir(configdir);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2015-09-15 08:16:02 +02:00
|
|
|
driver->caps = testQemuCapsInit();
|
|
|
|
if (!driver->caps)
|
|
|
|
goto error;
|
|
|
|
|
2015-09-09 17:03:15 +03:00
|
|
|
/* Using /dev/null for libDir and cacheDir automatically produces errors
|
|
|
|
* upon attempt to use any of them */
|
|
|
|
driver->qemuCapsCache = virQEMUCapsCacheNew("/dev/null", "/dev/null", 0, 0);
|
|
|
|
if (!driver->qemuCapsCache)
|
|
|
|
goto error;
|
|
|
|
|
2015-09-15 08:16:02 +02:00
|
|
|
driver->xmlopt = virQEMUDriverCreateXMLConf(driver);
|
|
|
|
if (!driver->xmlopt)
|
|
|
|
goto error;
|
|
|
|
|
2017-04-11 14:02:06 +02:00
|
|
|
if (qemuTestCapsCacheInsert(driver->qemuCapsCache, NULL) < 0)
|
2015-09-09 17:03:15 +03:00
|
|
|
goto error;
|
|
|
|
|
2016-03-23 16:19:26 +01:00
|
|
|
if (!(mgr = virSecurityManagerNew("none", "qemu",
|
|
|
|
VIR_SECURITY_MANAGER_PRIVILEGED)))
|
|
|
|
goto error;
|
|
|
|
if (!(driver->securityManager = virSecurityManagerNewStack(mgr)))
|
|
|
|
goto error;
|
|
|
|
|
2015-09-15 08:16:02 +02:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
error:
|
2016-03-23 16:19:26 +01:00
|
|
|
virObjectUnref(mgr);
|
2015-09-15 08:16:02 +02:00
|
|
|
qemuTestDriverFree(driver);
|
|
|
|
return -1;
|
|
|
|
}
|
2015-09-09 17:03:14 +03:00
|
|
|
|
2016-05-10 11:35:43 +02:00
|
|
|
int
|
|
|
|
testQemuCapsSetGIC(virQEMUCapsPtr qemuCaps,
|
|
|
|
int gic)
|
|
|
|
{
|
|
|
|
virGICCapability *gicCapabilities = NULL;
|
|
|
|
size_t ngicCapabilities = 0;
|
|
|
|
int ret = -1;
|
|
|
|
|
|
|
|
if (VIR_ALLOC_N(gicCapabilities, 2) < 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
# define IMPL_BOTH \
|
|
|
|
VIR_GIC_IMPLEMENTATION_KERNEL|VIR_GIC_IMPLEMENTATION_EMULATED
|
|
|
|
|
|
|
|
if (gic & GIC_V2) {
|
|
|
|
gicCapabilities[ngicCapabilities].version = VIR_GIC_VERSION_2;
|
|
|
|
gicCapabilities[ngicCapabilities].implementation = IMPL_BOTH;
|
|
|
|
ngicCapabilities++;
|
|
|
|
}
|
|
|
|
if (gic & GIC_V3) {
|
|
|
|
gicCapabilities[ngicCapabilities].version = VIR_GIC_VERSION_3;
|
|
|
|
gicCapabilities[ngicCapabilities].implementation = IMPL_BOTH;
|
|
|
|
ngicCapabilities++;
|
|
|
|
}
|
|
|
|
|
|
|
|
# undef IMPL_BOTH
|
|
|
|
|
|
|
|
virQEMUCapsSetGICCapabilities(qemuCaps,
|
|
|
|
gicCapabilities, ngicCapabilities);
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2008-06-26 09:37:51 +00:00
|
|
|
#endif
|