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