rebase to 1.7.13

This commit is contained in:
Than Ngo 2021-09-15 11:52:23 +02:00
parent 01c6952697
commit b76ff1af36
9 changed files with 7 additions and 553 deletions

1
.gitignore vendored
View File

@ -14,3 +14,4 @@ lsvpd-1.6.8.tar.gz
/lsvpd-1.7.10.tar.gz
/lsvpd-1.7.11.tar.gz
/lsvpd-1.7.12.tar.gz
/lsvpd-1.7.13.tar.gz

View File

@ -1,24 +0,0 @@
commit 25ac29f309dd8192a3fe5c628d303b48593738e1
Author: Sathvika Vasireddy <sv@linux.vnet.ibm.com>
Date: Fri Aug 20 14:50:18 2021 +0530
lsvpd/gatherer: spelling correction
Fix a typo in description of Gatherer::getComponentTree() function
Signed-off-by: Sathvika Vasireddy <sv@linux.vnet.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
diff --git a/src/internal/sys_interface/gatherer.cpp b/src/internal/sys_interface/gatherer.cpp
index 638288b..1c14524 100644
--- a/src/internal/sys_interface/gatherer.cpp
+++ b/src/internal/sys_interface/gatherer.cpp
@@ -378,7 +378,7 @@ namespace lsvpd
}
/**
- * Contruct complete collection of devices on system,
+ * Construct complete collection of devices on system,
* by calling 'getComponents()' on each specific collector type
*
* @arg devs: a Component* vector, which will be filled with the

View File

@ -1,30 +0,0 @@
commit 32958b576e87ec517048a8e446a7a06b703a36d2
Author: Kamalesh Babulal <kamalesh@linux.ibm.com>
Date: Mon May 31 15:46:59 2021 +0530
sysfstreecollector: check path before return in getDevTreePath()
devspec holds the device-path for the device in the /proc/device-tree,
some cases this file may also hold "(null)" string as value. Check for
device-tree path before returning from getDevTreePath() and return
empty string like in the error cases for "(null)" case.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
diff --git a/src/internal/sys_interface/sysfstreecollector.cpp b/src/internal/sys_interface/sysfstreecollector.cpp
index 9e808de..7e7e13c 100644
--- a/src/internal/sys_interface/sysfstreecollector.cpp
+++ b/src/internal/sys_interface/sysfstreecollector.cpp
@@ -985,7 +985,10 @@ esc_subsystem_info:
fclose(fi);
// cleanup
- return string(buf2);
+ if (strcmp(buf2, "(null)"))
+ return string(buf2);
+
+ return string("");
}
/* Collects devices on system, then returns how many were found.

View File

@ -1,76 +0,0 @@
commit 4e93ccc44f61854c84d82de8de80c18c87b87957
Author: Kamalesh Babulal <kamalesh@linux.ibm.com>
Date: Mon May 31 15:47:01 2021 +0530
devicetreecollector: refactor the code of buildSCSILocCode()
Refactoring the code in buildSCSILocCode(), to make it more readable.
This patch doesn't change the logic of the function, it's needed for
the future patches, those will be altering the function
Signed-off-by: Kamalesh Babulal <kamalesh@linux.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
diff --git a/src/internal/sys_interface/devicetreecollector.cpp b/src/internal/sys_interface/devicetreecollector.cpp
index db4e8b5..dd55611 100644
--- a/src/internal/sys_interface/devicetreecollector.cpp
+++ b/src/internal/sys_interface/devicetreecollector.cpp
@@ -771,31 +771,33 @@ ERROR:
* scsi, ide, usb, etc that do not generate ibm,loc-code
* files for easy grabbing
*/
- if (fillMe->devBus.dataValue == "scsi") {
- parent = findSCSIParent(fillMe, devs);
-
- if (parent != NULL) {
- target = fillMe->getDeviceSpecific("XT");
- lun = fillMe->getDeviceSpecific("XL");
- bus = fillMe->getDeviceSpecific("XB");
- host = fillMe->getDeviceSpecific("XH");
- if (host != NULL && target != NULL &&
- lun != NULL && bus != NULL) {
- if (fillMe->mPhysicalLocation.dataValue != "")
- val << fillMe->mPhysicalLocation.dataValue;
- else if
- (parent->mPhysicalLocation.dataValue != "")
- val << parent->mPhysicalLocation.dataValue;
- else
- val << getAttrValue( parent->deviceTreeNode.dataValue,
- "ibm,loc-code" );
- val << "H" << host->dataValue << "-B" << bus->dataValue
- << "-T" << target->dataValue << "-L" << lun->dataValue;
- fillMe->mPhysicalLocation.setValue( val.str( ), 60 ,
- __FILE__, __LINE__ );
- }
- }
- }
+ if (fillMe->devBus.dataValue != "scsi")
+ return;
+
+ parent = findSCSIParent(fillMe, devs);
+ if (parent == NULL)
+ return;
+
+ target = fillMe->getDeviceSpecific("XT");
+ lun = fillMe->getDeviceSpecific("XL");
+ bus = fillMe->getDeviceSpecific("XB");
+ host = fillMe->getDeviceSpecific("XH");
+ if (host == NULL || target == NULL || lun == NULL || bus == NULL)
+ return;
+
+ if (fillMe->mPhysicalLocation.dataValue != "")
+ val << fillMe->mPhysicalLocation.dataValue;
+ else if (parent->mPhysicalLocation.dataValue != "")
+ val << parent->mPhysicalLocation.dataValue;
+ else
+ val << getAttrValue( parent->deviceTreeNode.dataValue,
+ "ibm,loc-code" );
+
+ val << "H" << host->dataValue << "-B" << bus->dataValue
+ << "-T" << target->dataValue << "-L" << lun->dataValue;
+
+ fillMe->mPhysicalLocation.setValue( val.str( ), 60 ,
+ __FILE__, __LINE__ );
}
void DeviceTreeCollector::getRtasSystemParams(vector<Component*>& devs)

View File

@ -1,28 +0,0 @@
commit 52793604fa715cd352ef9ba488f8215afee8bb73
Author: Kamalesh Babulal <kamalesh@linux.ibm.com>
Date: Tue Jun 8 18:53:05 2021 +0530
lsmcode: Fix catching polymorphic type by value
Fix the compile time warning:
src/output/lsmcode.cpp: In function 'std::string read_dt_property(const string&, const string&)':
src/output/lsmcode.cpp:181:39: warning: catching polymorphic type 'class std::ios_base::failure' by value [-Wcatch-value=]
181 | catch (std::ifstream::failure e) {
| ^
Signed-off-by: Kamalesh Babulal <kamalesh@linux.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
diff --git a/src/output/lsmcode.cpp b/src/output/lsmcode.cpp
index 557c008..4928461 100644
--- a/src/output/lsmcode.cpp
+++ b/src/output/lsmcode.cpp
@@ -178,7 +178,7 @@ static string read_dt_property(const string& path, const string& attrName)
try {
attrIn.open( fullPath.c_str( ) );
}
- catch (std::ifstream::failure e) {
+ catch (std::ifstream::failure &e) {
ostringstream os;
os << "Error opening " << fullPath;
Logger().log(os.str( ), LOG_WARNING);

View File

@ -1,67 +0,0 @@
commit d6f0fad940ca5873d240f8d74529ea36cc20ed3d
Author: Kamalesh Babulal <kamalesh@linux.ibm.com>
Date: Mon May 31 15:47:00 2021 +0530
sysfstreecollector: use of_node file to device-tree path
In getDevTreePath(), currently we read the devspec in the sysfs path of
the device to retrive the path represented in /proc/device-tree, some
modern device do not construct devspec file, instead relay on of_node
file, which is a symlink to a file in the device-tree.
Teach getDevTreePath() to check for of_node file, and read the symbolic
link it points too and in case of of_node not available, fall back to
Signed-off-by: Kamalesh Babulal <kamalesh@linux.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
diff --git a/src/internal/sys_interface/sysfstreecollector.cpp b/src/internal/sys_interface/sysfstreecollector.cpp
index 7e7e13c..f0be417 100644
--- a/src/internal/sys_interface/sysfstreecollector.cpp
+++ b/src/internal/sys_interface/sysfstreecollector.cpp
@@ -957,15 +957,43 @@ esc_subsystem_info:
*/
string SysFSTreeCollector::getDevTreePath(string sysPath)
{
+ string sysFsPath, procDtPath, firmwareDtBase;
struct stat astats;
const char *buf;
char buf2[512];
FILE *fi;
HelperFunctions::fs_fixPath(sysPath);
- sysPath += "/devspec";
+ sysFsPath = sysPath + "/devspec";
+ procDtPath = sysPath + "/of_node";
+ firmwareDtBase = "/sys/firmware/devicetree/base";
- buf = sysPath.c_str();
+ /*
+ * Check for existence of of_node symlink and return the path it
+ * points to. devspec is obsolete now, most of the devices
+ * populate of_node and devspec too. Prefer of_node over
+ * devspec, where it exist and fall back to older logic, in case
+ * of of_node not populated.
+ */
+ buf = procDtPath.c_str();
+ if ((lstat(buf, &astats)) == 0) {
+ // of_node is symlink, follow the link
+ realpath( buf, buf2 );
+ if ( buf2 == NULL ) {
+ return string ("");
+ }
+
+ /*
+ * Trim the leading "/sys/firmware/devicetree/base" from the real
+ * path to match the assumption from devspec format, while used
+ * with /proc/devicetree.
+ */
+ procDtPath = string(buf2);
+ procDtPath.replace(0, firmwareDtBase.length(), "");
+ return procDtPath;
+ }
+
+ buf = sysFsPath.c_str();
if ((lstat(buf, &astats)) != 0) {
return string("");
}

View File

@ -1,316 +0,0 @@
commit fff4ada4f29978923527b06e95aca71513bac275
Author: Kamalesh Babulal <kamalesh@linux.ibm.com>
Date: Mon May 31 15:47:02 2021 +0530
devicetreecollector: buildSCSI() - add support for SCSI loc-code
fillQuickVPD failing to find the loc-code, doesn't always attribute to
the missing device-tree entry associated with the sysfs device path.
There are also configurations like USB hubs, to which the SCSI devices
gets connected with special device-tree layout. A USB controller, that
supports both USB 3.0 and USB 2.0 devices will create two USB hubs for
communicating with devices. Where one hub controllers devices with
speeds ranging upto 480M (USB 2.0) and another for devices operating
at the 5000M (USB 3.0). The layout might be little complex when the
USB 3.0 devices are internal on board ones and 2.0 is an external
device.
root hub
/ \
USB hub 1 (2.0) USB hub 2 (3.0)
| / \
external internal internal
device device1 device2
the populated device-tree adds both of the internal devices
under the hub1, that hosts the slower external device, with
the layout:
usb@1
|_ hub@1
|_ cdrom@1 (USB 2.0)
|_ usb-scsi@6 (USB 3.0, internal device 1)
|_ usb-scsi@8 (USB 3.0, internal device 2)
this patch add support to find location code for such SCSI devices
connected to USB hubs in a mix and match of external and internal
devices.
Signed-off-by: Kamalesh Babulal <kamalesh@linux.ibm.com>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
diff --git a/src/include/devicetreecollector.hpp b/src/include/devicetreecollector.hpp
index 84ddbfe..1bd0293 100644
--- a/src/include/devicetreecollector.hpp
+++ b/src/include/devicetreecollector.hpp
@@ -206,6 +206,10 @@ namespace lsvpd
Component * findSCSIParent(Component *fillMe,
vector<Component*> devs);
+
+ string fillLocCode(Component *gParent, Component *gGParent,
+ Component *gGGParent);
+
void buildSCSILocCode(Component *fillMe, vector<Component*> devs);
void getComponentsVector( vector<Component*>& devs );
diff --git a/src/internal/sys_interface/devicetreecollector.cpp b/src/internal/sys_interface/devicetreecollector.cpp
index dd55611..1f686f5 100644
--- a/src/internal/sys_interface/devicetreecollector.cpp
+++ b/src/internal/sys_interface/devicetreecollector.cpp
@@ -42,6 +42,7 @@
#include <fcntl.h>
#include <string>
#include <unistd.h>
+#include <libgen.h>
#include <cstdlib>
#include <cstring>
#include <cerrno>
@@ -735,7 +736,9 @@ ERROR:
int loc;
devSpecific = fillMe->getDeviceSpecific("XB");
- if (devSpecific != NULL) {
+ if (devSpecific != NULL ||
+ fillMe->devBus.dataValue == "scsi" ||
+ fillMe->devBus.dataValue == "usb" ) {
sysDev = fillMe->sysFsLinkTarget.dataValue;
while (sysDev.length() > 1) {
if ((loc = sysDev.rfind("/", sysDev.length())) != (int) string::npos )
@@ -752,6 +755,152 @@ ERROR:
return NULL;
}
+ /*
+ * @brief fillLocCode tries to parse the device-tree and find
+ * the loc-code based on port numbers.
+ * @args:
+ * gParent: two level higher in the sysfs path of the device (required for
+ * finding devices in the same root hub USB 2.0)
+ * gGParent: three level higher in the sysfs path of the device (required to
+ * calculate raw port number)
+ * gGGParent: Four level higher in the sysfs path of the device (required for
+ * findging devices in the sibling root hub USB 3.0)
+ *
+ * Example:
+ *
+ * device: /sys/devices/pci0019:01/0019:01:00.0/usb2/2-2/2-2:1.0/host0/target0:0:0/0:0:0:0
+ * parent: /sys/devices/pci0019:01/0019:01:00.0/usb2/2-2/2-2:1.0/host0
+ * gParent: /sys/devices/pci0019:01/0019:01:00.0/usb2/2-2/2-2:1.0
+ * gGparent: /sys/devices/pci0019:01/0019:01:00.0/usb2/2-2
+ * gGGparent: /sys/devices/pci0019:01/0019:01:00.0/usb2
+
+ */
+ string DeviceTreeCollector::fillLocCode(Component *gParent, Component *gGParent,
+ Component *gGGParent)
+ {
+ string devTreeDir, devName, rawPortS, locCode;
+ vector<string> listing, list;
+ char busNum[10], portNum[10];
+ int maxChild, rawPort = 0;
+ FSWalk fsw = FSWalk();
+ char *baseName;
+ int i = 0, j;
+
+ /*
+ * First part of this function, tries to find the port
+ * number assigned to the device under the USB
+ * controller. The algorithm used to construct the
+ * rawport (the term used in the Linux Kernel USB device
+ * driver code) is the parse the bus and port number
+ * from the last directory level of the device sysfs path
+ * and then find the maximum number of ports available
+ * under the USB hub, to connect devices in the hub.
+ * Applying the formula:
+ * - bus number * child of all the hubs, with bus number
+ * lesser than the current bus + current device port
+ * number.
+ * i.e., if the device gets assigned to port 2 of the
+ * root hub number 2, here 2 is the bus number, assigned
+ * by the USB controller and as maxchild of 4 or in other
+ * words maximum available ports on the root hub is 4.
+ * We assume that the same USB controller will host 4
+ * ports for both root hubs (USB 2.0 and USB 3.0).
+ * When the algorithm is applied to the above example:
+ * bus number (2) * (1 * 4) (1 is bus lesser than current
+ * one and 4 is maxchild/ports available) = port number 6.
+ * We need to search for devices ending with @6, under the
+ * root hub to find the location code.
+ */
+ baseName = basename((char *)(string(gGParent->sysFsNode.dataValue).c_str()));
+ if (baseName == NULL)
+ return string("");
+
+ for (i = 0; baseName[i] != '\0' && baseName[i] != '-'; i++)
+ busNum[i] = baseName[i];
+ busNum[i] = '\0';
+
+ if (strlen(busNum) == 0)
+ return string("");
+
+ for (i+=1, j=0; baseName[i] != '\0'; i++, j++)
+ portNum[j] = baseName[i];
+ portNum[j] = '\0';
+
+ if (strlen(portNum) == 0)
+ return string("");
+
+ maxChild = atoi(string(getAttrValue
+ ( gGGParent->sysFsNode.dataValue.c_str(), "/maxchild")).c_str());
+
+ i = atoi(busNum);
+ if ( i > 1 ) {
+ rawPort = i - 1;
+ rawPort *= maxChild;
+ }
+ rawPort += atoi(portNum);
+ rawPortS = "@" + to_string(rawPort);
+
+ /*
+ * for the USB 2.0 devices, device-tree association of root
+ * hub under which they are connected, is read from devspec
+ * or of_node in the sysfs path of the /sys/devices/. So we
+ * just search for the devices ending with the port number
+ * calculated above in the device (root hub) device-tree
+ * node.
+ */
+ fsw.fs_getDirContents(gParent->deviceTreeNode.dataValue, 'd', listing);
+ while (listing.size() > 0) {
+
+ string devDir = listing.back();
+ if (devDir.compare(devDir.length() - rawPortS.length(),
+ rawPortS.length(), rawPortS) == 0) {
+
+ devTreeDir = gParent->deviceTreeNode.dataValue + "/" + listing.back();
+ locCode = getAttrValue( devTreeDir.c_str(), "/ibm,loc-code");
+ return locCode;
+ }
+ listing.pop_back();
+ }
+
+ /*
+ * this logic is same as above but we are searching one
+ * level higher in the /proc/device-tree hierarchy, the
+ * search path includes all of the root hubs connected to
+ * this USB controller and use the same logic as above to
+ * find the device ending with the @portnumber in every
+ * root hub.
+ */
+ fsw.fs_getDirContents(gGGParent->deviceTreeNode.dataValue, 'd', listing);
+ while (listing.size() > 0) {
+
+ devTreeDir = gGGParent->deviceTreeNode.dataValue + "/" + listing.back();
+ devName = getAttrValue( devTreeDir.c_str(), "/name");
+
+ if (devName.compare("hub") == 0) {
+
+ fsw.fs_getDirContents(devTreeDir.c_str(), 'd', list);
+ while (list.size() > 0) {
+
+ string devDir = list.back();
+ string _devTreeDir;
+
+ if ( devDir.compare(devDir.length() - rawPortS.length(),
+ rawPortS.length(), rawPortS) == 0) {
+
+ _devTreeDir = devTreeDir + "/" + list.back();
+ locCode = getAttrValue( _devTreeDir.c_str(),
+ "/ibm,loc-code");
+ return locCode;
+ }
+ list.pop_back();
+ }
+ }
+ listing.pop_back();
+ }
+
+ return string("");
+}
+
/* @brief Collect Location Code information for devices that do not
* give us a nice ibm,loc-code
* @arg devs - device tree discovered devices
@@ -763,9 +912,10 @@ ERROR:
void DeviceTreeCollector::buildSCSILocCode(Component *fillMe,
vector<Component*> devs)
{
- Component *parent;
- ostringstream val;
+ Component *parent, *gParent, *gGParent, *gGGParent;
const DataItem *target, *lun, *bus, *host;
+ ostringstream val;
+ string locCode;
/* Build up a distinct YL based on parents YL - for device such as
* scsi, ide, usb, etc that do not generate ibm,loc-code
@@ -793,6 +943,71 @@ ERROR:
val << getAttrValue( parent->deviceTreeNode.dataValue,
"ibm,loc-code" );
+ /*
+ * fillQuickVPD failure, doesn't always attribute to the missing
+ * device-tree entry associated with the sysfs device path.
+ * There are also configurations like USB hubs, to which the
+ * SCSI devices gets connected with special device-tree layout.
+ * A USB controller, that supports both USB 3.0 and USB 2.0
+ * devices will create two USB hubs for communicating with
+ * devices. Where one hub controllers devices with speeds
+ * ranging upto 480M (USB 2.0) and another for devices operating
+ * at the 5000M (USB 3.0). The layout might be little complex
+ * when the USB 3.0 devices are internal on board ones and 2.0
+ * is an external device.
+ *
+ * root hub
+ * / \
+ * USB hub 1 USB hub 2
+ * (2.0) (3.0)
+ * | / \
+ * External Internal Internal
+ * device device1 device2
+ *
+ * the populated device-tree adds both of the internal devices
+ * under the hub1, that hosts the slower external device, with
+ * the layout:
+ * usb@1
+ * |_ hub@1
+ * |_ cdrom@1 (USB 2.0)
+ * |_ usb-scsi@6 (USB 3.0, internal device 1)
+ * |_ usb-scsi@8 (USB 3.0, internal device 2)
+ *
+ * the logic below finds the location code for such SCSI devices
+ * connected to USB hubs in a mix and match of external and
+ * internal devices.
+ */
+ gParent = findSCSIParent(parent, devs);
+ if (gParent != NULL) {
+
+ gGParent = findSCSIParent(gParent, devs);
+ if (gGParent != NULL) {
+
+ gGGParent = findSCSIParent(gGParent, devs);
+ if (gGGParent != NULL &&
+ gGGParent->devBus.dataValue == "usb" ) {
+
+ /*
+ * walk up to the hub controller sysfs
+ * directory to find the device-tree
+ * association.
+ */
+ locCode = fillLocCode
+ (gParent, gGParent, gGGParent);
+ }
+ }
+ }
+
+ if (locCode.length() > 0) {
+ fillMe->mPhysicalLocation.setValue( locCode.c_str( ), 60 ,
+ __FILE__, __LINE__ );
+ return;
+ }
+
+ /*
+ * if we fail to find the loation code, then fallback to old
+ * method of constructing an unique code.
+ */
val << "H" << host->dataValue << "-B" << bus->dataValue
<< "-T" << target->dataValue << "-L" << lun->dataValue;

View File

@ -1,20 +1,11 @@
%define name lsvpd
%define version 1.7.12
Name: %{name}
Version: %{version}
Name: lsvpd
Version: 1.7.13
Release: 1%{?dist}
Summary: VPD/hardware inventory utilities for Linux
License: GPLv2+
URL: https://github.com/power-ras/%{name}/releases
Source: https://github.com/power-ras/%{name}/archive/v%{version}/%{name}-%{version}.tar.gz
Patch1: lsvpd-52793604fa715cd352ef9ba488f8215afee8bb73.patch
Patch2: lsvpd-32958b576e87ec517048a8e446a7a06b703a36d2.patch
Patch3: lsvpd-d6f0fad940ca5873d240f8d74529ea36cc20ed3d.patch
Patch4: lsvpd-4e93ccc44f61854c84d82de8de80c18c87b87957.patch
Patch5: lsvpd-fff4ada4f29978923527b06e95aca71513bac275.patch
Patch6: lsvpd-25ac29f309dd8192a3fe5c628d303b48593738e1.patch
BuildRequires: gcc-c++
BuildRequires: libvpd-devel >= 2.2.5
BuildRequires: sg3_utils-devel
@ -77,6 +68,9 @@ exit 0
%dir %{_sysconfdir}/lsvpd
%changelog
* Wed Sep 15 2021 Than Ngo <than@redhat.com> - 1.7.13-1
- rebase to 1.7.13
* Fri Sep 03 2021 Than Ngo <than@redhat.com> - 1.7.12-1
- rebase to 1.7.12
- add support for SCSI loc-code

View File

@ -1 +1 @@
SHA512 (lsvpd-1.7.12.tar.gz) = 0a37a580432004c359080edd2b07ea44a68dcf81621e0ec3a89cf7c4ca0f64a29143cee154a8d39c1411f64bf229a8a19f10d9f2c95971374b97a4c05b1c1523
SHA512 (lsvpd-1.7.13.tar.gz) = 99039b622051a24d1d17a014a81c6909a403c4b3746c2e4e62b0822f1d14319b3fcd5c82c13ec240ef2110c8a08de5b74a39ed0dea8a482977a475566cd83d3b