Hi,
This patch adds support for the -pcidevice host=bus:dev.func
added in kvm-79
I used the structure as already defined in src/domain_conf.h
so analog to usb one now can add pci devices
as example:
lspci: 06:02.0 Network controller: Eicon Networks Corporation Diva
Server 2FX (rev 01)
<hostdev mode='subsystem' type='pci'>
<source>
<address bus="0x06" slot="0x02" function="0x0"/>
</source>
</hostdev>
values are hex so for bus: 0 to ff, slot: 0 to 1f and function: 0 to 7
Hope this patch is useful it applies to libvirt-0.5.1 and cvs checkout
from today (with some hunks)
Regards Jason
--
Collax GmbH . Burkheimer Str. 3 . 79111 Freiburg . Germany
p: +49 (0) 89-990157-0
f: +49 (0) 89-990157-11 . http://www.collax.com
diff -urp libvirt-0.5.1/src/domain_conf.c libvirt-0.5.1.new/src/domain_conf.c
--- libvirt-0.5.1/src/domain_conf.c 2008-12-04 13:51:39.000000000 +0100
+++ libvirt-0.5.1.new/src/domain_conf.c 2008-12-16 01:33:14.000000000 +0100
@@ -1531,6 +1531,95 @@ out:
}
+static int
+virDomainHostdevSubsysPciDefParseXML(virConnectPtr conn,
+ const xmlNodePtr node,
+ virDomainHostdevDefPtr def) {
+
+ int ret = -1;
+ xmlNodePtr cur;
+
+ cur = node->children;
+ while (cur != NULL) {
+ if (cur->type == XML_ELEMENT_NODE) {
+ if (xmlStrEqual(cur->name, BAD_CAST "address")) {
+
+ char *domain = virXMLPropString(cur, "domain");
+ if (domain) {
+ if (virStrToLong_ui(domain, NULL, 0,
+ &def->source.subsys.pci.domain) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse domain %s"), domain);
+ VIR_FREE(domain);
+ goto out;
+ }
+ VIR_FREE(domain);
+ }
+
+ char *bus = virXMLPropString(cur, "bus");
+ if (bus) {
+ if (virStrToLong_ui(bus, NULL, 0,
+ &def->source.subsys.pci.bus) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse bus %s"), bus);
+ VIR_FREE(bus);
+ goto out;
+ }
+ VIR_FREE(bus);
+ } else {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("pci address needs bus id"));
+ goto out;
+ }
+
+ char *slot = virXMLPropString(cur, "slot");
+ if (slot) {
+ if (virStrToLong_ui(slot, NULL, 0,
+ &def->source.subsys.pci.slot) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse slot %s"),
+ slot);
+ VIR_FREE(slot);
+ goto out;
+ }
+ VIR_FREE(slot);
+ } else {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("pci address needs slot id"));
+ goto out;
+ }
+
+ char *function = virXMLPropString(cur, "function");
+ if (function) {
+ if (virStrToLong_ui(function, NULL, 0,
+ &def->source.subsys.pci.function) < 0) {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse function %s"),
+ function);
+ VIR_FREE(function);
+ goto out;
+ }
+ VIR_FREE(function);
+ } else {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ "%s", _("pci address needs function id"));
+ goto out;
+ }
+ } else {
+ virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("unknown pci source type '%s'"), cur->name);
+ goto out;
+ }
+ }
+ cur = cur->next;
+ }
+
+ ret = 0;
+out:
+ return ret;
+}
+
+
static virDomainHostdevDefPtr
virDomainHostdevDefParseXML(virConnectPtr conn,
const xmlNodePtr node) {
@@ -1578,6 +1667,11 @@ virDomainHostdevDefParseXML(virConnectPt
if (virDomainHostdevSubsysUsbDefParseXML(conn, cur, def) < 0)
goto error;
}
+ if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ if (virDomainHostdevSubsysPciDefParseXML(conn, cur, def) < 0)
+ goto error;
+ }
} else {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unknown node %s"), cur->name);
@@ -2951,7 +3045,7 @@ virDomainHostdevDefFormat(virConnectPtr
}
type = virDomainHostdevSubsysTypeToString(def->source.subsys.type);
- if (!type || def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
+ if (!type || (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB && def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) ) {
virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR,
_("unexpected hostdev type %d"),
def->source.subsys.type);
@@ -2960,16 +3054,25 @@ virDomainHostdevDefFormat(virConnectPtr
virBufferVSprintf(buf, " <hostdev mode='%s' type='%s'>\n", mode, type);
virBufferAddLit(buf, " <source>\n");
-
- if (def->source.subsys.usb.vendor) {
- virBufferVSprintf(buf, " <vendor id='0x%.4x'/>\n",
- def->source.subsys.usb.vendor);
- virBufferVSprintf(buf, " <product id='0x%.4x'/>\n",
- def->source.subsys.usb.product);
- } else {
- virBufferVSprintf(buf, " <address bus='%d' device='%d'/>\n",
- def->source.subsys.usb.bus,
- def->source.subsys.usb.device);
+
+ if ( def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB ) {
+ if (def->source.subsys.usb.vendor) {
+ virBufferVSprintf(buf, " <vendor id='0x%.4x'/>\n",
+ def->source.subsys.usb.vendor);
+ virBufferVSprintf(buf, " <product id='0x%.4x'/>\n",
+ def->source.subsys.usb.product);
+ } else {
+ virBufferVSprintf(buf, " <address bus='%d' device='%d'/>\n",
+ def->source.subsys.usb.bus,
+ def->source.subsys.usb.device);
+ }
+ }
+ if ( def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI ) {
+ virBufferVSprintf(buf, " <address domain='0x%.4x' bus='0x%.2x' slot='0x%.2x' function='0x%.1x'/>\n",
+ def->source.subsys.pci.domain,
+ def->source.subsys.pci.bus,
+ def->source.subsys.pci.slot,
+ def->source.subsys.pci.function);
}
virBufferAddLit(buf, " </source>\n");
diff -urp libvirt-0.5.1/src/qemu_conf.c libvirt-0.5.1.new/src/qemu_conf.c
--- libvirt-0.5.1/src/qemu_conf.c 2008-12-16 02:11:04.000000000 +0100
+++ libvirt-0.5.1.new/src/qemu_conf.c 2008-12-16 01:33:14.000000000 +0100
@@ -1265,8 +1265,10 @@ int qemudBuildCommandLine(virConnectPtr
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
int ret;
char* usbdev;
+ char* pcidev;
virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i];
-
+
+ /* USB */
if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) {
if(hostdev->source.subsys.usb.vendor) {
@@ -1287,6 +1289,23 @@ int qemudBuildCommandLine(virConnectPtr
ADD_ARG_LIT(usbdev);
VIR_FREE(usbdev);
}
+
+ /* PCI */
+ if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+ hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+ ret = asprintf(&pcidev, "host=%0.2x:%0.2x.%.1x",
+ hostdev->source.subsys.pci.bus,
+ hostdev->source.subsys.pci.slot,
+ hostdev->source.subsys.pci.function);
+ if (ret < 0) {
+ pcidev = NULL;
+ goto error;
+ }
+ ADD_ARG_LIT("-pcidevice");
+ ADD_ARG_LIT(pcidev);
+ VIR_FREE(pcidev);
+ }
+
}
if (migrateFrom) {
--
Libvir-list mailing list
Libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list