From f83c7c88c54842d0ccd54255d718995e0aa779a4 Mon Sep 17 00:00:00 2001 From: Erik Skultety Date: Fri, 12 Jan 2018 13:14:26 +0100 Subject: [PATCH] nodedev: Move the sysfs-related cap handling to node_device_conf.c The capabilities are defined/parsed/formatted/queried from this module, no reason for 'update' not being part of the module as well. This also involves some module-specific prefix changes. This patch also drops the node_device_linux_sysfs module from the repo since: a) it only contained the capability handlers we just moved b) it's only linked with the driver (by design) and thus unreachable to other modules c) we touch sysfs across all the src/util modules so the module being deleted hasn't been serving its original intention for some time already. Signed-off-by: Erik Skultety --- src/Makefile.am | 4 +- src/conf/node_device_conf.c | 154 +++++++++++++++- src/conf/node_device_conf.h | 7 + src/libvirt_private.syms | 2 + src/node_device/node_device_driver.c | 7 +- src/node_device/node_device_hal.c | 1 - src/node_device/node_device_linux_sysfs.c | 206 ---------------------- src/node_device/node_device_linux_sysfs.h | 33 ---- src/node_device/node_device_udev.c | 5 +- 9 files changed, 168 insertions(+), 251 deletions(-) delete mode 100644 src/node_device/node_device_linux_sysfs.c delete mode 100644 src/node_device/node_device_linux_sysfs.h diff --git a/src/Makefile.am b/src/Makefile.am index 289b037472..b0ddfdfb75 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1168,9 +1168,7 @@ ACCESS_DRIVER_POLKIT_POLICY = \ NODE_DEVICE_DRIVER_SOURCES = \ node_device/node_device_driver.c \ - node_device/node_device_driver.h \ - node_device/node_device_linux_sysfs.c \ - node_device/node_device_linux_sysfs.h + node_device/node_device_driver.h NODE_DEVICE_DRIVER_HAL_SOURCES = \ node_device/node_device_hal.c \ diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c index a72a742bc8..d3c3618281 100644 --- a/src/conf/node_device_conf.c +++ b/src/conf/node_device_conf.c @@ -33,11 +33,13 @@ #include "virstring.h" #include "node_device_conf.h" #include "device_conf.h" +#include "dirname.h" #include "virxml.h" #include "virbuffer.h" #include "viruuid.h" #include "virrandom.h" #include "virlog.h" +#include "virfcp.h" #define VIR_FROM_THIS VIR_FROM_NODEDEV @@ -2514,10 +2516,160 @@ virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host) return ret; } + +int +virNodeDeviceGetSCSITargetCaps(const char *sysfsPath, + virNodeDevCapSCSITargetPtr scsi_target) +{ + int ret = -1; + char *dir = NULL, *rport = NULL; + + VIR_DEBUG("Checking if '%s' is an FC remote port", scsi_target->name); + + /* /sys/devices/[...]/host0/rport-0:0-0/target0:0:0 -> rport-0:0-0 */ + if (!(dir = mdir_name(sysfsPath))) + return -1; + + if (VIR_STRDUP(rport, last_component(dir)) < 0) + goto cleanup; + + if (!virFCIsCapableRport(rport)) + goto cleanup; + + VIR_FREE(scsi_target->rport); + VIR_STEAL_PTR(scsi_target->rport, rport); + + if (virFCReadRportValue(scsi_target->rport, "port_name", + &scsi_target->wwpn) < 0) { + VIR_WARN("Failed to read port_name for '%s'", scsi_target->rport); + goto cleanup; + } + + scsi_target->flags |= VIR_NODE_DEV_CAP_FLAG_FC_RPORT; + ret = 0; + + cleanup: + if (ret < 0) { + VIR_FREE(scsi_target->rport); + VIR_FREE(scsi_target->wwpn); + scsi_target->flags &= ~VIR_NODE_DEV_CAP_FLAG_FC_RPORT; + } + VIR_FREE(rport); + VIR_FREE(dir); + + return ret; +} + + +static int +virNodeDeviceGetPCISRIOVCaps(const char *sysfsPath, + virNodeDevCapPCIDevPtr pci_dev) +{ + size_t i; + int ret; + + /* this could be a refresh, so clear out the old data */ + for (i = 0; i < pci_dev->num_virtual_functions; i++) + VIR_FREE(pci_dev->virtual_functions[i]); + VIR_FREE(pci_dev->virtual_functions); + pci_dev->num_virtual_functions = 0; + pci_dev->max_virtual_functions = 0; + pci_dev->flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION; + pci_dev->flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION; + + ret = virPCIGetPhysicalFunction(sysfsPath, + &pci_dev->physical_function); + if (ret < 0) + goto cleanup; + + if (pci_dev->physical_function) + pci_dev->flags |= VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION; + + ret = virPCIGetVirtualFunctions(sysfsPath, &pci_dev->virtual_functions, + &pci_dev->num_virtual_functions, + &pci_dev->max_virtual_functions); + if (ret < 0) + goto cleanup; + + if (pci_dev->num_virtual_functions > 0 || + pci_dev->max_virtual_functions > 0) + pci_dev->flags |= VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION; + + cleanup: + return ret; +} + + +static int +virNodeDeviceGetPCIIOMMUGroupCaps(virNodeDevCapPCIDevPtr pci_dev) +{ + size_t i; + int tmpGroup, ret = -1; + virPCIDeviceAddress addr; + + /* this could be a refresh, so clear out the old data */ + for (i = 0; i < pci_dev->nIommuGroupDevices; i++) + VIR_FREE(pci_dev->iommuGroupDevices[i]); + VIR_FREE(pci_dev->iommuGroupDevices); + pci_dev->nIommuGroupDevices = 0; + pci_dev->iommuGroupNumber = 0; + + addr.domain = pci_dev->domain; + addr.bus = pci_dev->bus; + addr.slot = pci_dev->slot; + addr.function = pci_dev->function; + tmpGroup = virPCIDeviceAddressGetIOMMUGroupNum(&addr); + if (tmpGroup == -1) { + /* error was already reported */ + goto cleanup; + } + if (tmpGroup == -2) { + /* -2 return means there is no iommu_group data */ + ret = 0; + goto cleanup; + } + if (tmpGroup >= 0) { + if (virPCIDeviceAddressGetIOMMUGroupAddresses(&addr, &pci_dev->iommuGroupDevices, + &pci_dev->nIommuGroupDevices) < 0) + goto cleanup; + pci_dev->iommuGroupNumber = tmpGroup; + } + + ret = 0; + cleanup: + return ret; +} + + +/* virNodeDeviceGetPCIDynamicCaps() get info that is stored in sysfs + * about devices related to this device, i.e. things that can change + * without this device itself changing. These must be refreshed + * anytime full XML of the device is requested, because they can + * change with no corresponding notification from the kernel/udev. + */ +int +virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath, + virNodeDevCapPCIDevPtr pci_dev) +{ + if (virNodeDeviceGetPCISRIOVCaps(sysfsPath, pci_dev) < 0) + return -1; + if (virNodeDeviceGetPCIIOMMUGroupCaps(pci_dev) < 0) + return -1; + return 0; +} + #else int -virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host ATTRIBUTE_UNUSED) +virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath ATTRIBUTE_UNUSED, + virNodeDevCapPCIDevPtr pci_dev ATTRIBUTE_UNUSED) +{ + return -1; +} + + +int virNodeDeviceGetSCSITargetCaps(const char *sysfsPath ATTRIBUTE_UNUSED, + virNodeDevCapSCSITargetPtr scsi_target ATTRIBUTE_UNUSED) { return -1; } diff --git a/src/conf/node_device_conf.h b/src/conf/node_device_conf.h index cf79773aa0..4e3154875e 100644 --- a/src/conf/node_device_conf.h +++ b/src/conf/node_device_conf.h @@ -393,4 +393,11 @@ virNodeDeviceDeleteVport(virConnectPtr conn, int virNodeDeviceGetSCSIHostCaps(virNodeDevCapSCSIHostPtr scsi_host); +int +virNodeDeviceGetSCSITargetCaps(const char *sysfsPath, + virNodeDevCapSCSITargetPtr scsi_target); + +int +virNodeDeviceGetPCIDynamicCaps(const char *sysfsPath, + virNodeDevCapPCIDevPtr pci_dev); #endif /* __VIR_NODE_DEVICE_CONF_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index f2a2c8650d..1467796d4b 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -707,7 +707,9 @@ virNodeDeviceDefParseNode; virNodeDeviceDefParseString; virNodeDeviceDeleteVport; virNodeDeviceGetParentName; +virNodeDeviceGetPCIDynamicCaps; virNodeDeviceGetSCSIHostCaps; +virNodeDeviceGetSCSITargetCaps; virNodeDeviceGetWWNs; diff --git a/src/node_device/node_device_driver.c b/src/node_device/node_device_driver.c index a2f687942f..2e42d35274 100644 --- a/src/node_device/node_device_driver.c +++ b/src/node_device/node_device_driver.c @@ -38,7 +38,6 @@ #include "node_device_event.h" #include "node_device_driver.h" #include "node_device_hal.h" -#include "node_device_linux_sysfs.h" #include "virvhba.h" #include "viraccessapicheck.h" #include "virnetdev.h" @@ -59,7 +58,7 @@ nodeDeviceUpdateCaps(virNodeDeviceDefPtr def) virNodeDeviceGetSCSIHostCaps(&cap->data.scsi_host); break; case VIR_NODE_DEV_CAP_SCSI_TARGET: - nodeDeviceSysfsGetSCSITargetCaps(def->sysfs_path, + virNodeDeviceGetSCSITargetCaps(def->sysfs_path, &cap->data.scsi_target); break; case VIR_NODE_DEV_CAP_NET: @@ -70,8 +69,8 @@ nodeDeviceUpdateCaps(virNodeDeviceDefPtr def) return -1; break; case VIR_NODE_DEV_CAP_PCI_DEV: - if (nodeDeviceSysfsGetPCIRelatedDevCaps(def->sysfs_path, - &cap->data.pci_dev) < 0) + if (virNodeDeviceGetPCIDynamicCaps(def->sysfs_path, + &cap->data.pci_dev) < 0) return -1; break; diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c index 9fac5780e7..26fcd7918c 100644 --- a/src/node_device/node_device_hal.c +++ b/src/node_device/node_device_hal.c @@ -31,7 +31,6 @@ #include "node_device_conf.h" #include "node_device_driver.h" #include "node_device_hal.h" -#include "node_device_linux_sysfs.h" #include "virerror.h" #include "driver.h" #include "datatypes.h" diff --git a/src/node_device/node_device_linux_sysfs.c b/src/node_device/node_device_linux_sysfs.c deleted file mode 100644 index b3f80a5554..0000000000 --- a/src/node_device/node_device_linux_sysfs.c +++ /dev/null @@ -1,206 +0,0 @@ -/* - * node_device_linux_sysfs.c: Linux specific code to gather device data - * that is available from sysfs (but not from UDEV or HAL). - * - * 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 - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - */ - -#include - -#include -#include -#include - -#include "dirname.h" -#include "node_device_driver.h" -#include "node_device_hal.h" -#include "node_device_linux_sysfs.h" -#include "virerror.h" -#include "viralloc.h" -#include "virfcp.h" -#include "virlog.h" -#include "virfile.h" -#include "virscsihost.h" -#include "virstring.h" -#include "virvhba.h" - -#define VIR_FROM_THIS VIR_FROM_NODEDEV - -#ifdef __linux__ - -VIR_LOG_INIT("node_device.node_device_linux_sysfs"); - - -int -nodeDeviceSysfsGetSCSITargetCaps(const char *sysfsPath, - virNodeDevCapSCSITargetPtr scsi_target) -{ - int ret = -1; - char *dir = NULL, *rport = NULL; - - VIR_DEBUG("Checking if '%s' is an FC remote port", scsi_target->name); - - /* /sys/devices/[...]/host0/rport-0:0-0/target0:0:0 -> rport-0:0-0 */ - if (!(dir = mdir_name(sysfsPath))) - return -1; - - if (VIR_STRDUP(rport, last_component(dir)) < 0) - goto cleanup; - - if (!virFCIsCapableRport(rport)) - goto cleanup; - - VIR_FREE(scsi_target->rport); - VIR_STEAL_PTR(scsi_target->rport, rport); - - if (virFCReadRportValue(scsi_target->rport, "port_name", - &scsi_target->wwpn) < 0) { - VIR_WARN("Failed to read port_name for '%s'", scsi_target->rport); - goto cleanup; - } - - scsi_target->flags |= VIR_NODE_DEV_CAP_FLAG_FC_RPORT; - ret = 0; - - cleanup: - if (ret < 0) { - VIR_FREE(scsi_target->rport); - VIR_FREE(scsi_target->wwpn); - scsi_target->flags &= ~VIR_NODE_DEV_CAP_FLAG_FC_RPORT; - } - VIR_FREE(rport); - VIR_FREE(dir); - - return ret; -} - - -static int -nodeDeviceSysfsGetPCISRIOVCaps(const char *sysfsPath, - virNodeDevCapPCIDevPtr pci_dev) -{ - size_t i; - int ret; - - /* this could be a refresh, so clear out the old data */ - for (i = 0; i < pci_dev->num_virtual_functions; i++) - VIR_FREE(pci_dev->virtual_functions[i]); - VIR_FREE(pci_dev->virtual_functions); - pci_dev->num_virtual_functions = 0; - pci_dev->max_virtual_functions = 0; - pci_dev->flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION; - pci_dev->flags &= ~VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION; - - ret = virPCIGetPhysicalFunction(sysfsPath, - &pci_dev->physical_function); - if (ret < 0) - goto cleanup; - - if (pci_dev->physical_function) - pci_dev->flags |= VIR_NODE_DEV_CAP_FLAG_PCI_PHYSICAL_FUNCTION; - - ret = virPCIGetVirtualFunctions(sysfsPath, &pci_dev->virtual_functions, - &pci_dev->num_virtual_functions, - &pci_dev->max_virtual_functions); - if (ret < 0) - goto cleanup; - - if (pci_dev->num_virtual_functions > 0 || - pci_dev->max_virtual_functions > 0) - pci_dev->flags |= VIR_NODE_DEV_CAP_FLAG_PCI_VIRTUAL_FUNCTION; - - cleanup: - return ret; -} - - -static int -nodeDeviceSysfsGetPCIIOMMUGroupCaps(virNodeDevCapPCIDevPtr pci_dev) -{ - size_t i; - int tmpGroup, ret = -1; - virPCIDeviceAddress addr; - - /* this could be a refresh, so clear out the old data */ - for (i = 0; i < pci_dev->nIommuGroupDevices; i++) - VIR_FREE(pci_dev->iommuGroupDevices[i]); - VIR_FREE(pci_dev->iommuGroupDevices); - pci_dev->nIommuGroupDevices = 0; - pci_dev->iommuGroupNumber = 0; - - addr.domain = pci_dev->domain; - addr.bus = pci_dev->bus; - addr.slot = pci_dev->slot; - addr.function = pci_dev->function; - tmpGroup = virPCIDeviceAddressGetIOMMUGroupNum(&addr); - if (tmpGroup == -1) { - /* error was already reported */ - goto cleanup; - } - if (tmpGroup == -2) { - /* -2 return means there is no iommu_group data */ - ret = 0; - goto cleanup; - } - if (tmpGroup >= 0) { - if (virPCIDeviceAddressGetIOMMUGroupAddresses(&addr, &pci_dev->iommuGroupDevices, - &pci_dev->nIommuGroupDevices) < 0) - goto cleanup; - pci_dev->iommuGroupNumber = tmpGroup; - } - - ret = 0; - cleanup: - return ret; -} - - -/* nodeDeviceSysfsGetPCIRelatedCaps() get info that is stored in sysfs - * about devices related to this device, i.e. things that can change - * without this device itself changing. These must be refreshed - * anytime full XML of the device is requested, because they can - * change with no corresponding notification from the kernel/udev. - */ -int -nodeDeviceSysfsGetPCIRelatedDevCaps(const char *sysfsPath, - virNodeDevCapPCIDevPtr pci_dev) -{ - if (nodeDeviceSysfsGetPCISRIOVCaps(sysfsPath, pci_dev) < 0) - return -1; - if (nodeDeviceSysfsGetPCIIOMMUGroupCaps(pci_dev) < 0) - return -1; - return 0; -} - - -#else - -int nodeDeviceSysfsGetSCSITargetCaps(const char *sysfsPath ATTRIBUTE_UNUSED, - virNodeDevCapSCSITargetPtr scsi_target ATTRIBUTE_UNUSED) -{ - return -1; -} - -int -nodeDeviceSysfsGetPCIRelatedDevCaps(const char *sysfsPath ATTRIBUTE_UNUSED, - virNodeDevCapPCIDevPtr pci_dev ATTRIBUTE_UNUSED) -{ - return -1; -} - -#endif /* __linux__ */ diff --git a/src/node_device/node_device_linux_sysfs.h b/src/node_device/node_device_linux_sysfs.h deleted file mode 100644 index 9392d69349..0000000000 --- a/src/node_device/node_device_linux_sysfs.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * node_device_linux_sysfs.h: Linux specific code to gather device data - * that is available from sysfs (but not from UDEV or HAL). - * - * Copyright (C) 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 - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - * - */ - -#ifndef __VIR_NODE_DEVICE_LINUX_SYSFS_H__ -# define __VIR_NODE_DEVICE_LINUX_SYSFS_H__ - -# include "node_device_conf.h" - -int nodeDeviceSysfsGetSCSITargetCaps(const char *sysfsPath, - virNodeDevCapSCSITargetPtr scsi_target); -int nodeDeviceSysfsGetPCIRelatedDevCaps(const char *sysfsPath, - virNodeDevCapPCIDevPtr pci_dev); - -#endif /* __VIR_NODE_DEVICE_LINUX_SYSFS_H__ */ diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c index 4cc531d2c1..519b0bf6fa 100644 --- a/src/node_device/node_device_udev.c +++ b/src/node_device/node_device_udev.c @@ -30,7 +30,6 @@ #include "node_device_conf.h" #include "node_device_event.h" #include "node_device_driver.h" -#include "node_device_linux_sysfs.h" #include "node_device_udev.h" #include "virerror.h" #include "driver.h" @@ -558,7 +557,7 @@ udevProcessPCI(struct udev_device *device, &pci_dev->numa_node, 10) < 0) goto cleanup; - if (nodeDeviceSysfsGetPCIRelatedDevCaps(def->sysfs_path, pci_dev) < 0) + if (virNodeDeviceGetPCIDynamicCaps(def->sysfs_path, pci_dev) < 0) goto cleanup; if (!(pciDev = virPCIDeviceNew(pci_dev->domain, @@ -802,7 +801,7 @@ udevProcessSCSITarget(struct udev_device *device, if (VIR_STRDUP(scsi_target->name, sysname) < 0) return -1; - nodeDeviceSysfsGetSCSITargetCaps(def->sysfs_path, &def->caps->data.scsi_target); + virNodeDeviceGetSCSITargetCaps(def->sysfs_path, &def->caps->data.scsi_target); if (udevGenerateDeviceName(device, def, NULL) != 0) return -1;