hypervisor api: new virNodeDeviceDetachFlags

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 assignment 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").
This commit is contained in:
Laine Stump 2013-04-24 12:56:10 -04:00
parent cc0a918872
commit 353941961a
4 changed files with 84 additions and 1 deletions

View File

@ -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);

View File

@ -603,6 +603,11 @@ typedef virDomainPtr
typedef int
(*virDrvNodeDeviceDettach)(virNodeDevicePtr dev);
typedef int
(*virDrvNodeDeviceDetachFlags)(virNodeDevicePtr dev,
const char *driverName,
unsigned int flags);
typedef int
(*virDrvNodeDeviceReAttach)(virNodeDevicePtr dev);
@ -1152,6 +1157,7 @@ struct _virDriver {
virDrvDomainMigratePrepare2 domainMigratePrepare2;
virDrvDomainMigrateFinish2 domainMigrateFinish2;
virDrvNodeDeviceDettach nodeDeviceDettach;
virDrvNodeDeviceDetachFlags nodeDeviceDetachFlags;
virDrvNodeDeviceReAttach nodeDeviceReAttach;
virDrvNodeDeviceReset nodeDeviceReset;
virDrvDomainMigratePrepareTunnel domainMigratePrepareTunnel;

View File

@ -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
@ -14722,6 +14727,70 @@ error:
return -1;
}
/**
* 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

View File

@ -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 ....