mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 19:41:16 +00:00
pci: new utility functions
* virPCIDeviceFindByIDs - find a device on a list w/o creating an object This makes searching for an existing device on a list lighter weight. * virPCIDeviceCopy - make a copy of an existing virPCIDevice object. * virPCIDeviceGetDriverPathAndName - construct new strings containing 1) the name of the driver bound to this device. 2) the full path to the sysfs config for that driver. (This code was lifted from virPCIDeviceUnbindFromStub, and replaced there with a call to this new function).
This commit is contained in:
parent
53e52b4ac3
commit
50a8d85035
@ -1688,6 +1688,7 @@ virObjectUnref;
|
|||||||
|
|
||||||
# util/virpci.h
|
# util/virpci.h
|
||||||
virPCIDeviceAddressGetSysfsFile;
|
virPCIDeviceAddressGetSysfsFile;
|
||||||
|
virPCIDeviceCopy;
|
||||||
virPCIDeviceDetach;
|
virPCIDeviceDetach;
|
||||||
virPCIDeviceFileIterate;
|
virPCIDeviceFileIterate;
|
||||||
virPCIDeviceFree;
|
virPCIDeviceFree;
|
||||||
@ -1704,6 +1705,7 @@ virPCIDeviceListAdd;
|
|||||||
virPCIDeviceListCount;
|
virPCIDeviceListCount;
|
||||||
virPCIDeviceListDel;
|
virPCIDeviceListDel;
|
||||||
virPCIDeviceListFind;
|
virPCIDeviceListFind;
|
||||||
|
virPCIDeviceListFindByIDs;
|
||||||
virPCIDeviceListFindIndex;
|
virPCIDeviceListFindIndex;
|
||||||
virPCIDeviceListGet;
|
virPCIDeviceListGet;
|
||||||
virPCIDeviceListNew;
|
virPCIDeviceListNew;
|
||||||
|
@ -880,6 +880,54 @@ virPCIFile(char **buffer, const char *device, const char *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* virPCIDeviceGetDriverPathAndName - put the path to the driver
|
||||||
|
* directory of the driver in use for this device in @path and the
|
||||||
|
* name of the driver in @name. Both could be NULL if it's not bound
|
||||||
|
* to any driver.
|
||||||
|
*
|
||||||
|
* Return 0 for success, -1 for error.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
virPCIDeviceGetDriverPathAndName(virPCIDevicePtr dev, char **path, char **name)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
char *drvlink = NULL;
|
||||||
|
|
||||||
|
*path = *name = NULL;
|
||||||
|
/* drvlink = "/sys/bus/pci/dddd:bb:ss.ff/driver" */
|
||||||
|
if (virPCIFile(&drvlink, dev->name, "driver") < 0)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (virFileIsLink(drvlink) != 1) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Invalid device %s driver file %s is not a symlink"),
|
||||||
|
dev->name, drvlink);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
if (virFileResolveLink(drvlink, path) < 0) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("Unable to resolve device %s driver symlink %s"),
|
||||||
|
dev->name, drvlink);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
/* path = "/sys/bus/pci/drivers/${drivername}" */
|
||||||
|
|
||||||
|
if (VIR_STRDUP(*name, last_component(*path)) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
/* name = "${drivername}" */
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
VIR_FREE(drvlink);
|
||||||
|
if (ret < 0) {
|
||||||
|
VIR_FREE(*path);
|
||||||
|
VIR_FREE(*name);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
virPCIProbeStubDriver(const char *driver)
|
virPCIProbeStubDriver(const char *driver)
|
||||||
{
|
{
|
||||||
@ -931,23 +979,7 @@ virPCIDeviceUnbindFromStub(virPCIDevicePtr dev)
|
|||||||
/* If the device is currently bound to one of the "well known"
|
/* If the device is currently bound to one of the "well known"
|
||||||
* stub drivers, then unbind it, otherwise ignore it.
|
* stub drivers, then unbind it, otherwise ignore it.
|
||||||
*/
|
*/
|
||||||
if (virPCIFile(&path, dev->name, "driver") < 0)
|
if (virPCIDeviceGetDriverPathAndName(dev, &drvdir, &driver) < 0)
|
||||||
goto cleanup;
|
|
||||||
/* path = "/sys/bus/pci/dddd:bb:ss.ff/driver" */
|
|
||||||
if (virFileIsLink(path) != 1) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Invalid device %s driver file %s is not a symlink"),
|
|
||||||
dev->name, path);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (virFileResolveLink(path, &drvdir) < 0) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
||||||
_("Unable to resolve device %s driver symlink %s"),
|
|
||||||
dev->name, path);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
/* drvdir = "/sys/bus/pci/drivers/${drivername}" */
|
|
||||||
if (VIR_STRDUP(driver, last_component(drvdir)) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!dev->unbind_from_stub)
|
if (!dev->unbind_from_stub)
|
||||||
@ -1473,6 +1505,32 @@ error:
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virPCIDevicePtr
|
||||||
|
virPCIDeviceCopy(virPCIDevicePtr dev)
|
||||||
|
{
|
||||||
|
virPCIDevicePtr copy;
|
||||||
|
|
||||||
|
if (VIR_ALLOC(copy) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* shallow copy to take care of most attributes */
|
||||||
|
*copy = *dev;
|
||||||
|
copy->path = copy->stubDriver = NULL;
|
||||||
|
if (VIR_STRDUP(copy->path, dev->path) < 0 ||
|
||||||
|
VIR_STRDUP(copy->stubDriver, dev->stubDriver) < 0) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
return copy;
|
||||||
|
|
||||||
|
error:
|
||||||
|
virPCIDeviceFree(copy);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
virPCIDeviceFree(virPCIDevicePtr dev)
|
virPCIDeviceFree(virPCIDevicePtr dev)
|
||||||
{
|
{
|
||||||
@ -1690,6 +1748,27 @@ virPCIDeviceListFindIndex(virPCIDeviceListPtr list, virPCIDevicePtr dev)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
virPCIDevicePtr
|
||||||
|
virPCIDeviceListFindByIDs(virPCIDeviceListPtr list,
|
||||||
|
unsigned int domain,
|
||||||
|
unsigned int bus,
|
||||||
|
unsigned int slot,
|
||||||
|
unsigned int function)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < list->count; i++) {
|
||||||
|
if (list->devs[i]->domain == domain &&
|
||||||
|
list->devs[i]->bus == bus &&
|
||||||
|
list->devs[i]->slot == slot &&
|
||||||
|
list->devs[i]->function == function)
|
||||||
|
return list->devs[i];
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
virPCIDevicePtr
|
virPCIDevicePtr
|
||||||
virPCIDeviceListFind(virPCIDeviceListPtr list, virPCIDevicePtr dev)
|
virPCIDeviceListFind(virPCIDeviceListPtr list, virPCIDevicePtr dev)
|
||||||
{
|
{
|
||||||
|
@ -45,6 +45,7 @@ virPCIDevicePtr virPCIDeviceNew(unsigned int domain,
|
|||||||
unsigned int bus,
|
unsigned int bus,
|
||||||
unsigned int slot,
|
unsigned int slot,
|
||||||
unsigned int function);
|
unsigned int function);
|
||||||
|
virPCIDevicePtr virPCIDeviceCopy(virPCIDevicePtr dev);
|
||||||
void virPCIDeviceFree(virPCIDevicePtr dev);
|
void virPCIDeviceFree(virPCIDevicePtr dev);
|
||||||
const char *virPCIDeviceGetName(virPCIDevicePtr dev);
|
const char *virPCIDeviceGetName(virPCIDevicePtr dev);
|
||||||
|
|
||||||
@ -94,6 +95,12 @@ void virPCIDeviceListDel(virPCIDeviceListPtr list,
|
|||||||
virPCIDevicePtr dev);
|
virPCIDevicePtr dev);
|
||||||
virPCIDevicePtr virPCIDeviceListFind(virPCIDeviceListPtr list,
|
virPCIDevicePtr virPCIDeviceListFind(virPCIDeviceListPtr list,
|
||||||
virPCIDevicePtr dev);
|
virPCIDevicePtr dev);
|
||||||
|
virPCIDevicePtr
|
||||||
|
virPCIDeviceListFindByIDs(virPCIDeviceListPtr list,
|
||||||
|
unsigned int domain,
|
||||||
|
unsigned int bus,
|
||||||
|
unsigned int slot,
|
||||||
|
unsigned int function);
|
||||||
int virPCIDeviceListFindIndex(virPCIDeviceListPtr list,
|
int virPCIDeviceListFindIndex(virPCIDeviceListPtr list,
|
||||||
virPCIDevicePtr dev);
|
virPCIDevicePtr dev);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user