5c7d26753c
Commit links: -c36b20b7dc
/ -f5a8a079df
/ -68a4d47bdf
/
240 lines
7.2 KiB
Diff
240 lines
7.2 KiB
Diff
From 68a4d47bdfbe4ebcc048e9f08862e2639bbec2e7 Mon Sep 17 00:00:00 2001
|
|
From: Ankit Kumar <ankit@linux.vnet.ibm.com>
|
|
Date: Thu, 21 Sep 2017 18:34:20 +0530
|
|
Subject: [PATCH 3/3] lsmcode: Support firmware info on BMC based Power9 system
|
|
|
|
P9 system supports various service processor stack like FSP based system,
|
|
SMC system, AMI with OpenBMC stack etc. Some of these systems supports full
|
|
ipmi stack and few other systems doesn't (at least for now).
|
|
|
|
lsmcode uses ipmi interface (ipmitool fru) to get firmware information. It
|
|
fails on some of the P9 system where we donot have full ipmi support.
|
|
|
|
Recently we added support in OPAL to export firmware information via device
|
|
tree for P9 BMC systems (/ibm,firmware-versions node). Even recent hostboot
|
|
firmware on P8 BMC system exports these information via mini device tree.
|
|
|
|
This patch enables lsmcode to collect firmware information via device tree.
|
|
|
|
Sample output on Power9 system after applying this patch:
|
|
./lsmcode
|
|
Version of System Firmware :
|
|
Product Name : OpenPOWER Firmware
|
|
Product Version : open-power-firestone-v1.17-101-g1c57f18-dirty
|
|
Product Extra : occ-site_local-akshay-28f2cec-dirty
|
|
Product Extra : skiboot-5.6.0-158-ga1e0a047b2a0
|
|
Product Extra : buildroot-2017.02.2-7-g23118ce
|
|
Product Extra : capp-ucode-9c73e9f
|
|
Product Extra : petitboot-v1.4.3-pa6836f6
|
|
Product Extra : hostboot-binaries-711147e
|
|
Product Extra : machine-xml-2494a43
|
|
Product Extra : hostboot-695bd89
|
|
Product Extra : linux-4.11.6-openpower1-p1e59f24
|
|
|
|
root@fir02:/home/ankit/lsvpd# ./lsmcode --All
|
|
sys0!system: open-power-firestone-v1.17-101-g1c57f18-dirty
|
|
sg0 0:0:0:0 sda !ST1000NX0313.BE33
|
|
|
|
Sample output on Power8 system after applying this patch:
|
|
./lsmcode
|
|
Version of System Firmware :
|
|
Product Name : OpenPOWER Firmware
|
|
Product Version : open-power-firestone-v1.17-101-g1c57f18-dirty
|
|
Product Extra : buildroot-2017.02.2-7-g23118ce
|
|
Product Extra : skiboot-5.6.0-158-ga1e0a047b2a0
|
|
Product Extra : hostboot-695bd89
|
|
Product Extra : linux-4.11.6-openpower1-p1e59f24
|
|
Product Extra : petitboot-v1.4.3-pa6836f6
|
|
Product Extra : machine-xml-2494a43
|
|
Product Extra : occ-site_local-28f2cec-dirty
|
|
|
|
root@fir:lsvpd# ./lsmcode --All
|
|
sys0!system: open-power-firestone-v1.17-101-g1c57f18-dirty
|
|
sg0 0:0:0:0 sda !ST1000NX0313.BE33
|
|
|
|
Signed-off-by: Ankit Kumar <ankit@linux.vnet.ibm.com>
|
|
[Updated description, Changed "product version" property name - Vasant]
|
|
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
|
|
---
|
|
src/output/lsmcode.cpp | 135 ++++++++++++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 129 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/output/lsmcode.cpp b/src/output/lsmcode.cpp
|
|
index a8d9f11..c96a176 100644
|
|
--- a/src/output/lsmcode.cpp
|
|
+++ b/src/output/lsmcode.cpp
|
|
@@ -23,6 +23,7 @@
|
|
|
|
#include <rtascollector.hpp>
|
|
#include <platformcollector.hpp>
|
|
+#include <devicetreecollector.hpp>
|
|
#include <libvpd-2/vpdretriever.hpp>
|
|
#include <libvpd-2/component.hpp>
|
|
#include <libvpd-2/dataitem.hpp>
|
|
@@ -39,6 +40,7 @@
|
|
#define _GNU_SOURCE // for getopt_long
|
|
#endif
|
|
|
|
+#include <dirent.h>
|
|
#include <unistd.h>
|
|
#include <getopt.h>
|
|
#include <zlib.h>
|
|
@@ -50,6 +52,9 @@
|
|
#include <iomanip>
|
|
#include <limits.h>
|
|
|
|
+/* Firmware information device tree node on PowerNV system */
|
|
+#define FW_VERSION_DT_NODE DEVTREEPATH"/ibm,firmware-versions/"
|
|
+
|
|
/* IPMI tool */
|
|
#define CMD_IPMITOOL "ipmitool"
|
|
|
|
@@ -152,6 +157,117 @@ parse_err:
|
|
return string();
|
|
}
|
|
|
|
+static string read_dt_property(const string& path, const string& attrName)
|
|
+{
|
|
+ struct stat info;
|
|
+ string fullPath;
|
|
+ string ret = "";
|
|
+
|
|
+ ostringstream os;
|
|
+ os << path << "/" << attrName;
|
|
+ fullPath = os.str( );
|
|
+
|
|
+ if (stat(fullPath.c_str( ), &info) != 0) {
|
|
+ ostringstream os;
|
|
+ if (errno != ENOENT) {
|
|
+ os << "Error statting " << fullPath << ", errno: " << errno;
|
|
+ Logger().log( os.str( ), LOG_ERR );
|
|
+ }
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ifstream attrIn;
|
|
+ attrIn.exceptions ( std::ifstream::failbit | std::ifstream::badbit );
|
|
+ try {
|
|
+ attrIn.open( fullPath.c_str( ) );
|
|
+ }
|
|
+ catch (std::ifstream::failure e) {
|
|
+ ostringstream os;
|
|
+ os << "Error opening " << fullPath;
|
|
+ Logger().log(os.str( ), LOG_WARNING);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ if (attrIn) {
|
|
+ char * strBuf;
|
|
+ try
|
|
+ {
|
|
+ strBuf = new char [ info.st_size + 1 ];
|
|
+ }
|
|
+ catch (exception& e)
|
|
+ {
|
|
+ return ret;
|
|
+ }
|
|
+ memset( strBuf, '\0', info.st_size + 1 );
|
|
+ attrIn.read( strBuf, info.st_size );
|
|
+ ret = strBuf;
|
|
+ attrIn.close( );
|
|
+ delete [] strBuf;
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+/* Get system firmware information on BMC based system via device tree */
|
|
+static string bmc_get_fw_dt_info(void)
|
|
+{
|
|
+ string fwdata, tag, val, prod_ver = "", prod_extra = "";
|
|
+ struct dirent *ent;
|
|
+ DIR * pDBdir = NULL;
|
|
+ /* Properties to ignore from DT/ibm,firmware-versions node */
|
|
+ const char *ignore_dt[] = {"phandle", "name"};
|
|
+ int i;
|
|
+ bool ignore_dt_flag = false;
|
|
+
|
|
+ pDBdir = opendir(FW_VERSION_DT_NODE);
|
|
+ if (pDBdir == NULL) {
|
|
+ stringstream os;
|
|
+ os << "Error opening directory " << FW_VERSION_DT_NODE << endl;
|
|
+ Logger().log(os.str( ), LOG_ERR);
|
|
+ return string("");
|
|
+ }
|
|
+
|
|
+ fwdata = string("\n Product Name : OpenPOWER Firmware\n");
|
|
+ while ((ent = readdir( pDBdir )) != NULL) {
|
|
+ string fname = ent->d_name;
|
|
+ for (i = 0; i < (int)(sizeof(ignore_dt)/sizeof(char *)); i++) {
|
|
+ if (fname.compare(string(ignore_dt[i])) == 0) {
|
|
+ ignore_dt_flag = true;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (ignore_dt_flag == true) {
|
|
+ ignore_dt_flag = false;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ /*
|
|
+ * Looks like some system has open-power property and some
|
|
+ * other has "IBM" property. Lets use one of these property
|
|
+ * for Product Version.
|
|
+ */
|
|
+ if (fname.compare("IBM") == 0 || fname.compare("open-power") == 0) {
|
|
+ if (prod_ver == string("")) {
|
|
+ tag = string(" Product Version : ");
|
|
+ prod_ver = read_dt_property(string(FW_VERSION_DT_NODE), fname);
|
|
+ if (prod_ver == string(""))
|
|
+ continue;
|
|
+ prod_ver = tag + fname + string("-") + prod_ver + string("\n");
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ tag = string(" Product Extra : \t");
|
|
+ val = read_dt_property(string(FW_VERSION_DT_NODE), fname);
|
|
+ if (val == string(""))
|
|
+ continue;
|
|
+ prod_extra = prod_extra + tag + fname + string("-") + val + string("\n");
|
|
+ }
|
|
+
|
|
+ fwdata = fwdata + prod_ver + prod_extra;
|
|
+ return fwdata;
|
|
+}
|
|
+
|
|
/* Get production version */
|
|
static string bmc_get_product_version(string fwData)
|
|
{
|
|
@@ -181,13 +297,20 @@ bool printSystem( const vector<Component*>& leaves )
|
|
* based system. Hence we don't store this information in VPD db.
|
|
*/
|
|
if (PlatformCollector::isBMCBasedSystem()) {
|
|
- string ipmitool = get_ipmitool_path();
|
|
- if (ipmitool.empty())
|
|
- return false;
|
|
+ string fwData;
|
|
+ if (!access(FW_VERSION_DT_NODE, F_OK | R_OK)) {
|
|
+ fwData = bmc_get_fw_dt_info();
|
|
+ if (fwData.empty())
|
|
+ return false;
|
|
+ } else {
|
|
+ string ipmitool = get_ipmitool_path();
|
|
+ if (ipmitool.empty())
|
|
+ return false;
|
|
|
|
- string fwData = bmc_get_fw_fru_info(ipmitool);
|
|
- if (fwData.empty())
|
|
- return false;
|
|
+ fwData = bmc_get_fw_fru_info(ipmitool);
|
|
+ if (fwData.empty())
|
|
+ return false;
|
|
+ }
|
|
|
|
if ( all ) {
|
|
string pVersion = bmc_get_product_version(fwData);
|
|
--
|
|
2.14.3
|
|
|