networkCreateInterfacePool(virNetworkDefPtr netdef)
{
size_t numVirtFns = 0;
+ unsigned int maxVirtFns = 0;
char **vfNames = NULL;
virPCIDeviceAddressPtr *virtFns;
if (netdef->forward.npfs == 0 || netdef->forward.nifs > 0)
return 0;
- if ((virNetDevGetVirtualFunctions(netdef->forward.pfs->dev,
- &vfNames, &virtFns, &numVirtFns)) < 0) {
+ if ((virNetDevGetVirtualFunctions(netdef->forward.pfs->dev, &vfNames,
+ &virtFns, &numVirtFns, &maxVirtFns)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not get Virtual functions on %s"),
netdef->forward.pfs->dev);
VIR_FREE(data->pci_dev.virtual_functions[i]);
VIR_FREE(data->pci_dev.virtual_functions);
data->pci_dev.num_virtual_functions = 0;
+ data->pci_dev.max_virtual_functions = 0;
data->pci_dev.flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION;
data->pci_dev.flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION;
data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION;
ret = virPCIGetVirtualFunctions(sysfsPath, &data->pci_dev.virtual_functions,
- &data->pci_dev.num_virtual_functions);
+ &data->pci_dev.num_virtual_functions,
+ &data->pci_dev.max_virtual_functions);
if (ret < 0)
return ret;
- if (data->pci_dev.num_virtual_functions > 0)
+ if (data->pci_dev.num_virtual_functions > 0 ||
+ data->pci_dev.max_virtual_functions > 0)
data->pci_dev.flags |= VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION;
return ret;
virNetDevGetVirtualFunctions(const char *pfname,
char ***vfname,
virPCIDeviceAddressPtr **virt_fns,
- size_t *n_vfname)
+ size_t *n_vfname,
+ unsigned int *max_vfs)
{
int ret = -1;
size_t i;
*virt_fns = NULL;
*n_vfname = 0;
+ *max_vfs = 0;
if (virNetDevSysfsFile(&pf_sysfs_device_link, pfname, "device") < 0)
return ret;
if (virPCIGetVirtualFunctions(pf_sysfs_device_link, virt_fns,
- n_vfname) < 0)
+ n_vfname, max_vfs) < 0)
goto cleanup;
if (VIR_ALLOC_N(*vfname, *n_vfname) < 0)
virNetDevGetVirtualFunctions(const char *pfname ATTRIBUTE_UNUSED,
char ***vfname ATTRIBUTE_UNUSED,
virPCIDeviceAddressPtr **virt_fns ATTRIBUTE_UNUSED,
- size_t *n_vfname ATTRIBUTE_UNUSED)
+ size_t *n_vfname ATTRIBUTE_UNUSED,
+ unsigned int *max_vfs ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
_("Unable to get virtual functions on this platform"));
int virNetDevGetVirtualFunctions(const char *pfname,
char ***vfname,
virPCIDeviceAddressPtr **virt_fns,
- size_t *n_vfname)
+ size_t *n_vfname,
+ unsigned int *max_vfs)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
- ATTRIBUTE_NONNULL(4) ATTRIBUTE_RETURN_CHECK;
+ ATTRIBUTE_NONNULL(4) ATTRIBUTE_NONNULL(5) ATTRIBUTE_RETURN_CHECK;
int virNetDevLinkDump(const char *ifname, int ifindex,
void **nlData, struct nlattr **tb,
/*
* virpci.c: helper APIs for managing host PCI devices
*
- * Copyright (C) 2009-2014 Red Hat, Inc.
+ * Copyright (C) 2009-2015 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
int
virPCIGetVirtualFunctions(const char *sysfs_path,
virPCIDeviceAddressPtr **virtual_functions,
- size_t *num_virtual_functions)
+ size_t *num_virtual_functions,
+ unsigned int *max_virtual_functions)
{
int ret = -1;
size_t i;
char *device_link = NULL;
virPCIDeviceAddress *config_addr = NULL;
+ char *totalvfs_file = NULL, *totalvfs_str = NULL;
VIR_DEBUG("Attempting to get SR IOV virtual functions for device"
"with sysfs path '%s'", sysfs_path);
*virtual_functions = NULL;
*num_virtual_functions = 0;
+ *max_virtual_functions = 0;
+
+ if (virAsprintf(&totalvfs_file, "%s/sriov_totalvfs", sysfs_path) < 0)
+ goto error;
+ if (virFileExists(totalvfs_file)) {
+ char *end = NULL; /* so that terminating \n doesn't create error */
+
+ if (virFileReadAll(totalvfs_file, 16, &totalvfs_str) < 0)
+ goto error;
+ if (virStrToLong_ui(totalvfs_str, &end, 10, max_virtual_functions) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Unrecognized value in %s: %s"),
+ totalvfs_file, totalvfs_str);
+ goto error;
+ }
+ }
do {
/* look for virtfn%d links until one isn't found */
cleanup:
VIR_FREE(device_link);
VIR_FREE(config_addr);
+ VIR_FREE(totalvfs_file);
+ VIR_FREE(totalvfs_str);
return ret;
error:
int ret = -1;
size_t i;
size_t num_virt_fns = 0;
+ unsigned int max_virt_fns = 0;
virPCIDeviceAddressPtr vf_bdf = NULL;
virPCIDeviceAddressPtr *virt_fns = NULL;
return ret;
if (virPCIGetVirtualFunctions(pf_sysfs_device_link, &virt_fns,
- &num_virt_fns) < 0) {
+ &num_virt_fns, &max_virt_fns) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Error getting physical function's '%s' "
"virtual_functions"), pf_sysfs_device_link);
int
virPCIGetVirtualFunctions(const char *sysfs_path ATTRIBUTE_UNUSED,
virPCIDeviceAddressPtr **virtual_functions ATTRIBUTE_UNUSED,
- size_t *num_virtual_functions ATTRIBUTE_UNUSED)
+ size_t *num_virtual_functions ATTRIBUTE_UNUSED,
+ unsigned int *max_virtual_functions ATTRIBUTE_UNUSED)
{
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
return -1;
/*
* virpci.h: helper APIs for managing host PCI devices
*
- * Copyright (C) 2009, 2011-2014 Red Hat, Inc.
+ * Copyright (C) 2009, 2011-2015 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
int virPCIGetVirtualFunctions(const char *sysfs_path,
virPCIDeviceAddressPtr **virtual_functions,
- size_t *num_virtual_functions);
+ size_t *num_virtual_functions,
+ unsigned int *max_virtual_functions);
int virPCIIsVirtualFunction(const char *vf_sysfs_device_link);