qemu: virtio console support

Enable specifying a virtio console device with:

<console type='pty'>
  <target type='virtio'/>
</console>
This commit is contained in:
Cole Robinson 2010-07-14 13:02:04 -04:00
parent 6b24755235
commit 82b6d7600e
12 changed files with 151 additions and 12 deletions

View File

@ -1132,8 +1132,16 @@ qemu-kvm -net nic,model=? /dev/null
<p>
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.
</p>
<p>
A virtio console device is exposed in the
guest as /dev/hvc[0-7] (for more information, see
<a href="http://fedoraproject.org/wiki/Features/VirtioSerial">http://fedoraproject.org/wiki/Features/VirtioSerial</a>)
<span class="since">Since 0.8.3</span>
</p>
<pre>
@ -1143,6 +1151,12 @@ qemu-kvm -net nic,model=? /dev/null
&lt;source path='/dev/pts/4'/&gt;
&lt;target port='0'/&gt;
&lt;/console&gt;
&lt;!-- KVM virtio console --&gt;
&lt;console type='pty'&gt;
&lt;source path='/dev/pts/5'/&gt;
&lt;target type='virtio' port='0'/&gt;
&lt;/console&gt;
&lt;/devices&gt;
...</pre>

View File

@ -1226,6 +1226,7 @@
<value>xen</value>
<value>serial</value>
<value>uml</value>
<value>virtio</value>
</choice>
</attribute>
</define>
@ -1302,7 +1303,9 @@
</optional>
<empty/>
</group>
<ref name="qemucdev"/>
<choice>
<ref name="qemucdev"/>
</choice>
</choice>
</element>
</define>

View File

@ -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:

View File

@ -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,
};

View File

@ -228,6 +228,7 @@ virDomainSnapshotAssignDef;
virDomainObjAssignDef;
virDomainChrDefForeach;
virDomainDiskDefForeachPath;
virDomainChrConsoleTargetTypeToString;
# domain_event.h

View File

@ -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];

View File

@ -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;

View File

@ -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

View File

@ -0,0 +1,27 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</currentMemory>
<vcpu cpuset='1-4,8-20,525'>1</vcpu>
<os>
<type arch='i686' machine='pc'>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/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<controller type='ide' index='0'/>
<console type='pty'>
<target type='virtio'/>
</console>
</devices>
</domain>

View File

@ -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 |

View File

@ -0,0 +1,29 @@
<domain type='qemu'>
<name>QEMUGuest1</name>
<uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
<memory>219200</memory>
<currentMemory>219200</currentMemory>
<vcpu cpuset='1-4,8-20,525'>1</vcpu>
<os>
<type arch='i686' machine='pc'>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/bin/qemu</emulator>
<disk type='block' device='disk'>
<source dev='/dev/HostVG/QEMUGuest1'/>
<target dev='hda' bus='ide'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<controller type='ide' index='0'/>
<controller type='virtio-serial' index='0'/>
<console type='pty'>
<target type='virtio' port='0'/>
</console>
<memballoon model='virtio'/>
</devices>
</domain>

View File

@ -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);