[libvirt] [PATCH 0/2] Dettach and reset devices before assigning to guests

Hi, The following two patches build on the previous series. The idea is simple - when starting a guest, we should automatically dettach and reset any devices assigned to it. Rather than change the semantics of the existing hostdev source, we only do this when the node device name is used as the hostdev source. Directly specifying the device address rather than its name can be seen as an option for people who know what they're doing. Cheers, Mark.

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@redhat.com> --- 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@redhat.com> + + * 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@redhat.com> * 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

Handle a hostdev source specified as a node device name by looking up the node device, parsing its XML for PCI/USB address details, using those as the hostdev source and, finally, dettaching and resetting the device. Signed-off-by: Mark McLoughlin <markmc@redhat.com> --- src/qemu_conf.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 102 insertions(+), 13 deletions(-) diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 6f58ee8..dd35f9a 100644 --- a/src/qemu_conf.c +++ b/src/qemu_conf.c @@ -47,6 +47,7 @@ #include "datatypes.h" #include "xml.h" #include "nodeinfo.h" +#include "node_device_conf.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -629,6 +630,69 @@ qemudNetworkIfaceConnect(virConnectPtr conn, } +static int qemudResolveHostdev(virConnectPtr conn, virDomainHostdevDefPtr hostdev) +{ + virNodeDevicePtr dev = NULL; + virNodeDeviceDefPtr def = NULL; + virNodeDevCapsDefPtr cap; + char *xml = NULL; + int ret = 0; + + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV) + goto out; + + ret = -1; + + dev = virNodeDeviceLookupByName(conn, hostdev->source.subsys.u.nodedev_name); + if (!dev) + goto out; + + xml = virNodeDeviceGetXMLDesc(dev, 0); + if (!xml) + goto out; + + def = virNodeDeviceDefParseString(dev->conn, xml); + if (!def) + goto out; + + cap = def->caps; + while (cap) { + if (cap->type == VIR_NODE_DEV_CAP_USB_DEV) { + hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB; + hostdev->source.subsys.u.usb.bus = cap->data.usb_dev.bus; + hostdev->source.subsys.u.usb.device = cap->data.usb_dev.device; + hostdev->source.subsys.u.usb.vendor = cap->data.usb_dev.vendor; + hostdev->source.subsys.u.usb.product = cap->data.usb_dev.product; + break; + } else if (cap->type == VIR_NODE_DEV_CAP_PCI_DEV) { + hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; + hostdev->source.subsys.u.pci.domain = cap->data.pci_dev.domain; + hostdev->source.subsys.u.pci.bus = cap->data.pci_dev.bus; + hostdev->source.subsys.u.pci.slot = cap->data.pci_dev.slot; + hostdev->source.subsys.u.pci.function = cap->data.pci_dev.function; + break; + } + cap = cap->next; + } + + if (!cap) { + qemudReportError(dev->conn, NULL, NULL, VIR_ERR_INVALID_ARG, + _("device %s is not a PCI or USB device"), dev->name); + goto out; + } + + if (virNodeDeviceDettach(dev) < 0) + goto out; + + ret = 0; +out: + virNodeDeviceDefFree(def); + VIR_FREE(xml); + virNodeDeviceFree(dev); + return ret; +} + static int qemudBuildCommandLineChrDevStr(virDomainChrDefPtr dev, char *buf, int buflen) @@ -1357,20 +1421,23 @@ int qemudBuildCommandLine(virConnectPtr conn, int ret; char* usbdev; char* pcidev; - virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i]; + virDomainHostdevDef hostdev = *vm->def->hostdevs[i]; + + if (qemudResolveHostdev(conn, &hostdev) < 0) + goto error; /* USB */ - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { - if(hostdev->source.subsys.u.usb.vendor) { + if (hostdev.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev.source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { + if(hostdev.source.subsys.u.usb.vendor) { ret = virAsprintf(&usbdev, "host:%.4x:%.4x", - hostdev->source.subsys.u.usb.vendor, - hostdev->source.subsys.u.usb.product); + hostdev.source.subsys.u.usb.vendor, + hostdev.source.subsys.u.usb.product); } else { ret = virAsprintf(&usbdev, "host:%.3d.%.3d", - hostdev->source.subsys.u.usb.bus, - hostdev->source.subsys.u.usb.device); + hostdev.source.subsys.u.usb.bus, + hostdev.source.subsys.u.usb.device); } if (ret < 0) goto error; @@ -1381,12 +1448,12 @@ int qemudBuildCommandLine(virConnectPtr conn, } /* PCI */ - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && - hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { + if (hostdev.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev.source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { ret = virAsprintf(&pcidev, "host=%.2x:%.2x.%.1x", - hostdev->source.subsys.u.pci.bus, - hostdev->source.subsys.u.pci.slot, - hostdev->source.subsys.u.pci.function); + hostdev.source.subsys.u.pci.bus, + hostdev.source.subsys.u.pci.slot, + hostdev.source.subsys.u.pci.function); if (ret < 0) { pcidev = NULL; goto error; @@ -1395,7 +1462,29 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT(pcidev); VIR_FREE(pcidev); } + } + + /* Now try and reset passthrough node devices; we do this + * because we want to have dettached *all* devices before + * resetting *any* devices. */ + for (i = 0 ; i < vm->def->nhostdevs ; i++) { + virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i]; + virNodeDevicePtr dev; + + if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_NODEDEV) + continue; + + dev = virNodeDeviceLookupByName(conn, hostdev->source.subsys.u.nodedev_name); + if (!dev) + goto error; + + if (virNodeDeviceReset(dev) < 0) { + virNodeDeviceFree(dev); + goto error; + } + virNodeDeviceFree(dev); } if (migrateFrom) { -- 1.6.0.6

On Tue, Feb 24, 2009 at 10:35:39PM +0000, Mark McLoughlin wrote:
Handle a hostdev source specified as a node device name by looking up the node device, parsing its XML for PCI/USB address details, using those as the hostdev source and, finally, dettaching and resetting the device.
I don't think we should be calling back out to the public API from internal impl here. If the XML just uses the PCI address directly then we can easily call the internal pciDettach() and pciReAttach() APIs directly, and avoid the potential for thread deadlock that calling back out to public API could lead to. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Wed, 2009-02-25 at 15:14 +0000, Daniel P. Berrange wrote:
I don't think we should be calling back out to the public API from internal impl here. If the XML just uses the PCI address directly then we can easily call the internal pciDettach() and pciReAttach() APIs directly, and avoid the potential for thread deadlock that calling back out to public API could lead to.
Yep, that would make sense given that we won't be calling out to the public APIs to fetch the nodedev XML. Cheers, Mark.

On Tue, Feb 24, 2009 at 10:35:37PM +0000, Mark McLoughlin wrote:
Hi, The following two patches build on the previous series.
The idea is simple - when starting a guest, we should automatically dettach and reset any devices assigned to it.
Rather than change the semantics of the existing hostdev source, we only do this when the node device name is used as the hostdev source. Directly specifying the device address rather than its name can be seen as an option for people who know what they're doing.
I don't like this idea really. The reason we use the PCI address in the XML is because that is a guarenteed stable identifier. The names given to nodedevices are currently under such a guarentee. So if we used the nodedev naming and then a Fedora release switched from HAL to DeviceKit nodedev drivers, any guests with PCI devs attached wouuld be broken. NB, I *do* think we should define a standard stable naming for nodedevs, that is identical whether using HAL of DeviceKit, but even if we had that I don't particularly like idea of using the names here when we already have a workable addressing scheme in the XML. If we want to indicate whether the HV or caller should be responsible for attach/detach/reset operations, we should just add some boolean flag to the <hostdev> element. We'll also likely need to add something to the capabilities XML format to identify what PCI passthrough features are supported by a HV. eg, With your KVM patches we can mange the attach/detach/reset stuff internally, or leave it upto the mgmt app. The Xen impl though will have no such choice currently - XenD expects that you've done the attach/detach yourself, and merely does the reset stuff internally. Perhaps allow for autoattach="yes|no" or managed="yes|no" to indicate whether we should do a detach/attach internally or not. Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

On Wed, 2009-02-25 at 15:10 +0000, Daniel P. Berrange wrote:
I don't like this idea really. The reason we use the PCI address in the XML is because that is a guarenteed stable identifier. The names given to nodedevices are currently under such a guarentee. So if we used the nodedev naming and then a Fedora release switched from HAL to DeviceKit nodedev drivers, any guests with PCI devs attached wouuld be broken.
That's a fair point - it's unfortunate, but I do agree. Cheers, Mark.
participants (2)
-
Daniel P. Berrange
-
Mark McLoughlin