142 lines
4.7 KiB
Diff
142 lines
4.7 KiB
Diff
|
commit 50e2fa22298de13fd731488306d2cbd0081730d8
|
||
|
Author: Sathvika Vasireddy <sv@linux.ibm.com>
|
||
|
Date: Fri Feb 10 14:55:41 2023 +0530
|
||
|
|
||
|
lsvpd: Fill firmware information by recursively looking for firmware specific files within sysfs ID
|
||
|
|
||
|
Currently, fillFirmware() is filling firmware information based on the
|
||
|
classNode value of a given component. It then looks for firmware specific
|
||
|
sysfs files (fw_version, fwrev, firmware_rev), within the classNode path,
|
||
|
to set firmware fields accordingly. For components that do not have a
|
||
|
classNode value, fillFirmware() does not look for firmware information
|
||
|
within the sysfs firmware files, and hence does not set firmware fields.
|
||
|
|
||
|
This patch recursively looks for sysfs firmware files within the ID path of
|
||
|
a component, and sets the firmware fields accordingly, if not already set.
|
||
|
|
||
|
Reported-by: Borislav Stoymirski <borislav.stoymirski@bg.ibm.com>
|
||
|
Signed-off-by: Sathvika Vasireddy <sv@linux.ibm.com>
|
||
|
Signed-off-by: Mahesh Salgaonkar <mahesh@linux.ibm.com>
|
||
|
Tested-by: Borislav Stoymirski <borislav.stoymirski@bg.ibm.com>
|
||
|
|
||
|
diff --git a/src/include/icollector.hpp b/src/include/icollector.hpp
|
||
|
index 894dd99..392632f 100644
|
||
|
--- a/src/include/icollector.hpp
|
||
|
+++ b/src/include/icollector.hpp
|
||
|
@@ -116,6 +116,25 @@ namespace lsvpd
|
||
|
virtual ~ICollector( ){}
|
||
|
|
||
|
protected:
|
||
|
+ /** Recursively search for attrName within a given path.
|
||
|
+ *
|
||
|
+ * @param path
|
||
|
+ * Directory path to search for filename.
|
||
|
+ *
|
||
|
+ * @param attrName
|
||
|
+ * Filename to search for.
|
||
|
+ *
|
||
|
+ * @return
|
||
|
+ * Path in which attrName file exists.
|
||
|
+ *
|
||
|
+ * If attrName is fwrev, and is found at
|
||
|
+ * /sys/devices/pci0020:01/0020:01:00.1/host4/scsi_host/host4/fwrev,
|
||
|
+ * searchFile() will return
|
||
|
+ * /sys/devices/pci0020:01/0020:01:00.1/host4/scsi_host/host4.
|
||
|
+ */
|
||
|
+ string searchFile( const string& path,
|
||
|
+ const string& attrName );
|
||
|
+
|
||
|
string getAttrValue( const string& path,
|
||
|
const string& attrName );
|
||
|
|
||
|
diff --git a/src/internal/sys_interface/icollector.cpp b/src/internal/sys_interface/icollector.cpp
|
||
|
index 5c4dccc..7586fe8 100644
|
||
|
--- a/src/internal/sys_interface/icollector.cpp
|
||
|
+++ b/src/internal/sys_interface/icollector.cpp
|
||
|
@@ -32,11 +32,46 @@
|
||
|
#include <fstream>
|
||
|
#include <cstring>
|
||
|
#include <bitset>
|
||
|
+#include <iostream>
|
||
|
+#include <dirent.h>
|
||
|
+#include <string.h>
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
namespace lsvpd
|
||
|
{
|
||
|
+
|
||
|
+ string ICollector::searchFile( const string& path, const string& attrName )
|
||
|
+ {
|
||
|
+ DIR *dir;
|
||
|
+ struct dirent *entry;
|
||
|
+
|
||
|
+ if ((dir = opendir(path.c_str())) == NULL)
|
||
|
+ return "";
|
||
|
+
|
||
|
+ while ((entry = readdir(dir)) != NULL) {
|
||
|
+ if (entry->d_type == DT_DIR) {
|
||
|
+ // Found a directory, but ignore . and ..
|
||
|
+ if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
|
||
|
+ continue;
|
||
|
+ string newPath = path + "/" + entry->d_name;
|
||
|
+ string result = searchFile(newPath, attrName);
|
||
|
+ if (result != "") {
|
||
|
+ closedir(dir);
|
||
|
+ return result;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ else {
|
||
|
+ if (entry->d_name == attrName) {
|
||
|
+ closedir(dir);
|
||
|
+ return path;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ }
|
||
|
+ closedir(dir);
|
||
|
+ return "";
|
||
|
+ }
|
||
|
+
|
||
|
/**
|
||
|
* Read a device attribute, given dev path and attribute name
|
||
|
* @var path Full path to device in sysfs
|
||
|
diff --git a/src/internal/sys_interface/sysfstreecollector.cpp b/src/internal/sys_interface/sysfstreecollector.cpp
|
||
|
index c5eb71d..03eb7da 100644
|
||
|
--- a/src/internal/sys_interface/sysfstreecollector.cpp
|
||
|
+++ b/src/internal/sys_interface/sysfstreecollector.cpp
|
||
|
@@ -1837,6 +1837,10 @@ ERROR:
|
||
|
|
||
|
void SysFSTreeCollector::fillFirmware( Component* fillMe )
|
||
|
{
|
||
|
+ string result = "";
|
||
|
+ string path = fillMe->getID();
|
||
|
+ const string firmwareAttributes[] = {"fw_version", "firmware_rev"};
|
||
|
+ const size_t firmwareAttributesSize = sizeof(firmwareAttributes) / sizeof(firmwareAttributes[0]);
|
||
|
string classNode = fillMe->getClassNode();
|
||
|
if (classNode.length() > 0) {
|
||
|
fillMe->mFirmwareVersion.setValue( getAttrValue( classNode,
|
||
|
@@ -1848,6 +1852,23 @@ ERROR:
|
||
|
fillMe->mFirmwareVersion.setValue( getAttrValue( classNode,
|
||
|
"firmware_rev" ), 30, __FILE__, __LINE__ );
|
||
|
}
|
||
|
+
|
||
|
+ if (fillMe->mFirmwareLevel.dataValue.empty()) {
|
||
|
+ result = searchFile(path, "fwrev");
|
||
|
+ if (!result.empty()) {
|
||
|
+ fillMe->mFirmwareLevel.setValue( getAttrValue( result,
|
||
|
+ "fwrev" ), 30, __FILE__, __LINE__ );
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ for (size_t i = 0; i < firmwareAttributesSize && fillMe->mFirmwareVersion.dataValue.empty(); i++) {
|
||
|
+ result = searchFile(path, firmwareAttributes[i]);
|
||
|
+ if (!result.empty()) {
|
||
|
+ fillMe->mFirmwareVersion.setValue( getAttrValue( result,
|
||
|
+ firmwareAttributes[i]), 30, __FILE__, __LINE__ );
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
}
|
||
|
|
||
|
string SysFSTreeCollector::resolveClassPath( const string& path )
|