mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-27 02:51:16 +00:00
More flexible setup of QEMU capabilities/emulators
This commit is contained in:
parent
0ad4ece725
commit
b75a469852
@ -1,3 +1,12 @@
|
|||||||
|
Fri Mar 20 11:21:40 GMT 2009 Daniel P. Berrange <berrange@redhat.com>
|
||||||
|
|
||||||
|
Make use of emulator binaries more flexible
|
||||||
|
* src/qemu_conf.h: Add flag for -no-kvm option
|
||||||
|
* src/qemu_conf.c: Allow i686 on x86_64 for KVM guests using
|
||||||
|
-cpu flag. Allow qemu-system-x86_64 to be used for 32-bit
|
||||||
|
guests. Allow KVM binary to be used for non-KVM guests using
|
||||||
|
-no-kvm flag
|
||||||
|
|
||||||
Thu Mar 19 15:25:40 CET 2009 Daniel Veillard <veillard@redhat.com>
|
Thu Mar 19 15:25:40 CET 2009 Daniel Veillard <veillard@redhat.com>
|
||||||
|
|
||||||
* docs/schemas/domain.rng: extend definition for security attributes
|
* docs/schemas/domain.rng: extend definition for security attributes
|
||||||
|
149
src/qemu_conf.c
149
src/qemu_conf.c
@ -211,6 +211,7 @@ struct qemu_arch_info {
|
|||||||
const char *const *machines;
|
const char *const *machines;
|
||||||
int nmachines;
|
int nmachines;
|
||||||
const char *binary;
|
const char *binary;
|
||||||
|
const char *altbinary;
|
||||||
const struct qemu_feature_flags *flags;
|
const struct qemu_feature_flags *flags;
|
||||||
int nflags;
|
int nflags;
|
||||||
};
|
};
|
||||||
@ -231,24 +232,24 @@ static const struct qemu_feature_flags const arch_info_x86_64_flags [] = {
|
|||||||
/* The archicture tables for supported QEMU archs */
|
/* The archicture tables for supported QEMU archs */
|
||||||
static const struct qemu_arch_info const arch_info_hvm[] = {
|
static const struct qemu_arch_info const arch_info_hvm[] = {
|
||||||
{ "i686", 32, arch_info_hvm_x86_machines, 2,
|
{ "i686", 32, arch_info_hvm_x86_machines, 2,
|
||||||
"/usr/bin/qemu", arch_info_i686_flags, 4 },
|
"/usr/bin/qemu", "/usr/bin/qemu-system-x86_64", arch_info_i686_flags, 4 },
|
||||||
{ "x86_64", 64, arch_info_hvm_x86_machines, 2,
|
{ "x86_64", 64, arch_info_hvm_x86_machines, 2,
|
||||||
"/usr/bin/qemu-system-x86_64", arch_info_x86_64_flags, 2 },
|
"/usr/bin/qemu-system-x86_64", NULL, arch_info_x86_64_flags, 2 },
|
||||||
{ "mips", 32, arch_info_hvm_mips_machines, 1,
|
{ "mips", 32, arch_info_hvm_mips_machines, 1,
|
||||||
"/usr/bin/qemu-system-mips", NULL, 0 },
|
"/usr/bin/qemu-system-mips", NULL, NULL, 0 },
|
||||||
{ "mipsel", 32, arch_info_hvm_mips_machines, 1,
|
{ "mipsel", 32, arch_info_hvm_mips_machines, 1,
|
||||||
"/usr/bin/qemu-system-mipsel", NULL, 0 },
|
"/usr/bin/qemu-system-mipsel", NULL, NULL, 0 },
|
||||||
{ "sparc", 32, arch_info_hvm_sparc_machines, 1,
|
{ "sparc", 32, arch_info_hvm_sparc_machines, 1,
|
||||||
"/usr/bin/qemu-system-sparc", NULL, 0 },
|
"/usr/bin/qemu-system-sparc", NULL, NULL, 0 },
|
||||||
{ "ppc", 32, arch_info_hvm_ppc_machines, 3,
|
{ "ppc", 32, arch_info_hvm_ppc_machines, 3,
|
||||||
"/usr/bin/qemu-system-ppc", NULL, 0 },
|
"/usr/bin/qemu-system-ppc", NULL, NULL, 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct qemu_arch_info const arch_info_xen[] = {
|
static const struct qemu_arch_info const arch_info_xen[] = {
|
||||||
{ "i686", 32, arch_info_xen_x86_machines, 1,
|
{ "i686", 32, arch_info_xen_x86_machines, 1,
|
||||||
"/usr/bin/xenner", arch_info_i686_flags, 4 },
|
"/usr/bin/xenner", NULL, arch_info_i686_flags, 4 },
|
||||||
{ "x86_64", 64, arch_info_xen_x86_machines, 1,
|
{ "x86_64", 64, arch_info_xen_x86_machines, 1,
|
||||||
"/usr/bin/xenner", arch_info_x86_64_flags, 2 },
|
"/usr/bin/xenner", NULL, arch_info_x86_64_flags, 2 },
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -257,43 +258,62 @@ qemudCapsInitGuest(virCapsPtr caps,
|
|||||||
const struct qemu_arch_info *info,
|
const struct qemu_arch_info *info,
|
||||||
int hvm) {
|
int hvm) {
|
||||||
virCapsGuestPtr guest;
|
virCapsGuestPtr guest;
|
||||||
int i, haskvm, hasbase, samearch;
|
int i;
|
||||||
|
int hasbase = 0;
|
||||||
|
int hasaltbase = 0;
|
||||||
|
int haskvm = 0;
|
||||||
|
int haskqemu = 0;
|
||||||
const char *kvmbin = NULL;
|
const char *kvmbin = NULL;
|
||||||
|
|
||||||
/* Check for existance of base emulator */
|
/* Check for existance of base emulator, or alternate base
|
||||||
|
* which can be used with magic cpu choice
|
||||||
|
*/
|
||||||
hasbase = (access(info->binary, X_OK) == 0);
|
hasbase = (access(info->binary, X_OK) == 0);
|
||||||
|
hasaltbase = (access(info->altbinary, X_OK) == 0);
|
||||||
|
|
||||||
samearch = STREQ(info->arch, hostmachine);
|
/* Can use acceleration for KVM/KQEMU if
|
||||||
if (samearch) {
|
* - host & guest arches match
|
||||||
|
* Or
|
||||||
|
* - hostarch is x86_64 and guest arch is i686
|
||||||
|
* The latter simply needs "-cpu qemu32"
|
||||||
|
*/
|
||||||
|
if (STREQ(info->arch, hostmachine) ||
|
||||||
|
(STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) {
|
||||||
const char *const kvmbins[] = { "/usr/bin/qemu-kvm", /* Fedora */
|
const char *const kvmbins[] = { "/usr/bin/qemu-kvm", /* Fedora */
|
||||||
"/usr/bin/kvm" }; /* Upstream .spec */
|
"/usr/bin/kvm" }; /* Upstream .spec */
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
|
for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
|
||||||
if ((haskvm = (access(kvmbins[i], X_OK) == 0))) {
|
if (access(kvmbins[i], X_OK) == 0 &&
|
||||||
|
access("/dev/kvm", F_OK) == 0) {
|
||||||
|
haskvm = 1;
|
||||||
kvmbin = kvmbins[i];
|
kvmbin = kvmbins[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
haskvm = 0;
|
if (access("/dev/kqemu", F_OK) == 0)
|
||||||
|
haskqemu = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasbase && !haskvm)
|
|
||||||
|
if (!hasbase && !hasaltbase && !haskvm)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* We register kvm as the base emulator too, since we can
|
||||||
|
* just give -no-kvm to disable acceleration if required */
|
||||||
if ((guest = virCapabilitiesAddGuest(caps,
|
if ((guest = virCapabilitiesAddGuest(caps,
|
||||||
hvm ? "hvm" : "xen",
|
hvm ? "hvm" : "xen",
|
||||||
info->arch,
|
info->arch,
|
||||||
info->wordsize,
|
info->wordsize,
|
||||||
info->binary,
|
(hasbase ? info->binary :
|
||||||
|
(hasaltbase ? info->altbinary : kvmbin)),
|
||||||
NULL,
|
NULL,
|
||||||
info->nmachines,
|
info->nmachines,
|
||||||
info->machines)) == NULL)
|
info->machines)) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (hvm) {
|
if (hvm) {
|
||||||
if (hasbase &&
|
if (virCapabilitiesAddGuestDomain(guest,
|
||||||
virCapabilitiesAddGuestDomain(guest,
|
|
||||||
"qemu",
|
"qemu",
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
@ -301,27 +321,23 @@ qemudCapsInitGuest(virCapsPtr caps,
|
|||||||
NULL) == NULL)
|
NULL) == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* If guest & host match, then we can accelerate */
|
if (haskqemu &&
|
||||||
if (samearch) {
|
virCapabilitiesAddGuestDomain(guest,
|
||||||
if (access("/dev/kqemu", F_OK) == 0 &&
|
"kqemu",
|
||||||
virCapabilitiesAddGuestDomain(guest,
|
NULL,
|
||||||
"kqemu",
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
NULL,
|
NULL) == NULL)
|
||||||
0,
|
return -1;
|
||||||
NULL) == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (access("/dev/kvm", F_OK) == 0 &&
|
if (haskvm &&
|
||||||
haskvm &&
|
virCapabilitiesAddGuestDomain(guest,
|
||||||
virCapabilitiesAddGuestDomain(guest,
|
"kvm",
|
||||||
"kvm",
|
kvmbin,
|
||||||
kvmbin,
|
NULL,
|
||||||
NULL,
|
0,
|
||||||
0,
|
NULL) == NULL)
|
||||||
NULL) == NULL)
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (virCapabilitiesAddGuestDomain(guest,
|
if (virCapabilitiesAddGuestDomain(guest,
|
||||||
"kvm",
|
"kvm",
|
||||||
@ -363,12 +379,14 @@ virCapsPtr qemudCapsInit(void) {
|
|||||||
if (virCapsInitNUMA(caps) < 0)
|
if (virCapsInitNUMA(caps) < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
|
/* First the pure HVM guests */
|
||||||
for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_hvm) ; i++)
|
for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_hvm) ; i++)
|
||||||
if (qemudCapsInitGuest(caps,
|
if (qemudCapsInitGuest(caps,
|
||||||
utsname.machine,
|
utsname.machine,
|
||||||
&arch_info_hvm[i], 1) < 0)
|
&arch_info_hvm[i], 1) < 0)
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
|
||||||
|
/* Then possibly the Xen paravirt guests (ie Xenner */
|
||||||
if (access("/usr/bin/xenner", X_OK) == 0 &&
|
if (access("/usr/bin/xenner", X_OK) == 0 &&
|
||||||
access("/dev/kvm", F_OK) == 0) {
|
access("/dev/kvm", F_OK) == 0) {
|
||||||
for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_xen) ; i++)
|
for (i = 0 ; i < ARRAY_CARDINALITY(arch_info_xen) ; i++)
|
||||||
@ -430,6 +448,8 @@ int qemudExtractVersionInfo(const char *qemu,
|
|||||||
|
|
||||||
if (strstr(help, "-no-kqemu"))
|
if (strstr(help, "-no-kqemu"))
|
||||||
flags |= QEMUD_CMD_FLAG_KQEMU;
|
flags |= QEMUD_CMD_FLAG_KQEMU;
|
||||||
|
if (strstr(help, "-no-kvm"))
|
||||||
|
flags |= QEMUD_CMD_FLAG_KVM;
|
||||||
if (strstr(help, "-no-reboot"))
|
if (strstr(help, "-no-reboot"))
|
||||||
flags |= QEMUD_CMD_FLAG_NO_REBOOT;
|
flags |= QEMUD_CMD_FLAG_NO_REBOOT;
|
||||||
if (strstr(help, "-name"))
|
if (strstr(help, "-name"))
|
||||||
@ -749,6 +769,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
char boot[VIR_DOMAIN_BOOT_LAST];
|
char boot[VIR_DOMAIN_BOOT_LAST];
|
||||||
struct utsname ut;
|
struct utsname ut;
|
||||||
int disableKQEMU = 0;
|
int disableKQEMU = 0;
|
||||||
|
int disableKVM = 0;
|
||||||
int qargc = 0, qarga = 0;
|
int qargc = 0, qarga = 0;
|
||||||
const char **qargv = NULL;
|
const char **qargv = NULL;
|
||||||
int qenvc = 0, qenva = 0;
|
int qenvc = 0, qenva = 0;
|
||||||
@ -757,6 +778,7 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
char uuid[VIR_UUID_STRING_BUFLEN];
|
char uuid[VIR_UUID_STRING_BUFLEN];
|
||||||
char domid[50];
|
char domid[50];
|
||||||
char *pidfile;
|
char *pidfile;
|
||||||
|
const char *cpu = NULL;
|
||||||
|
|
||||||
uname_normalize(&ut);
|
uname_normalize(&ut);
|
||||||
|
|
||||||
@ -789,9 +811,16 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
emulator = vm->def->emulator;
|
||||||
|
if (!emulator)
|
||||||
|
emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
|
||||||
|
if (!emulator)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
/* Need to explicitly disable KQEMU if
|
/* Need to explicitly disable KQEMU if
|
||||||
* 1. Arch matches host arch
|
* 1. Arch matches host arch
|
||||||
* 2. Guest is 'qemu'
|
* 2. Guest domain is 'qemu'
|
||||||
* 3. The qemu binary has the -no-kqemu flag
|
* 3. The qemu binary has the -no-kqemu flag
|
||||||
*/
|
*/
|
||||||
if ((qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
|
if ((qemuCmdFlags & QEMUD_CMD_FLAG_KQEMU) &&
|
||||||
@ -799,6 +828,34 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
|
vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
|
||||||
disableKQEMU = 1;
|
disableKQEMU = 1;
|
||||||
|
|
||||||
|
/* Need to explicitly disable KVM if
|
||||||
|
* 1. Arch matches host arch
|
||||||
|
* 2. Guest domain is 'qemu'
|
||||||
|
* 3. The qemu binary has the -no-kvm flag
|
||||||
|
*/
|
||||||
|
if ((qemuCmdFlags & QEMUD_CMD_FLAG_KVM) &&
|
||||||
|
STREQ(ut.machine, vm->def->os.arch) &&
|
||||||
|
vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
|
||||||
|
disableKVM = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to force a 32-bit guest CPU type if
|
||||||
|
*
|
||||||
|
* 1. guest OS is i686
|
||||||
|
* 2. host OS is x86_64
|
||||||
|
* 3. emulator is qemu-kvm or kvm
|
||||||
|
*
|
||||||
|
* Or
|
||||||
|
*
|
||||||
|
* 1. guest OS is i686
|
||||||
|
* 2. emulator is qemu-system-x86_64
|
||||||
|
*/
|
||||||
|
if (STREQ(vm->def->os.arch, "i686") &&
|
||||||
|
((STREQ(ut.machine, "x86_64") &&
|
||||||
|
strstr(emulator, "kvm")) ||
|
||||||
|
strstr(emulator, "x86_64")))
|
||||||
|
cpu = "qemu32";
|
||||||
|
|
||||||
#define ADD_ARG_SPACE \
|
#define ADD_ARG_SPACE \
|
||||||
do { \
|
do { \
|
||||||
if (qargc == qarga) { \
|
if (qargc == qarga) { \
|
||||||
@ -887,12 +944,6 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
ADD_ENV_COPY("LOGNAME");
|
ADD_ENV_COPY("LOGNAME");
|
||||||
ADD_ENV_COPY("TMPDIR");
|
ADD_ENV_COPY("TMPDIR");
|
||||||
|
|
||||||
emulator = vm->def->emulator;
|
|
||||||
if (!emulator)
|
|
||||||
emulator = virDomainDefDefaultEmulator(conn, vm->def, driver->caps);
|
|
||||||
if (!emulator)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ADD_ARG_LIT(emulator);
|
ADD_ARG_LIT(emulator);
|
||||||
ADD_ARG_LIT("-S");
|
ADD_ARG_LIT("-S");
|
||||||
|
|
||||||
@ -904,9 +955,15 @@ int qemudBuildCommandLine(virConnectPtr conn,
|
|||||||
ADD_ARG_LIT("-M");
|
ADD_ARG_LIT("-M");
|
||||||
ADD_ARG_LIT(vm->def->os.machine);
|
ADD_ARG_LIT(vm->def->os.machine);
|
||||||
}
|
}
|
||||||
|
if (cpu) {
|
||||||
|
ADD_ARG_LIT("-cpu");
|
||||||
|
ADD_ARG_LIT(cpu);
|
||||||
|
}
|
||||||
|
|
||||||
if (disableKQEMU)
|
if (disableKQEMU)
|
||||||
ADD_ARG_LIT("-no-kqemu");
|
ADD_ARG_LIT("-no-kqemu");
|
||||||
|
if (disableKVM)
|
||||||
|
ADD_ARG_LIT("-no-kvm");
|
||||||
ADD_ARG_LIT("-m");
|
ADD_ARG_LIT("-m");
|
||||||
ADD_ARG_LIT(memory);
|
ADD_ARG_LIT(memory);
|
||||||
ADD_ARG_LIT("-smp");
|
ADD_ARG_LIT("-smp");
|
||||||
|
@ -55,6 +55,7 @@ enum qemud_cmd_flags {
|
|||||||
QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP = (1 << 10), /* New migration syntax after merge to QEMU with TCP transport */
|
QEMUD_CMD_FLAG_MIGRATE_QEMU_TCP = (1 << 10), /* New migration syntax after merge to QEMU with TCP transport */
|
||||||
QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC = (1 << 11), /* New migration syntax after merge to QEMU with EXEC transport */
|
QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC = (1 << 11), /* New migration syntax after merge to QEMU with EXEC transport */
|
||||||
QEMUD_CMD_FLAG_DRIVE_CACHE_V2 = (1 << 12), /* Is the cache= flag wanting new v2 values */
|
QEMUD_CMD_FLAG_DRIVE_CACHE_V2 = (1 << 12), /* Is the cache= flag wanting new v2 values */
|
||||||
|
QEMUD_CMD_FLAG_KVM = (1 << 13), /* Whether KVM is compiled in */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Main driver state */
|
/* Main driver state */
|
||||||
|
Loading…
Reference in New Issue
Block a user