From: Cole Robinson Date: Wed, 14 Jul 2010 17:02:04 +0000 (-0400) Subject: qemu: virtio console support X-Git-Tag: v0.8.3~45 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=82b6d7600e2c1ea23a18b23984d7d8d47961cfc9;p=thirdparty%2Flibvirt.git qemu: virtio console support Enable specifying a virtio console device with: --- diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index a70a94e72b..5269cc5edc 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1132,8 +1132,16 @@ qemu-kvm -net nic,model=? /dev/null

This represents the primary console. This can be the paravirtualized - console with Xen guests, or duplicates the primary serial port for fully - virtualized guests without a paravirtualized console. + console with Xen guests, virtio console for QEMU/KVM, or duplicates + the primary serial port for fully virtualized guests without a + paravirtualized console. +

+ +

+ A virtio console device is exposed in the + guest as /dev/hvc[0-7] (for more information, see + http://fedoraproject.org/wiki/Features/VirtioSerial) + Since 0.8.3

@@ -1143,6 +1151,12 @@ qemu-kvm -net nic,model=? /dev/null
       <source path='/dev/pts/4'/>
       <target port='0'/>
     </console>
+
+    <!-- KVM virtio console -->
+    <console type='pty'>
+      <source path='/dev/pts/5'/>
+      <target type='virtio' port='0'/>
+    </console>
   </devices>
   ...
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 04dc298b2d..b2783b0a6c 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -1226,6 +1226,7 @@ xen serial uml + virtio @@ -1302,7 +1303,9 @@ - + + + diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 5d7dfbf96c..82e5ce7457 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -173,7 +173,8 @@ VIR_ENUM_IMPL(virDomainChrConsoleTarget, VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST, "serial", "xen", - "uml") + "uml", + "virtio") VIR_ENUM_IMPL(virDomainChrDevice, VIR_DOMAIN_CHR_DEVICE_TYPE_LAST, "monitor", @@ -2426,13 +2427,12 @@ virDomainChrTargetTypeFromString(virCapsPtr caps, case VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE: target = virDomainChrConsoleTargetTypeFromString(targetType); - /* Fall through */ + break; case VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL: case VIR_DOMAIN_CHR_DEVICE_TYPE_PARALLEL: default: /* No target type yet*/ - target = 0; break; } @@ -4578,7 +4578,8 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps, * For HVM console actually created a serial device * while for non-HVM it was a parvirt console */ - if (STREQ(def->os.type, "hvm")) { + if (STREQ(def->os.type, "hvm") && + chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL) { if (def->nserials != 0) { virDomainChrDefFree(chr); } else { @@ -5122,7 +5123,7 @@ static int virDomainDefAddDiskControllersForType(virDomainDefPtr def, static int virDomainDefMaybeAddVirtioSerialController(virDomainDefPtr def) { - /* Look for any virtio serial device */ + /* Look for any virtio serial or virtio console devs */ int i; for (i = 0 ; i < def->nchannels ; i++) { @@ -5139,6 +5140,21 @@ static int virDomainDefMaybeAddVirtioSerialController(virDomainDefPtr def) } } + if (def->console) { + virDomainChrDefPtr console = def->console; + + if (console->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO) { + int idx = 0; + if (console->info.type == + VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL) + idx = console->info.addr.vioserial.controller; + + if (virDomainDefMaybeAddController(def, + VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL, idx) < 0) + return -1; + } + } + return 0; } @@ -5733,14 +5749,14 @@ virDomainChrDefFormat(virBufferPtr buf, virBufferVSprintf(buf, " <%s type='%s'", elementName, type); if (def->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE && + def->target.port == 0 && def->type == VIR_DOMAIN_CHR_TYPE_PTY && !(flags & VIR_DOMAIN_XML_INACTIVE) && def->data.file.path) { - virBufferEscapeString(buf, " tty='%s'>\n", + virBufferEscapeString(buf, " tty='%s'", def->data.file.path); - } else { - virBufferAddLit(buf, ">\n"); } + virBufferAddLit(buf, ">\n"); switch (def->type) { case VIR_DOMAIN_CHR_TYPE_NULL: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 9bd61ca154..e32188fa75 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -334,6 +334,7 @@ enum virDomainChrConsoleTargetType { VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL = 0, VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_XEN, VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_UML, + VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO, VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_LAST, }; diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 6b83cb984c..b5944a799b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -228,6 +228,7 @@ virDomainSnapshotAssignDef; virDomainObjAssignDef; virDomainChrDefForeach; virDomainDiskDefForeachPath; +virDomainChrConsoleTargetTypeToString; # domain_event.h diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 2c35a45a45..7c63bdcb30 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -2031,6 +2031,10 @@ qemuAssignDeviceAliases(virDomainDefPtr def, unsigned long long qemuCmdFlags) if (virAsprintf(&def->channels[i]->info.alias, "channel%d", i) < 0) goto no_memory; } + if (def->console) { + if (virAsprintf(&def->console->info.alias, "console%d", i) < 0) + goto no_memory; + } if (def->watchdog) { if (virAsprintf(&def->watchdog->info.alias, "watchdog%d", 0) < 0) goto no_memory; @@ -3337,7 +3341,10 @@ char * qemuBuildVirtioSerialPortDevStr(virDomainChrDefPtr dev) { virBuffer buf = VIR_BUFFER_INITIALIZER; - virBufferAddLit(&buf, "virtserialport"); + if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE) + virBufferAddLit(&buf, "virtconsole"); + else + virBufferAddLit(&buf, "virtserialport"); if (dev->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { /* Check it's a virtio-serial address */ @@ -4547,6 +4554,41 @@ int qemudBuildCommandLine(virConnectPtr conn, } } + /* Explicit console devices */ + if (def->console) { + virDomainChrDefPtr console = def->console; + char *devstr; + + switch(console->targetType) { + case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO: + if (!(qemuCmdFlags & QEMUD_CMD_FLAG_DEVICE)) { + qemuReportError(VIR_ERR_NO_SUPPORT, "%s", + _("virtio channel requires QEMU to support -device")); + goto error; + } + + ADD_ARG_LIT("-chardev"); + if (!(devstr = qemuBuildChrChardevStr(console))) + goto error; + ADD_ARG(devstr); + + ADD_ARG_LIT("-device"); + if (!(devstr = qemuBuildVirtioSerialPortDevStr(console))) + goto error; + ADD_ARG(devstr); + break; + + case VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL: + break; + + default: + qemuReportError(VIR_ERR_NO_SUPPORT, + _("unsupported console target type %s"), + NULLSTR(virDomainChrConsoleTargetTypeToString(console->targetType))); + goto error; + } + } + ADD_ARG_LIT("-usb"); for (i = 0 ; i < def->ninputs ; i++) { virDomainInputDefPtr input = def->inputs[i]; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 315fcc8da4..767265d7a5 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -2229,6 +2229,8 @@ qemudFindCharDevicePTYsMonitor(virDomainObjPtr vm, LOOKUP_PTYS(vm->def->serials, vm->def->nserials, "serial"); LOOKUP_PTYS(vm->def->parallels, vm->def->nparallels, "parallel"); LOOKUP_PTYS(vm->def->channels, vm->def->nchannels, "channel"); + if (vm->def->console) + LOOKUP_PTYS(&vm->def->console, 1, "console"); #undef LOOKUP_PTYS return 0; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-virtio.args b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio.args new file mode 100644 index 0000000000..a55000f590 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio.args @@ -0,0 +1 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -device virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x2 -hda /dev/HostVG/QEMUGuest1 -chardev pty,id=console0 -device virtconsole,chardev=console0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-console-virtio.xml b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio.xml new file mode 100644 index 0000000000..fd72421460 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-console-virtio.xml @@ -0,0 +1,27 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + +
+ + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index a967fef2b1..7b9df09b29 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -355,6 +355,8 @@ mymain(int argc, char **argv) QEMUD_CMD_FLAG_NODEFCONFIG); DO_TEST("channel-virtio-auto", QEMUD_CMD_FLAG_DEVICE | QEMUD_CMD_FLAG_NODEFCONFIG); + DO_TEST("console-virtio", QEMUD_CMD_FLAG_DEVICE | + QEMUD_CMD_FLAG_NODEFCONFIG); DO_TEST("watchdog", 0); DO_TEST("watchdog-device", QEMUD_CMD_FLAG_DEVICE | diff --git a/tests/qemuxml2xmloutdata/qemuxml2xmlout-console-virtio.xml b/tests/qemuxml2xmloutdata/qemuxml2xmlout-console-virtio.xml new file mode 100644 index 0000000000..431dd34b6b --- /dev/null +++ b/tests/qemuxml2xmloutdata/qemuxml2xmlout-console-virtio.xml @@ -0,0 +1,29 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219200 + 219200 + 1 + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu + + + +
+ + + + + + + + + diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index 0f4c83cb84..904183c658 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -184,6 +184,7 @@ mymain(int argc, char **argv) DO_TEST_DIFFERENT("channel-virtio-auto"); DO_TEST_DIFFERENT("console-compat-auto"); DO_TEST_DIFFERENT("disk-scsi-device-auto"); + DO_TEST_DIFFERENT("console-virtio"); virCapabilitiesFree(driver.caps);