qemu: Use -machine accel=tcg|kvm when available

This is a better interface to choose accelerator than guessing whether
we should enable or disable kvm to get the right one.
This commit is contained in:
Jiri Denemark 2013-04-23 16:17:08 +02:00
parent cfe24c1a18
commit 6d4804858e
7 changed files with 111 additions and 63 deletions

View File

@ -5274,11 +5274,80 @@ no_memory:
goto cleanup;
}
static int
qemuBuildObsoleteAccelArg(virCommandPtr cmd,
const virDomainDefPtr def,
virQEMUCapsPtr qemuCaps)
{
int disableKQEMU = 0;
int enableKQEMU = 0;
int disableKVM = 0;
int enableKVM = 0;
switch (def->virtType) {
case VIR_DOMAIN_VIRT_QEMU:
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU))
disableKQEMU = 1;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
disableKVM = 1;
break;
case VIR_DOMAIN_VIRT_KQEMU:
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
disableKVM = 1;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KQEMU)) {
enableKQEMU = 1;
} else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("the QEMU binary does not support kqemu"));
return -1;
}
break;
case VIR_DOMAIN_VIRT_KVM:
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU))
disableKQEMU = 1;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) {
enableKVM = 1;
} else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("the QEMU binary does not support kvm"));
return -1;
}
break;
case VIR_DOMAIN_VIRT_XEN:
/* XXX better check for xenner */
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("the QEMU binary does not support %s"),
virDomainVirtTypeToString(def->virtType));
return -1;
}
if (disableKQEMU)
virCommandAddArg(cmd, "-no-kqemu");
else if (enableKQEMU)
virCommandAddArgList(cmd, "-enable-kqemu", "-kernel-kqemu", NULL);
if (disableKVM)
virCommandAddArg(cmd, "-no-kvm");
if (enableKVM)
virCommandAddArg(cmd, "-enable-kvm");
return 0;
}
static int
qemuBuildMachineArgStr(virCommandPtr cmd,
const virDomainDefPtr def,
virQEMUCapsPtr qemuCaps)
{
bool obsoleteAccel = false;
/* This should *never* be NULL, since we always provide
* a machine in the capabilities data for QEMU. So this
* check is just here as a safety in case the unexpected
@ -5297,12 +5366,20 @@ qemuBuildMachineArgStr(virCommandPtr cmd,
"with this QEMU binary"));
return -1;
}
obsoleteAccel = true;
} else {
virBuffer buf = VIR_BUFFER_INITIALIZER;
virCommandAddArg(cmd, "-machine");
virBufferAdd(&buf, def->os.machine, -1);
if (def->virtType == VIR_DOMAIN_VIRT_QEMU)
virBufferAddLit(&buf, ",accel=tcg");
else if (def->virtType == VIR_DOMAIN_VIRT_KVM)
virBufferAddLit(&buf, ",accel=kvm");
else
obsoleteAccel = true;
/* To avoid the collision of creating USB controllers when calling
* machine->init in QEMU, it needs to set usb=off
*/
@ -5325,6 +5402,10 @@ qemuBuildMachineArgStr(virCommandPtr cmd,
virCommandAddArgBuffer(cmd, &buf);
}
if (obsoleteAccel &&
qemuBuildObsoleteAccelArg(cmd, def, qemuCaps) < 0)
return -1;
return 0;
}
@ -5771,10 +5852,6 @@ qemuBuildCommandLine(virConnectPtr conn,
enum virNetDevVPortProfileOp vmop)
{
int i, j;
int disableKQEMU = 0;
int enableKQEMU = 0;
int disableKVM = 0;
int enableKVM = 0;
const char *emulator;
char uuid[VIR_UUID_STRING_BUFLEN];
char *cpu;
@ -5819,53 +5896,6 @@ qemuBuildCommandLine(virConnectPtr conn,
(def->virtType == VIR_DOMAIN_VIRT_QEMU))
virQEMUCapsClear(qemuCaps, QEMU_CAPS_DRIVE_BOOT);
switch (def->virtType) {
case VIR_DOMAIN_VIRT_QEMU:
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU))
disableKQEMU = 1;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
disableKVM = 1;
break;
case VIR_DOMAIN_VIRT_KQEMU:
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
disableKVM = 1;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KQEMU)) {
enableKQEMU = 1;
} else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("the QEMU binary %s does not support kqemu"),
emulator);
goto error;
}
break;
case VIR_DOMAIN_VIRT_KVM:
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KQEMU))
disableKQEMU = 1;
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ENABLE_KVM)) {
enableKVM = 1;
} else if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("the QEMU binary %s does not support kvm"),
emulator);
goto error;
}
break;
case VIR_DOMAIN_VIRT_XEN:
/* XXX better check for xenner */
break;
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("the QEMU binary %s does not support %s"),
emulator, virDomainVirtTypeToString(def->virtType));
break;
}
cmd = virCommandNew(emulator);
virCommandAddEnvPassCommon(cmd);
@ -5885,15 +5915,6 @@ qemuBuildCommandLine(virConnectPtr conn,
if (qemuBuildMachineArgStr(cmd, def, qemuCaps) < 0)
goto error;
if (disableKQEMU)
virCommandAddArg(cmd, "-no-kqemu");
else if (enableKQEMU)
virCommandAddArgList(cmd, "-enable-kqemu", "-kernel-kqemu", NULL);
if (disableKVM)
virCommandAddArg(cmd, "-no-kvm");
if (enableKVM)
virCommandAddArg(cmd, "-enable-kvm");
if (qemuBuildCpuArgStr(driver, def, emulator, qemuCaps,
hostarch, &cpu, &hasHwVirt, !!migrateFrom) < 0)
goto error;

View File

@ -0,0 +1,4 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test \
/usr/libexec/qemu-kvm -S -machine pc-1.0,accel=kvm -m 4096 \
-smp 4 -nographic -monitor unix:/tmp/test-monitor,server,nowait \
-no-acpi -boot c -usb -net none -serial none -parallel none

View File

@ -0,0 +1,22 @@
<domain type='kvm'>
<name>kvm</name>
<uuid>d091ea82-29e6-2e34-3005-f02617b36e87</uuid>
<memory unit='KiB'>4194304</memory>
<currentMemory unit='KiB'>4194304</currentMemory>
<vcpu placement='static'>4</vcpu>
<os>
<type arch='x86_64' machine='pc-1.0'>hvm</type>
<boot dev='hd'/>
</os>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
</controller>
<memballoon model='none'/>
</devices>
</domain>

View File

@ -1,5 +1,5 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
-S -machine pc,dump-guest-core=off -m 214 -smp 1 -nographic \
-S -machine pc,accel=tcg,dump-guest-core=off -m 214 -smp 1 -nographic \
-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
-hda /dev/HostVG/QEMUGuest1 -net none -serial \
none -parallel none

View File

@ -1,5 +1,5 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
-S -machine pc,dump-guest-core=on -m 214 -smp 1 -nographic \
-S -machine pc,accel=tcg,dump-guest-core=on -m 214 -smp 1 -nographic \
-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
-hda /dev/HostVG/QEMUGuest1 -net none -serial \
none -parallel none

View File

@ -1,5 +1,5 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
-S -machine pc,usb=off -m 214 -smp 1 -nographic \
-S -machine pc,accel=tcg,usb=off -m 214 -smp 1 -nographic \
-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -usb \
-hda /dev/HostVG/QEMUGuest1 -net none -serial \
none -parallel none

View File

@ -372,6 +372,7 @@ mymain(void)
DO_TEST_FAILURE("machine-core-on", QEMU_CAPS_MACHINE_OPT);
DO_TEST("machine-usb-opt", QEMU_CAPS_MACHINE_OPT,
QEMU_CAPS_MACHINE_USB_OPT);
DO_TEST("kvm", QEMU_CAPS_MACHINE_OPT);
DO_TEST("boot-cdrom", NONE);
DO_TEST("boot-network", NONE);
DO_TEST("boot-floppy", NONE);