metal/mtce-common/src/common/ipmiUtil.cpp

247 lines
8.2 KiB
C++

/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*
*
* @file
* Wind River Titanium Cloud Common IPMI Utilities
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
#include "nodeBase.h" /* for ... mtce node common definitions */
#include "hostUtil.h" /* for ... mtce host common definitions */
#include "ipmiUtil.h" /* for ... this module header */
/* Create a randomly named password filename */
void ipmiUtil_create_pw_fn ( thread_info_type * info_ptr, string pw )
{
info_ptr->password_file.clear ();
string password_tempfile = IPMITOOL_OUTPUT_DIR ;
password_tempfile.append(".") ;
password_tempfile.append(program_invocation_short_name);
password_tempfile.append("-");
password_tempfile.append(info_ptr->hostname);
password_tempfile.append("-");
info_ptr->pw_file_fd = hostUtil_mktmpfile (info_ptr->hostname,
password_tempfile,
info_ptr->password_file,
pw );
if ( info_ptr->pw_file_fd <= 0 )
{
info_ptr->status_string = "failed to get an open temporary password filedesc" ;
info_ptr->status = FAIL_FILE_CREATE ;
info_ptr->password_file.clear();
}
else
{
/* clean-up */
if ( info_ptr->pw_file_fd > 0 )
close(info_ptr->pw_file_fd);
info_ptr->pw_file_fd = 0 ;
}
}
/* Create the ipmitool output_filename */
string ipmiUtil_create_data_fn ( string & hostname, string file_suffix )
{
/* create the output filename */
string ipmitool_datafile = IPMITOOL_OUTPUT_DIR ;
ipmitool_datafile.append(program_invocation_short_name);
ipmitool_datafile.append("_");
ipmitool_datafile.append(hostname);
/* add the sensor list command */
ipmitool_datafile.append(file_suffix);
return ( ipmitool_datafile );
}
/* Create the ipmi request */
string ipmiUtil_create_request ( string cmd, string & ip, string & un, string & pw, string & out )
{
/* ipmitool -I lanplus -H $uut_ip -U $uut_un -E */
/* build the ipmitool command */
string ipmitool_request = IPMITOOL_PATH_AND_FILENAME ;
/* Specify lanplus network mode for centralized power control, 1 retry
* followed by the bm ip address and password file */
ipmitool_request.append(" -I lanplus -R 1 -H ");
ipmitool_request.append(ip);
/* then specify the bmc username */
ipmitool_request.append(" -U ");
ipmitool_request.append(un);
if ( daemon_is_file_present ( MTC_CMD_FIT__LOUD_BM_PW ) == true )
{
/* get the password from the file and put it on the command line */
ipmitool_request.append(" -P ");
ipmitool_request.append(daemon_get_file_str(pw.data()));
}
else
{
/* add the password file option and file */
ipmitool_request.append(" -f ");
ipmitool_request.append(pw);
}
/* add the command */
ipmitool_request.append(" ");
ipmitool_request.append(cmd);
/* output filename */
ipmitool_request.append (" > ");
ipmitool_request.append (out);
return (ipmitool_request);
}
/* init the mc info struct */
void ipmiUtil_mc_info_init ( mc_info_type & mc_info )
{
mc_info.device_id.clear();
mc_info.manufacturer_name.clear();
mc_info.manufacturer_id.clear();
mc_info.product_name.clear();
mc_info.product_id.clear();
mc_info.fw_version.clear();
mc_info.hw_version.clear();
}
/* print a log of the mc info data */
void mc_info_log ( string hostname, mc_info_type & mc_info, int rc )
{
if ( rc )
{
elog ("%s mc info load failed (rc:%d)\n", hostname.c_str(), rc );
}
else
{
ilog ("%s Manufacturer: %s [id:%s] [ Device: %s ver %s ]\n",
hostname.c_str(),
mc_info.manufacturer_name.c_str(),
mc_info.manufacturer_id.c_str(),
mc_info.device_id.c_str(),
mc_info.hw_version.c_str());
ilog ("%s Product Name: %s [id:%s] [ BMC FW: ver %s ]\n",
hostname.c_str(),
mc_info.product_name.c_str(),
mc_info.product_id.c_str(),
mc_info.fw_version.c_str());
}
}
/* load the specified key value in buffer line into 'value' */
bool _got_delimited_value ( char * buf_ptr, const char * key, const char * delimiter, string & value )
{
if ( strstr ( buf_ptr, key ))
{
string _str = buf_ptr ;
if ( _str.find(key) != std::string::npos )
{
if ( _str.find( delimiter ) != std::string::npos )
{
int y = _str.find( delimiter ) ;
value = _str.substr ( y+strlen(delimiter), std::string::npos) ;
value.erase ( value.size()-1, std::string::npos ) ;
return (true);
}
}
}
return (false);
}
/*****************************************************************************
*
* Name : ipmiUtil_mc_info_load
*
* Description: Load the contents of a file containing an ipmitool formatted
* output from an mc info request into the passed in mc_info
* struct. Loaded info includes
*
* Manufacturer (id/name)
* Product (id/name)
* Device (id/version)
* Firmware (version)
*
* A log like the following is generated.
*
* controller-0 mc info: Nokia:7244 - Quanta:12866 (0x3242) [bmc fw:3.29] [device:32 ver:1]
*
* Example MC Info output from ipmitool
*
* Device ID : 32
* Device Revision : 1
* Firmware Revision : 3.29
* IPMI Version : 2.0
* Manufacturer ID : 7244
* Manufacturer Name : Nokia
* Product ID : 12866 (0x3242)
* Product Name : Quanta
* Device Available : yes
* Provides Device SDRs : no
* Additional Device Support :
* Sensor Device
* SDR Repository Device
* SEL Device
* FRU Inventory Device
* Chassis Device
*
**************************************************************************/
#define BUFFER (80)
int ipmiUtil_mc_info_load ( string hostname, const char * filename, mc_info_type & mc_info )
{
int rc = FAIL ;
ipmiUtil_mc_info_init ( mc_info );
if ( daemon_is_file_present ( filename ) )
{
FILE * _stream = fopen ( filename, "r" );
if ( _stream )
{
char buffer [BUFFER];
MEMSET_ZERO(buffer);
while ( fgets (buffer, BUFFER, _stream) )
{
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_FW_VERSION, MC_INFO_LABEL_DELIMITER, mc_info.fw_version ))
{
rc = PASS ;
continue;
}
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_HW_VERSION, MC_INFO_LABEL_DELIMITER, mc_info.hw_version ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_DEVICE_ID, MC_INFO_LABEL_DELIMITER, mc_info.device_id ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_PRODUCT_ID, MC_INFO_LABEL_DELIMITER, mc_info.product_id ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_PRODUCT_NAME, MC_INFO_LABEL_DELIMITER, mc_info.product_name ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_MANUFACTURE_ID, MC_INFO_LABEL_DELIMITER, mc_info.manufacturer_id ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_MANUFACTURE_NAME, MC_INFO_LABEL_DELIMITER, mc_info.manufacturer_name ))
continue;
else
blog3 ("buffer: %s\n", buffer );
MEMSET_ZERO(buffer);
}
fclose(_stream);
}
}
else
{
elog ("%s failed to open mc info file '%s'\n", hostname.c_str(), filename);
rc = FAIL_FILE_ACCESS ;
}
mc_info_log ( hostname, mc_info, rc );
return (rc);
}