This adds a new <hostdev managed='(yes|no)'> property indicating whether or not we should automatically dettach/reset. Signed-off-by: Mark McLoughlin <markmc@xxxxxxxxxx> --- docs/schemas/domain.rng | 6 +++ src/domain_conf.c | 12 +++++- src/domain_conf.h | 1 + src/qemu_conf.c | 42 ++++++++++++++++++++ .../qemuxml2argv-hostdev-pci-address.xml | 2 +- .../qemuxml2argv-hostdev-usb-address.xml | 2 +- .../qemuxml2argv-hostdev-usb-product.xml | 2 +- 7 files changed, 62 insertions(+), 5 deletions(-) diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index 04f6e78..8bd3ffb 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -911,6 +911,12 @@ <value>pci</value> </choice> </attribute> + <attribute name='managed'> + <choice> + <value>yes</value> + <value>no</value> + </choice> + </attribute> </optional> <group> <element name='source'> diff --git a/src/domain_conf.c b/src/domain_conf.c index 622665c..23618b9 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -1729,7 +1729,7 @@ virDomainHostdevDefParseXML(virConnectPtr conn, xmlNodePtr cur; virDomainHostdevDefPtr def; - char *mode, *type = NULL; + char *mode, *type = NULL, *managed = NULL; if (VIR_ALLOC(def) < 0) { virReportOOMError(conn); @@ -1761,6 +1761,13 @@ virDomainHostdevDefParseXML(virConnectPtr conn, goto error; } + managed = virXMLPropString(node, "managed"); + if (managed != NULL) { + if (STREQ(managed, "yes")) + def->managed = 1; + VIR_FREE(managed); + } + cur = node->children; while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { @@ -3185,7 +3192,8 @@ virDomainHostdevDefFormat(virConnectPtr conn, return -1; } - virBufferVSprintf(buf, " <hostdev mode='%s' type='%s'>\n", mode, type); + virBufferVSprintf(buf, " <hostdev mode='%s' type='%s' managed='%s'>\n", + mode, type, def->managed ? "yes" : "no"); virBufferAddLit(buf, " <source>\n"); if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { diff --git a/src/domain_conf.h b/src/domain_conf.h index b6f6b43..d370b5d 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -305,6 +305,7 @@ typedef struct _virDomainHostdevDef virDomainHostdevDef; typedef virDomainHostdevDef *virDomainHostdevDefPtr; struct _virDomainHostdevDef { int mode; /* enum virDomainHostdevMode */ + unsigned int managed : 1; union { struct { int type; /* enum virDomainHostdevBusType */ diff --git a/src/qemu_conf.c b/src/qemu_conf.c index 6f58ee8..fad3eeb 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 "pci.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -1394,10 +1395,51 @@ int qemudBuildCommandLine(virConnectPtr conn, ADD_ARG_LIT("-pcidevice"); ADD_ARG_LIT(pcidev); VIR_FREE(pcidev); + + if (hostdev->managed) { + pciDevice *dev = pciGetDevice(conn, + hostdev->source.subsys.u.pci.domain, + hostdev->source.subsys.u.pci.bus, + hostdev->source.subsys.u.pci.slot, + hostdev->source.subsys.u.pci.function); + if (!dev) + goto error; + + if (pciDettachDevice(conn, dev) < 0) { + pciFreeDevice(conn, dev); + goto error; + } + + pciFreeDevice(conn, dev); + } } } + /* Now that all the PCI hostdevs have be dettached, we can reset them */ + for (i = 0 ; i < vm->def->nhostdevs ; i++) { + virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i]; + pciDevice *dev; + + if (!hostdev->managed || + hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) + continue; + + dev = pciGetDevice(conn, + hostdev->source.subsys.u.pci.domain, + hostdev->source.subsys.u.pci.bus, + hostdev->source.subsys.u.pci.slot, + hostdev->source.subsys.u.pci.function); + if (!dev) + goto error; + + if (pciResetDevice(conn, dev) < 0) + goto error; + + pciFreeDevice(conn, dev); + } + if (migrateFrom) { ADD_ARG_LIT("-incoming"); ADD_ARG_LIT(migrateFrom); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml index af2f400..9a6207e 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-address.xml @@ -18,7 +18,7 @@ <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hda' bus='ide'/> </disk> - <hostdev mode='subsystem' type='pci'> + <hostdev mode='subsystem' type='pci' managed='no'> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/> </source> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml index 0c044e1..61bb2a2 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-address.xml @@ -18,7 +18,7 @@ <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> </disk> - <hostdev mode='subsystem' type='usb'> + <hostdev mode='subsystem' type='usb' managed='no'> <source> <address bus='14' device='6'/> </source> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml index aecad4c..b861665 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-usb-product.xml @@ -18,7 +18,7 @@ <source dev='/dev/HostVG/QEMUGuest1'/> <target dev='hda' bus='ide'/> </disk> - <hostdev mode='subsystem' type='usb'> + <hostdev mode='subsystem' type='usb' managed='no'> <source> <vendor id='0x0204'/> <product id='0x6025'/> -- 1.6.0.6 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list