The existing virNodeDeviceDettach() assumes that there is only a
single PCI device assignment backend driver appropriate for any
hypervisor. This is no longer true, as the qemu driver is getting
support for PCI device assigment via VFIO. The new API
virNodeDeviceDetachFlags adds a driverName arg that should be set to
the exact same string set in a domain <hostdev>'s <driver
name='x'/>
element (i.e. "vfio", "kvm", or NULL for default). It also adds a
flags arg for good measure (and because it's possible we may need it
when we start dealing with VFIO's "device groups").
---
include/libvirt/libvirt.h.in | 5 +++-
src/driver.h | 6 ++++
src/libvirt.c | 69 ++++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 5 ++++
4 files changed, 84 insertions(+), 1 deletion(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 518f0fe..79c74fd 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -4,7 +4,7 @@
* Description: Provides the interfaces of the libvirt library to handle
* virtualized domains
*
- * Copyright (C) 2005-2006, 2010-2012 Red Hat, Inc.
+ * Copyright (C) 2005-2006, 2010-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -3289,6 +3289,9 @@ int virNodeDeviceRef (virNodeDevicePtr
dev);
int virNodeDeviceFree (virNodeDevicePtr dev);
int virNodeDeviceDettach (virNodeDevicePtr dev);
+int virNodeDeviceDetachFlags(virNodeDevicePtr dev,
+ const char *driverName,
+ unsigned int flags);
int virNodeDeviceReAttach (virNodeDevicePtr dev);
int virNodeDeviceReset (virNodeDevicePtr dev);
diff --git a/src/driver.h b/src/driver.h
index f6feb15..405e0a7 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -604,6 +604,11 @@ typedef int
(*virDrvNodeDeviceDettach)(virNodeDevicePtr dev);
typedef int
+(*virDrvNodeDeviceDetachFlags)(virNodeDevicePtr dev,
+ const char *driverName,
+ unsigned int flags);
+
+typedef int
(*virDrvNodeDeviceReAttach)(virNodeDevicePtr dev);
typedef int
@@ -1152,6 +1157,7 @@ struct _virDriver {
virDrvDomainMigratePrepare2 domainMigratePrepare2;
virDrvDomainMigrateFinish2 domainMigrateFinish2;
virDrvNodeDeviceDettach nodeDeviceDettach;
+ virDrvNodeDeviceDetachFlags nodeDeviceDetachFlags;
virDrvNodeDeviceReAttach nodeDeviceReAttach;
virDrvNodeDeviceReset nodeDeviceReset;
virDrvDomainMigratePrepareTunnel domainMigratePrepareTunnel;
diff --git a/src/libvirt.c b/src/libvirt.c
index c236152..2daa0b4 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -14687,6 +14687,11 @@ virNodeDeviceRef(virNodeDevicePtr dev)
* Once the device is not assigned to any guest, it may be re-attached
* to the node using the virNodeDeviceReattach() method.
*
+ * If the caller needs control over which backend driver will be used
+ * during PCI device assignment (to use something other than the
+ * default, for example VFIO), the newer virNodeDeviceDetachFlags()
+ * API should be used instead.
+ *
* Returns 0 in case of success, -1 in case of failure.
*/
int
@@ -14723,6 +14728,70 @@ error:
}
/**
+ * virNodeDeviceDetachFlags:
+ * @dev: pointer to the node device
+ * @driverName: name of backend driver that will be used
+ * for later device assignment to a domain. NULL
+ * means "use the hypervisor default driver"
+ * @flags: extra flags; not used yet, so callers should always pass 0
+ *
+ * Detach the node device from the node itself so that it may be
+ * assigned to a guest domain.
+ *
+ * Depending on the hypervisor, this may involve operations such as
+ * unbinding any device drivers from the device, binding the device to
+ * a dummy device driver and resetting the device. Different backend
+ * drivers expect the device to be bound to different dummy
+ * devices. For example, QEMU's "kvm" backend driver (the default)
+ * expects the device to be bound to "pci-stub", but its "vfio"
+ * backend driver expects the device to be bound to "vfio-pci".
+ *
+ * If the device is currently in use by the node, this method may
+ * fail.
+ *
+ * Once the device is not assigned to any guest, it may be re-attached
+ * to the node using the virNodeDeviceReAttach() method.
+ *
+ * Returns 0 in case of success, -1 in case of failure.
+ */
+int
+virNodeDeviceDetachFlags(virNodeDevicePtr dev,
+ const char *driverName,
+ unsigned int flags)
+{
+ VIR_DEBUG("dev=%p, conn=%p driverName=%s flags=%x",
+ dev, dev ? dev->conn : NULL,
+ driverName ? driverName : "(default)", flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_NODE_DEVICE(dev)) {
+ virLibNodeDeviceError(VIR_ERR_INVALID_NODE_DEVICE, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+
+ if (dev->conn->flags & VIR_CONNECT_RO) {
+ virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (dev->conn->driver->nodeDeviceDetachFlags) {
+ int ret;
+ ret = dev->conn->driver->nodeDeviceDetachFlags(dev, driverName, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(dev->conn);
+ return -1;
+}
+
+/**
* virNodeDeviceReAttach:
* @dev: pointer to the node device
*
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index ab993ed..dfbf44e 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -611,4 +611,9 @@ LIBVIRT_1.0.3 {
virNodeDeviceLookupSCSIHostByWWN;
} LIBVIRT_1.0.2;
+LIBVIRT_1.0.5 {
+ global:
+ virNodeDeviceDetachFlags;
+} LIBVIRT_1.0.3;
+
# .... define new API here using predicted next version number ....
--
1.7.11.7