Rather than requiring that hostdev sources be specified using the PCI/USB addresses, allow them to be specified using the node device name. The patch includes documentation and test updates, but does not implement support in any driver. Signed-off-by: Mark McLoughlin <markmc@xxxxxxxxxx> --- ChangeLog | 12 +++++ docs/formatdomain.html | 26 +++++++--- docs/formatdomain.html.in | 29 +++++++--- docs/schemas/domain.rng | 10 ++++ src/domain_conf.c | 53 +++++++++++++++++++- src/domain_conf.h | 2 + .../qemuxml2argv-hostdev-nodedev-name.xml | 27 ++++++++++ tests/qemuxml2argvtest.c | 5 ++ tests/qemuxml2xmltest.c | 1 + 9 files changed, 146 insertions(+), 19 deletions(-) create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml diff --git a/ChangeLog b/ChangeLog index 4f2c125..4bd87a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Tue Feb 24 22:27:12 GMT 2009 Mark McLoughlin <markmc@xxxxxxxxxx> + + * src/domain_conf.[ch]: Allow supplying a node + device name as hostdev source + + * docs/formatdomain.html, docs/schemas/domain.rng: + documentation updates + + * tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml, + tests/qemuxml2argvtest.c, tests/qemuxml2xmltest.c: test + updates + Tue Feb 24 22:09:40 GMT 2009 Mark McLoughlin <markmc@xxxxxxxxxx> * src/virsh.c: add new commands for each of the new diff --git a/docs/formatdomain.html b/docs/formatdomain.html index 17dc0cd..11ea697 100644 --- a/docs/formatdomain.html +++ b/docs/formatdomain.html @@ -473,6 +473,15 @@ </p> <pre> ... + <hostdev mode='subsystem' type='nodedev'> + <source> + <nodedev name='pci_8086_109a'/> + </source> + </hostdev> + ...</pre> + <p>or:</p> + <pre> + ... <hostdev mode='subsystem' type='usb'> <source> <vendor id='0x1234'/> @@ -490,15 +499,16 @@ </hostdev> ...</pre> <dl><dt><code>hostdev</code></dt><dd>The <code>hostdev</code> element is the main container for describing - host devices. For usb device passthrough <code>mode</code> is always - "subsystem" and <code>type</code> is "usb" for an USB device and "pci" - for a PCI device.. + host devices. For USB or PCI device passthrough <code>mode</code> is always + "subsystem" and <code>type</code> is either "usb", "pci" or "nodedev". </dd><dt><code>source</code></dt><dd>The source element describes the device as seen from the host. - The USB device can either be addressed by vendor / product id using the - <code>vendor</code> and <code>product</code> elements or by the device's - address on the hosts using the <code>address</code> element. - PCI devices on the other hand can only be described by their - <code>address</code></dd><dt><code>vendor</code>, <code>product</code></dt><dd>The <code>vendor</code> and <code>product</code> elements each have an + With <code>type</code> "nodedev", USB and PCI devices can be described + using their node device name as listed by <code>virsh nodedev-list</code>. + Alternatively, USB devices can either be addressed by vendor / product id + using the <code>vendor</code> and <code>product</code> elements or by the + device's address on the hosts using the <code>address</code> element. + PCI devices can be described by their <code>address</code>.</dd><dt><code>nodedev</code></dt><dd>The <code>nodedev</code> element describes a USB or PCI device using + its node device name as listed by <code>virsh nodedev-list</code>.</dd><dt><code>vendor</code>, <code>product</code></dt><dd>The <code>vendor</code> and <code>product</code> elements each have an <code>id</code> attribute that specifies the USB vendor and product id. The ids can be given in decimal, hexadecimal (starting with 0x) or octal (starting with 0) form.</dd><dt><code>address</code></dt><dd>The <code>address</code> element for USB devices has a diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index ee32354..a661b02 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -385,6 +385,15 @@ <pre> ... + <hostdev mode='subsystem' type='nodedev'> + <source> + <nodedev name='pci_8086_109a'/> + </source> + </hostdev> + ...</pre> + <p>or:</p> + <pre> + ... <hostdev mode='subsystem' type='usb'> <source> <vendor id='0x1234'/> @@ -401,20 +410,22 @@ </source> </hostdev> ...</pre> - <dl> <dt><code>hostdev</code></dt> <dd>The <code>hostdev</code> element is the main container for describing - host devices. For usb device passthrough <code>mode</code> is always - "subsystem" and <code>type</code> is "usb" for an USB device and "pci" - for a PCI device.. + host devices. For USB or PCI device passthrough <code>mode</code> is always + "subsystem" and <code>type</code> is either "usb", "pci" or "nodedev". <dt><code>source</code></dt> <dd>The source element describes the device as seen from the host. - The USB device can either be addressed by vendor / product id using the - <code>vendor</code> and <code>product</code> elements or by the device's - address on the hosts using the <code>address</code> element. - PCI devices on the other hand can only be described by their - <code>address</code></dd> + With <code>type</code> "nodedev", USB and PCI devices can be described + using their node device name as listed by <code>virsh nodedev-list</code>. + Alternatively, USB devices can either be addressed by vendor / product id + using the <code>vendor</code> and <code>product</code> elements or by the + device's address on the hosts using the <code>address</code> element. + PCI devices can be described by their <code>address</code>.</dd> + <dt><code>nodedev</code></dt> + <dd>The <code>nodedev</code> element describes a USB or PCI device using + its node device name as listed by <code>virsh nodedev-list</code>.</dd> <dt><code>vendor</code>, <code>product</code></dt> <dd>The <code>vendor</code> and <code>product</code> elements each have an <code>id</code> attribute that specifies the USB vendor and product id. diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 04f6e78..3dfbddb 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -909,6 +909,7 @@ <choice> <value>usb</value> <value>pci</value> + <value>nodedev</value> </choice> </attribute> </optional> @@ -918,6 +919,7 @@ <ref name="usbproduct"/> <ref name="usbaddress"/> <ref name="pciaddress"/> + <ref name="nodedev"/> </choice> </element> </group> @@ -966,6 +968,14 @@ </attribute> </element> </define> + + <define name="nodedev"> + <element name="nodedev"> + <attribute name="name"> + <ref name="genericName"/> + </attribute> + </element> + </define> <!-- Devices attached to a domain. --> diff --git a/src/domain_conf.c b/src/domain_conf.c index 622665c..1ad52f1 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -149,7 +149,8 @@ VIR_ENUM_IMPL(virDomainHostdevMode, VIR_DOMAIN_HOSTDEV_MODE_LAST, VIR_ENUM_IMPL(virDomainHostdevSubsys, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST, "usb", - "pci") + "pci", + "nodedev") VIR_ENUM_IMPL(virDomainState, VIR_DOMAIN_CRASHED+1, "nostate", @@ -349,6 +350,10 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def) if (!def) return; + if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV) + VIR_FREE(def->source.subsys.u.nodedev_name); + VIR_FREE(def->target); VIR_FREE(def); } @@ -1721,6 +1726,38 @@ out: return ret; } +static int +virDomainHostdevSubsysNodedevDefParseXML(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 "nodedev")) { + def->source.subsys.u.nodedev_name = virXMLPropString(cur, "name"); + if (!def->source.subsys.u.nodedev_name) { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("missing node device name")); + goto out; + } + } else { + virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, + _("unknown nodedev source type '%s'"), + cur->name); + goto out; + } + } + cur = cur->next; + } + + ret = 0; +out: + return ret; +} static virDomainHostdevDefPtr virDomainHostdevDefParseXML(virConnectPtr conn, @@ -1776,6 +1813,11 @@ virDomainHostdevDefParseXML(virConnectPtr conn, if (virDomainHostdevSubsysPciDefParseXML(conn, cur, def) < 0) goto error; } + if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV) { + if (virDomainHostdevSubsysNodedevDefParseXML(conn, cur, def) < 0) + goto error; + } } else { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, _("unknown node %s"), cur->name); @@ -3178,7 +3220,10 @@ virDomainHostdevDefFormat(virConnectPtr conn, } type = virDomainHostdevSubsysTypeToString(def->source.subsys.type); - if (!type || (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB && def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) ) { + if (!type || + (def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB && + def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI && + def->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV) ) { virDomainReportError(conn, VIR_ERR_INTERNAL_ERROR, _("unexpected hostdev type %d"), def->source.subsys.type); @@ -3207,6 +3252,10 @@ virDomainHostdevDefFormat(virConnectPtr conn, def->source.subsys.u.pci.slot, def->source.subsys.u.pci.function); } + if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV) { + virBufferVSprintf(buf, " <nodedev name='%s'/>\n", + def->source.subsys.u.nodedev_name); + } virBufferAddLit(buf, " </source>\n"); virBufferAddLit(buf, " </hostdev>\n"); diff --git a/src/domain_conf.h b/src/domain_conf.h index b6f6b43..bde3417 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -297,6 +297,7 @@ enum virDomainHostdevMode { enum virDomainHostdevSubsysType { VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI, + VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV, VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST }; @@ -322,6 +323,7 @@ struct _virDomainHostdevDef { unsigned slot; unsigned function; } pci; + char *nodedev_name; } u; } subsys; struct { diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml new file mode 100644 index 0000000..96c6112 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-nodedev-name.xml @@ -0,0 +1,27 @@ +<domain type='qemu'> + <name>QEMUGuest2</name> + <uuid>c7a5fdbd-edaf-9466-926a-d65c16db1809</uuid> + <memory>219200</memory> + <currentMemory>219200</currentMemory> + <vcpu>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/QEMUGuest2'/> + <target dev='hda' bus='ide'/> + </disk> + <hostdev mode='subsystem' type='nodedev'> + <source> + <nodedev name='pci_8086_109a'/> + </source> + </hostdev> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 90b4740..9490d0b 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -245,6 +245,11 @@ mymain(int argc, char **argv) DO_TEST("hostdev-pci-address", 0); + /* Cannot resolve node device names here + * + * DO_TEST("hostdev-nodedev-name", 0); + */ + DO_TEST_FULL("restore-v1", QEMUD_CMD_FLAG_MIGRATE_KVM_STDIO, "stdio"); DO_TEST_FULL("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "stdio"); DO_TEST_FULL("restore-v2", QEMUD_CMD_FLAG_MIGRATE_QEMU_EXEC, "exec:cat"); diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index ab9943d..5ccace8 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -130,6 +130,7 @@ mymain(int argc, char **argv) DO_TEST("hostdev-usb-product"); DO_TEST("hostdev-usb-address"); DO_TEST("hostdev-pci-address"); + DO_TEST("hostdev-nodedev-name"); virCapabilitiesFree(driver.caps); -- 1.6.0.6 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list