mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 21:55:25 +00:00
Add domain support for virtio channel
Add support for virtio-serial by defining a new 'virtio' channel target type and a virtio-serial controller. Allows the following to be specified in a domain: <controller type='virtio-serial' index='0' ports='16' vectors='4'/> <channel type='pty'> <target type='virtio' name='org.linux-kvm.port.0'/> <address type='virtio-serial' controller='0' bus='0'/> </channel> * docs/schemas/domain.rng: Add virtio-serial controller and virtio channel type. * src/conf/domain_conf.[ch]: Domain parsing/serialization for virtio-serial controller and virtio channel. * tests/qemuxml2xmltest.c tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml: add domain xml parsing test * src/libvirt_private.syms src/qemu/qemu_conf.c: virDomainDefAddDiskControllers() renamed to virDomainDefAddImplicitControllers()
This commit is contained in:
parent
07e318b3db
commit
7813a0f81c
@ -523,16 +523,36 @@
|
||||
</define>
|
||||
<define name="controller">
|
||||
<element name="controller">
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<choice>
|
||||
<value>fdc</value>
|
||||
<value>ide</value>
|
||||
<value>scsi</value>
|
||||
<value>sata</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
<choice>
|
||||
<group>
|
||||
<optional>
|
||||
<attribute name="type">
|
||||
<choice>
|
||||
<value>fdc</value>
|
||||
<value>ide</value>
|
||||
<value>scsi</value>
|
||||
<value>sata</value>
|
||||
</choice>
|
||||
</attribute>
|
||||
</optional>
|
||||
</group>
|
||||
<!-- virtio-serial can have 2 additional attributes -->
|
||||
<group>
|
||||
<attribute name="type">
|
||||
<value>virtio-serial</value>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="ports">
|
||||
<ref name="unsignedInt"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
<optional>
|
||||
<attribute name="vectors">
|
||||
<ref name="unsignedInt"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</group>
|
||||
</choice>
|
||||
<attribute name="index">
|
||||
<ref name="unsignedInt"/>
|
||||
</attribute>
|
||||
@ -1139,12 +1159,25 @@
|
||||
<attribute name="port"/>
|
||||
</element>
|
||||
</define>
|
||||
<define name="virtioTarget">
|
||||
<element name="target">
|
||||
<attribute name="type">
|
||||
<value>virtio</value>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="name"/>
|
||||
</optional>
|
||||
</element>
|
||||
</define>
|
||||
<define name="channel">
|
||||
<element name="channel">
|
||||
<ref name="qemucdevSrcType"/>
|
||||
<interleave>
|
||||
<ref name="qemucdevSrcDef"/>
|
||||
<ref name="guestfwdTarget"/>
|
||||
<choice>
|
||||
<ref name="guestfwdTarget"/>
|
||||
<ref name="virtioTarget"/>
|
||||
</choice>
|
||||
<optional>
|
||||
<ref name="address"/>
|
||||
</optional>
|
||||
@ -1269,6 +1302,16 @@
|
||||
<ref name="driveUnit"/>
|
||||
</attribute>
|
||||
</define>
|
||||
<define name="virtioserialaddress">
|
||||
<attribute name="controller">
|
||||
<ref name="driveController"/>
|
||||
</attribute>
|
||||
<optional>
|
||||
<attribute name="bus">
|
||||
<ref name="driveBus"/>
|
||||
</attribute>
|
||||
</optional>
|
||||
</define>
|
||||
<!--
|
||||
Devices attached to a domain.
|
||||
-->
|
||||
@ -1413,6 +1456,12 @@
|
||||
</attribute>
|
||||
<ref name="driveaddress"/>
|
||||
</group>
|
||||
<group>
|
||||
<attribute name="type">
|
||||
<value>virtio-serial</value>
|
||||
</attribute>
|
||||
<ref name="virtioserialaddress"/>
|
||||
</group>
|
||||
</choice>
|
||||
</element>
|
||||
</define>
|
||||
|
@ -93,7 +93,8 @@ VIR_ENUM_IMPL(virDomainDevice, VIR_DOMAIN_DEVICE_LAST,
|
||||
VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
|
||||
"none",
|
||||
"pci",
|
||||
"drive");
|
||||
"drive",
|
||||
"virtio-serial");
|
||||
|
||||
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
|
||||
"block",
|
||||
@ -125,7 +126,8 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
|
||||
"ide",
|
||||
"fdc",
|
||||
"scsi",
|
||||
"sata")
|
||||
"sata",
|
||||
"virtio-serial")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainFS, VIR_DOMAIN_FS_TYPE_LAST,
|
||||
"mount",
|
||||
@ -150,7 +152,8 @@ VIR_ENUM_IMPL(virDomainChrTarget, VIR_DOMAIN_CHR_TARGET_TYPE_LAST,
|
||||
"parallel",
|
||||
"serial",
|
||||
"console",
|
||||
"guestfwd")
|
||||
"guestfwd",
|
||||
"virtio")
|
||||
|
||||
VIR_ENUM_IMPL(virDomainChr, VIR_DOMAIN_CHR_TYPE_LAST,
|
||||
"null",
|
||||
@ -459,6 +462,10 @@ void virDomainChrDefFree(virDomainChrDefPtr def)
|
||||
case VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD:
|
||||
VIR_FREE(def->target.addr);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO:
|
||||
VIR_FREE(def->target.name);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (def->type) {
|
||||
@ -811,6 +818,13 @@ int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr ATTRI
|
||||
/*return addr->controller || addr->bus || addr->unit;*/
|
||||
return 1; /* 0 is valid for all fields, so any successfully parsed addr is valid */
|
||||
}
|
||||
|
||||
|
||||
int virDomainDeviceVirtioSerialAddressIsValid(
|
||||
virDomainDeviceVirtioSerialAddressPtr addr ATTRIBUTE_UNUSED)
|
||||
{
|
||||
return 1; /* 0 is valid for all fields, so any successfully parsed addr is valid */
|
||||
}
|
||||
#endif /* !PROXY */
|
||||
|
||||
|
||||
@ -952,6 +966,12 @@ static int virDomainDeviceInfoFormat(virBufferPtr buf,
|
||||
info->addr.drive.unit);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL:
|
||||
virBufferVSprintf(buf, " controller='%d' bus='%d'",
|
||||
info->addr.vioserial.controller,
|
||||
info->addr.vioserial.bus);
|
||||
break;
|
||||
|
||||
default:
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("unknown address type '%d'"), info->type);
|
||||
@ -1075,6 +1095,50 @@ cleanup:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virDomainDeviceVirtioSerialAddressParseXML(
|
||||
xmlNodePtr node,
|
||||
virDomainDeviceVirtioSerialAddressPtr addr
|
||||
)
|
||||
{
|
||||
char *controller, *bus;
|
||||
int ret = -1;
|
||||
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
|
||||
controller = virXMLPropString(node, "controller");
|
||||
bus = virXMLPropString(node, "bus");
|
||||
|
||||
if (controller &&
|
||||
virStrToLong_ui(controller, NULL, 10, &addr->controller) < 0) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Cannot parse <address> 'controller' attribute"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (bus &&
|
||||
virStrToLong_ui(bus, NULL, 10, &addr->bus) < 0) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Cannot parse <address> 'bus' attribute"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!virDomainDeviceVirtioSerialAddressIsValid(addr)) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Insufficient specification for "
|
||||
"virtio serial address"));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
VIR_FREE(controller);
|
||||
VIR_FREE(bus);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Parse the XML definition for a device address
|
||||
* @param node XML nodeset to parse for device address definition
|
||||
*/
|
||||
@ -1137,6 +1201,12 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL:
|
||||
if (virDomainDeviceVirtioSerialAddressParseXML
|
||||
(address, &info->addr.vioserial) < 0)
|
||||
goto cleanup;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Should not happen */
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
@ -1462,9 +1532,9 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
||||
|
||||
type = virXMLPropString(node, "type");
|
||||
if (type) {
|
||||
if ((def->type = virDomainDiskBusTypeFromString(type)) < 0) {
|
||||
if ((def->type = virDomainControllerTypeFromString(type)) < 0) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("unknown disk controller type '%s'"), type);
|
||||
_("Unknown controller type '%s'"), type);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@ -1473,7 +1543,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
||||
if (idx) {
|
||||
if (virStrToLong_i(idx, NULL, 10, &def->idx) < 0) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("cannot parse disk controller index %s"), idx);
|
||||
_("Cannot parse controller index %s"), idx);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@ -1481,10 +1551,48 @@ virDomainControllerDefParseXML(xmlNodePtr node,
|
||||
if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0)
|
||||
goto error;
|
||||
|
||||
switch (def->type) {
|
||||
case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL: {
|
||||
char *ports = virXMLPropString(node, "ports");
|
||||
if (ports) {
|
||||
int r = virStrToLong_i(ports, NULL, 10,
|
||||
&def->opts.vioserial.ports);
|
||||
if (r != 0 || def->opts.vioserial.ports < 0) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Invalid ports: %s"), ports);
|
||||
VIR_FREE(ports);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
def->opts.vioserial.ports = -1;
|
||||
}
|
||||
VIR_FREE(ports);
|
||||
|
||||
char *vectors = virXMLPropString(node, "vectors");
|
||||
if (vectors) {
|
||||
int r = virStrToLong_i(vectors, NULL, 10,
|
||||
&def->opts.vioserial.vectors);
|
||||
if (r != 0 || def->opts.vioserial.vectors < 0) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
_("Invalid vectors: %s"), vectors);
|
||||
VIR_FREE(vectors);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
def->opts.vioserial.vectors = -1;
|
||||
}
|
||||
VIR_FREE(vectors);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
|
||||
def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("Disk controllers must use the 'pci' address type"));
|
||||
_("Controllers must use the 'pci' address type"));
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -2086,6 +2194,10 @@ virDomainChrDefParseXML(xmlNodePtr node,
|
||||
virSocketSetPort(def->target.addr, port);
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO:
|
||||
def->target.name = virXMLPropString(cur, "name");
|
||||
break;
|
||||
|
||||
default:
|
||||
virDomainReportError(VIR_ERR_XML_ERROR,
|
||||
_("unexpected target type type %u"),
|
||||
@ -2096,7 +2208,6 @@ virDomainChrDefParseXML(xmlNodePtr node,
|
||||
cur = cur->next;
|
||||
}
|
||||
|
||||
|
||||
switch (def->type) {
|
||||
case VIR_DOMAIN_CHR_TYPE_NULL:
|
||||
/* Nada */
|
||||
@ -3629,12 +3740,6 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
|
||||
}
|
||||
VIR_FREE(nodes);
|
||||
|
||||
/* Auto-add any further disk controllers implied by declared <disk>
|
||||
* elements, but not present as <controller> elements
|
||||
*/
|
||||
if (virDomainDefAddDiskControllers(def) < 0)
|
||||
goto error;
|
||||
|
||||
/* analysis of the filesystems */
|
||||
if ((n = virXPathNodeSet("./devices/filesystem", ctxt, &nodes)) < 0) {
|
||||
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
@ -3948,6 +4053,11 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Auto-add any implied controllers which aren't present
|
||||
*/
|
||||
if (virDomainDefAddImplicitControllers(def) < 0)
|
||||
goto error;
|
||||
|
||||
return def;
|
||||
|
||||
no_memory:
|
||||
@ -4211,9 +4321,9 @@ cleanup:
|
||||
return obj;
|
||||
}
|
||||
|
||||
static int virDomainDefMaybeAddDiskController(virDomainDefPtr def,
|
||||
int type,
|
||||
int idx)
|
||||
static int virDomainDefMaybeAddController(virDomainDefPtr def,
|
||||
int type,
|
||||
int idx)
|
||||
{
|
||||
int found = 0;
|
||||
int i;
|
||||
@ -4266,7 +4376,7 @@ static int virDomainDefAddDiskControllersForType(virDomainDefPtr def,
|
||||
}
|
||||
|
||||
for (i = 0 ; i <= maxController ; i++) {
|
||||
if (virDomainDefMaybeAddDiskController(def, controllerType, i) < 0)
|
||||
if (virDomainDefMaybeAddController(def, controllerType, i) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -4274,13 +4384,33 @@ static int virDomainDefAddDiskControllersForType(virDomainDefPtr def,
|
||||
}
|
||||
|
||||
|
||||
static int virDomainDefMaybeAddVirtioSerialController(virDomainDefPtr def)
|
||||
{
|
||||
/* Look for any virtio serial device */
|
||||
int i;
|
||||
for (i = 0 ; i < def->nchannels ; i++) {
|
||||
virDomainChrDefPtr channel = def->channels[i];
|
||||
|
||||
if (channel->targetType == VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO) {
|
||||
/* Try to add a virtio serial controller with index 0 */
|
||||
if (virDomainDefMaybeAddController(def,
|
||||
VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL, 0) < 0)
|
||||
return -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Based on the declared <address type=drive> info for any disks,
|
||||
* Based on the declared <address/> info for any devices,
|
||||
* add neccessary drive controllers which are not already present
|
||||
* in the XML. This is for compat with existing apps which will
|
||||
* not know/care about <controller> info in the XML
|
||||
*/
|
||||
int virDomainDefAddDiskControllers(virDomainDefPtr def)
|
||||
int virDomainDefAddImplicitControllers(virDomainDefPtr def)
|
||||
{
|
||||
if (virDomainDefAddDiskControllersForType(def,
|
||||
VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
|
||||
@ -4297,6 +4427,9 @@ int virDomainDefAddDiskControllers(virDomainDefPtr def)
|
||||
VIR_DOMAIN_DISK_BUS_IDE) < 0)
|
||||
return -1;
|
||||
|
||||
if (virDomainDefMaybeAddVirtioSerialController(def) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4622,6 +4755,22 @@ virDomainControllerDefFormat(virBufferPtr buf,
|
||||
" <controller type='%s' index='%d'",
|
||||
type, def->idx);
|
||||
|
||||
switch (def->type) {
|
||||
case VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL:
|
||||
if (def->opts.vioserial.ports != -1) {
|
||||
virBufferVSprintf(buf, " ports='%d'",
|
||||
def->opts.vioserial.ports);
|
||||
}
|
||||
if (def->opts.vioserial.vectors != -1) {
|
||||
virBufferVSprintf(buf, " vectors='%d'",
|
||||
def->opts.vioserial.vectors);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (virDomainDeviceInfoIsSet(&def->info)) {
|
||||
virBufferAddLit(buf, ">\n");
|
||||
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
|
||||
@ -4792,6 +4941,7 @@ virDomainChrDefFormat(virBufferPtr buf,
|
||||
switch (def->targetType) {
|
||||
/* channel types are in a common channel element */
|
||||
case VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD:
|
||||
case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO:
|
||||
elementName = "channel";
|
||||
break;
|
||||
|
||||
@ -4905,11 +5055,18 @@ virDomainChrDefFormat(virBufferPtr buf,
|
||||
break;
|
||||
}
|
||||
|
||||
case VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO:
|
||||
virBufferAddLit(buf, " <target type='virtio'");
|
||||
if (def->target.name) {
|
||||
virBufferEscapeString(buf, " name='%s'", def->target.name);
|
||||
}
|
||||
virBufferAddLit(buf, "/>\n");
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_CHR_TARGET_TYPE_PARALLEL:
|
||||
case VIR_DOMAIN_CHR_TARGET_TYPE_SERIAL:
|
||||
case VIR_DOMAIN_CHR_TARGET_TYPE_CONSOLE:
|
||||
virBufferVSprintf(buf, " <target port='%d'/>\n",
|
||||
def->target.port);
|
||||
virBufferVSprintf(buf, " <target port='%d'/>\n", def->target.port);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -4919,8 +5076,10 @@ virDomainChrDefFormat(virBufferPtr buf,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
|
||||
return -1;
|
||||
if (virDomainDeviceInfoIsSet(&def->info)) {
|
||||
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
virBufferVSprintf(buf, " </%s>\n",
|
||||
elementName);
|
||||
|
@ -68,6 +68,7 @@ enum virDomainDeviceAddressType {
|
||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE,
|
||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI,
|
||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE,
|
||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_VIRTIO_SERIAL,
|
||||
|
||||
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
|
||||
};
|
||||
@ -89,6 +90,13 @@ struct _virDomainDeviceDriveAddress {
|
||||
unsigned int unit;
|
||||
};
|
||||
|
||||
typedef struct _virDomainDeviceVirtioSerialAddress virDomainDeviceVirtioSerialAddress;
|
||||
typedef virDomainDeviceVirtioSerialAddress *virDomainDeviceVirtioSerialAddressPtr;
|
||||
struct _virDomainDeviceVirtioSerialAddress {
|
||||
unsigned int controller;
|
||||
unsigned int bus;
|
||||
};
|
||||
|
||||
typedef struct _virDomainDeviceInfo virDomainDeviceInfo;
|
||||
typedef virDomainDeviceInfo *virDomainDeviceInfoPtr;
|
||||
struct _virDomainDeviceInfo {
|
||||
@ -97,6 +105,7 @@ struct _virDomainDeviceInfo {
|
||||
union {
|
||||
virDomainDevicePCIAddress pci;
|
||||
virDomainDeviceDriveAddress drive;
|
||||
virDomainDeviceVirtioSerialAddress vioserial;
|
||||
} addr;
|
||||
};
|
||||
|
||||
@ -166,16 +175,27 @@ enum virDomainControllerType {
|
||||
VIR_DOMAIN_CONTROLLER_TYPE_FDC,
|
||||
VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
|
||||
VIR_DOMAIN_CONTROLLER_TYPE_SATA,
|
||||
VIR_DOMAIN_CONTROLLER_TYPE_VIRTIO_SERIAL,
|
||||
|
||||
VIR_DOMAIN_CONTROLLER_TYPE_LAST
|
||||
};
|
||||
|
||||
typedef struct _virDomainVirtioSerialOpts virDomainVirtioSerialOpts;
|
||||
typedef virDomainVirtioSerialOpts *virDomainVirtioSerialOptsPtr;
|
||||
struct _virDomainVirtioSerialOpts {
|
||||
int ports; /* -1 == undef */
|
||||
int vectors; /* -1 == undef */
|
||||
};
|
||||
|
||||
/* Stores the virtual disk controller configuration */
|
||||
typedef struct _virDomainControllerDef virDomainControllerDef;
|
||||
typedef virDomainControllerDef *virDomainControllerDefPtr;
|
||||
struct _virDomainControllerDef {
|
||||
int type;
|
||||
int idx;
|
||||
union {
|
||||
virDomainVirtioSerialOpts vioserial;
|
||||
} opts;
|
||||
virDomainDeviceInfo info;
|
||||
};
|
||||
|
||||
@ -271,6 +291,7 @@ enum virDomainChrTargetType {
|
||||
VIR_DOMAIN_CHR_TARGET_TYPE_SERIAL,
|
||||
VIR_DOMAIN_CHR_TARGET_TYPE_CONSOLE,
|
||||
VIR_DOMAIN_CHR_TARGET_TYPE_GUESTFWD,
|
||||
VIR_DOMAIN_CHR_TARGET_TYPE_VIRTIO,
|
||||
|
||||
VIR_DOMAIN_CHR_TARGET_TYPE_LAST
|
||||
};
|
||||
@ -304,6 +325,7 @@ struct _virDomainChrDef {
|
||||
union {
|
||||
int port; /* parallel, serial, console */
|
||||
virSocketAddrPtr addr; /* guestfwd */
|
||||
char *name; /* virtio */
|
||||
} target;
|
||||
|
||||
int type;
|
||||
@ -744,6 +766,7 @@ int virDomainDeviceAddressIsValid(virDomainDeviceInfoPtr info,
|
||||
int type);
|
||||
int virDomainDevicePCIAddressIsValid(virDomainDevicePCIAddressPtr addr);
|
||||
int virDomainDeviceDriveAddressIsValid(virDomainDeviceDriveAddressPtr addr);
|
||||
int virDomainDeviceVirtioSerialAddressIsValid(virDomainDeviceVirtioSerialAddressPtr addr);
|
||||
int virDomainDeviceInfoIsSet(virDomainDeviceInfoPtr info);
|
||||
void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info);
|
||||
void virDomainDefClearPCIAddresses(virDomainDefPtr def);
|
||||
@ -790,7 +813,7 @@ virDomainObjPtr virDomainObjParseNode(virCapsPtr caps,
|
||||
xmlDocPtr xml,
|
||||
xmlNodePtr root);
|
||||
|
||||
int virDomainDefAddDiskControllers(virDomainDefPtr def);
|
||||
int virDomainDefAddImplicitControllers(virDomainDefPtr def);
|
||||
|
||||
#endif
|
||||
char *virDomainDefFormat(virDomainDefPtr def,
|
||||
|
@ -185,7 +185,7 @@ virDomainDeviceInfoIsSet;
|
||||
virDomainControllerTypeToString;
|
||||
virDomainControllerDefFree;
|
||||
virDomainDeviceAddressTypeToString;
|
||||
virDomainDefAddDiskControllers;
|
||||
virDomainDefAddImplicitControllers;
|
||||
virDomainDefClearPCIAddresses;
|
||||
virDomainDefClearDeviceAliases;
|
||||
virDomainDeviceInfoIterate;
|
||||
|
@ -5709,7 +5709,7 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
|
||||
goto no_memory;
|
||||
}
|
||||
|
||||
if (virDomainDefAddDiskControllers(def) < 0)
|
||||
if (virDomainDefAddImplicitControllers(def) < 0)
|
||||
goto error;
|
||||
|
||||
return def;
|
||||
|
35
tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml
Normal file
35
tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<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' ports='16' vectors='4'/>
|
||||
<controller type='virtio-serial' index='1'>
|
||||
<address type='pci' domain='0x0000' bus='0x00' slot='0x0a' function='0x0'/>
|
||||
</controller>
|
||||
<channel type='pty'>
|
||||
<target type='virtio' name='org.linux-kvm.port.0'/>
|
||||
</channel>
|
||||
<channel type='pty'>
|
||||
<target type='virtio' name='org.linux-kvm.port.1'/>
|
||||
<address type='virtio-serial' controller='1' bus='0'/>
|
||||
</channel>
|
||||
</devices>
|
||||
</domain>
|
@ -133,6 +133,7 @@ mymain(int argc, char **argv)
|
||||
DO_TEST("parallel-tcp");
|
||||
DO_TEST("console-compat");
|
||||
DO_TEST("channel-guestfwd");
|
||||
DO_TEST("channel-virtio");
|
||||
|
||||
DO_TEST("hostdev-usb-address");
|
||||
DO_TEST("hostdev-pci-address");
|
||||
|
Loading…
Reference in New Issue
Block a user