Add redfish support detection to maintenance

This update

1. Refactors some of the common maintenance ipmi
   definitions and utilities into a more generic
   'bmcUtil' module to reduce code duplication and improve
   improve code reuse with the introduction of a second
   bmc communication protocol ; redfish.

2. Creates a new 'redFishUtil' module similar to the existing
   'ipmiUtil' module but in support of common redfish
   utilities and definitions that can be used by both
   maintenance and the hardware monitor.

3. Moves the existing 'mtcIpmiUtil' module to a more common
   'mtcBmcUtil' and renames the 'ipmi_command_send/recv' to
   the more generic 'bmc_command_send/recv' which are enhanced
   to support both ipmi and redfish bmc communication methods.

4. Renames the bmc info collection and connection monitor ;
   'bm_handler' to 'bmc_handler' and adds support necessary
   to learn if a host's bmc supports redfish.

5. Renames the existing 'mtcThread_ipmitool' to a more common
   'mtcThread_bmc' and redfishtool support for the now common
   set of bmc thread commands and the addition of the new
   redfishtool bmc query, aka 'redfish root query', used to
   detect if a host's bmc supports redfish.

   Note: This aspect is the primary feature of this update.

         Namely the ability to detect and print a log indicating
         if a host's bmc supports redfish.

Test Plan:

PASS: Verify sensor monitoring and alarming still works.
PASS: Verify power-off command handling.
PASS: Verify power-on command handling.
PASS: Verify reset command handling.
PASS: Verify reinstall (netboot) command handling.
PASS: Verify logging when redfish is not supported.
PASS: Verify logging when redfish is supported.
PASS: Verify ipmitool is used regardless of redfish support.
PASS: Verify mtce thread error handling for both protocols.

Change-Id: I72e63958f61d10f5c0d4a93a49a7f39bdd53a76f
Story: 2005861
Task: 35825
Signed-off-by: Eric MacDonald <eric.macdonald@windriver.com>
This commit is contained in:
Eric MacDonald 2019-07-17 13:31:13 -04:00
parent 5b9ae3a5ff
commit 804ec52227
42 changed files with 2300 additions and 1711 deletions

View File

@ -163,7 +163,7 @@ function install_mtce_common {
local libdaecom_file=( \
"common/libcommon.a" \
"common/libthreadUtil.a" \
"common/libipmiUtil.a" \
"common/libbmcUtils.a" \
"common/libpingUtil.a" \
"common/libnodeBase.a" \
"common/libregexUtil.a" \
@ -190,7 +190,9 @@ function install_mtce_common {
"common/timeUtil.h" \
"common/alarmUtil.h" \
"common/hostUtil.h" \
"common/bmcUtil.h" \
"common/ipmiUtil.h" \
"common/redfishUtil.h" \
"common/nlEvent.h" \
"common/pingUtil.h" \
"common/regexUtil.h" \
@ -898,7 +900,7 @@ function cleanup_metal {
local libdaecom_file=( \
"libcommon.a" \
"libthreadUtil.a" \
"libipmiUtil.a" \
"libBmcUtils.a" \
"libpingUtil.a" \
"libnodeBase.a" \
"libregexUtil.a" \

View File

@ -99,7 +99,7 @@ install -m 755 -d %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/daemon/libdaemon.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libcommon.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libthreadUtil.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libipmiUtil.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libbmcUtils.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libpingUtil.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libnodeBase.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libregexUtil.a %{buildroot}%{_libdir}
@ -134,6 +134,8 @@ install -m 644 -p -D %{_buildsubdir}/daemon/daemon_option.h %{buildroot}%{_inclu
install -m 644 -p -D %{_buildsubdir}/common/alarmUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/hostUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/ipmiUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/redfishUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/bmcUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/nlEvent.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/pingUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/regexUtil.h %{buildroot}%{_includedir}/mtce-common

View File

@ -8,7 +8,9 @@ SHELL = /bin/bash
SRCS = regexUtil.cpp \
timeUtil.cpp \
bmcUtil.cpp \
ipmiUtil.cpp \
redfishUtil.cpp \
pingUtil.cpp \
keyClass.cpp \
hostClass.cpp \
@ -76,7 +78,7 @@ threadUtil:
library:
ar rcs libcommon.a $(COMMON_OBJS) $(EXTRAARFLAGS)
ar rcs libipmiUtil.a ipmiUtil.o $(EXTRAARFLAGS)
ar rcs libbmcUtils.a bmcUtil.o ipmiUtil.o redfishUtil.o $(EXTRAARFLAGS)
ar rcs libpingUtil.a pingUtil.o $(EXTRAARFLAGS)
ar rcs libnodeBase.a nodeBase.o $(EXTRAARFLAGS)
ar rcs libregexUtil.a regexUtil.o $(EXTRAARFLAGS)

View File

@ -0,0 +1,260 @@
/*
* Copyright (c) 2019 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*
*
* @file
* Starling-X Common Bmc Utilities
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
#include "nodeBase.h" /* for ... mtce-common node definitions */
#include "hostUtil.h" /* for ... mtce-common host definitions */
#include "bmcUtil.h" /* for ... mtce-common bmc utility header */
/**********************************************************************
*
* Name : bmcUtil_getCmd_str
*
* Purpose : logging ; bmc request
*
* Description: return string representing command
*
* Construct : static array of bmc request strings
*
* bmcUtil_request_str_array
*
* Assumptions: initialized in module init
*
**********************************************************************/
static std::string bmcUtil_request_str_array [BMC_THREAD_CMD__LAST+1] ;
string bmcUtil_getCmd_str ( int command )
{
if ( command >= BMC_THREAD_CMD__LAST )
{
slog ("Invalid thread command (%d)\n", command );
return (bmcUtil_request_str_array[BMC_THREAD_CMD__LAST]);
}
return (bmcUtil_request_str_array[command]);
}
/**********************************************************************
*
* Name : bmcUtil_getAction_str
*
* Purpose : logging ; bmc action
*
* Description: return string representing action
*
* Construct : static array of bmc action strings
*
* bmcUtil_action_str_array
*
* Assumptions: initialized in module init
*
**********************************************************************/
static std::string bmcUtil_action_str_array [BMC_THREAD_CMD__LAST+1] ;
string bmcUtil_getAction_str ( int action )
{
if ( action >= BMC_THREAD_CMD__LAST )
{
slog ("Invalid thread action (%d)\n", action );
return (bmcUtil_action_str_array[BMC_THREAD_CMD__LAST]);
}
return (bmcUtil_action_str_array[action]);
}
/**********************************************************************
*
* Name : bmcUtil_getProtocol_str
*
* Purpose : logging ; bmc protocol name
*
* Description: return string representing bmc protocol name
*
**********************************************************************/
string bmcUtil_getProtocol_str ( bmc_protocol_enum protocol )
{
switch (protocol)
{
case BMC_PROTOCOL__REDFISHTOOL: return("redfishtool");
case BMC_PROTOCOL__IPMITOOL: return("ipmitool");
default: return("unknown");
}
}
/*************************************************************************
*
* Name : bmcUtil_init
*
* Purpose : Initialize various common Board Management support
* service functions and aspects.
*
* Description: Init support for IPMI and Redfish
*
* Returns : Initialization result ; always PASS (for now)
*
*************************************************************************/
int bmcUtil_init ( void )
{
daemon_make_dir(BMC_OUTPUT_DIR) ;
ipmiUtil_init ();
redfishUtil_init ();
#ifdef WANT_FIT_TESTING
daemon_make_dir(FIT__INFO_FILEPATH);
#endif
/* init static strings */
bmcUtil_request_str_array[BMC_THREAD_CMD__POWER_RESET] = "Reset";
bmcUtil_request_str_array[BMC_THREAD_CMD__POWER_ON] = "Power-On";
bmcUtil_request_str_array[BMC_THREAD_CMD__POWER_OFF] = "Power-Off";
bmcUtil_request_str_array[BMC_THREAD_CMD__POWER_CYCLE] = "Power-Cycle";
bmcUtil_request_str_array[BMC_THREAD_CMD__BMC_QUERY] = "Query BMC Root";
bmcUtil_request_str_array[BMC_THREAD_CMD__BMC_INFO] = "Query BMC Info";
bmcUtil_request_str_array[BMC_THREAD_CMD__POWER_STATUS] = "Query Power Status";
bmcUtil_request_str_array[BMC_THREAD_CMD__RESTART_CAUSE] = "Query Reset Reason";
bmcUtil_request_str_array[BMC_THREAD_CMD__BOOTDEV_PXE] = "Netboot";
bmcUtil_request_str_array[BMC_THREAD_CMD__READ_SENSORS] = "Read Sensors";
bmcUtil_request_str_array[BMC_THREAD_CMD__LAST] = "unknown";
bmcUtil_action_str_array[BMC_THREAD_CMD__POWER_RESET] = "resetting";
bmcUtil_action_str_array[BMC_THREAD_CMD__POWER_ON] = "powering on";
bmcUtil_action_str_array[BMC_THREAD_CMD__POWER_OFF] = "powering off";
bmcUtil_action_str_array[BMC_THREAD_CMD__POWER_CYCLE] = "power cycling";
bmcUtil_action_str_array[BMC_THREAD_CMD__BMC_QUERY] = "querying bmc root";
bmcUtil_action_str_array[BMC_THREAD_CMD__BMC_INFO] = "querying bmc info";
bmcUtil_action_str_array[BMC_THREAD_CMD__POWER_STATUS] = "querying power status";
bmcUtil_action_str_array[BMC_THREAD_CMD__RESTART_CAUSE] = "querying reset cause";
bmcUtil_action_str_array[BMC_THREAD_CMD__BOOTDEV_PXE] = "setting next boot dev";
bmcUtil_action_str_array[BMC_THREAD_CMD__READ_SENSORS] = "reading sensors";
bmcUtil_action_str_array[BMC_THREAD_CMD__LAST] = "unknown";
return (PASS);
}
/*************************************************************************
*
* Name : bmcUtil_info_init
*
* Purpose : Initialize the BMC information struct.
*
* Returns : nothing
*
*************************************************************************/
void bmcUtil_info_init ( bmc_info_type & bmc_info )
{
bmc_info.device_id.clear();
bmc_info.manufacturer_name.clear();
bmc_info.manufacturer_id.clear();
bmc_info.product_name.clear();
bmc_info.product_id.clear();
bmc_info.fw_version.clear();
bmc_info.hw_version.clear();
}
/*************************************************************************
*
* Name : bmcUtil_create_pw_file
*
* Purpose : Create a randomly named password filename
*
* Description: Create based on protocol.
* Add the password info to the file.
* Attach filename to thread info.
*
* Returns : Error status passed through thread info status
* and status string
*
*************************************************************************/
void bmcUtil_create_pw_file ( thread_info_type * info_ptr,
string pw_file_content,
bmc_protocol_enum protocol )
{
string password_tempfile ;
info_ptr->password_file.clear ();
/* protocol specific output dir */
if ( protocol == BMC_PROTOCOL__REDFISHTOOL )
password_tempfile = REDFISHTOOL_OUTPUT_DIR ;
else
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_file_content );
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 ;
info_ptr->status_string = "" ;
info_ptr->status = PASS ;
}
}
/*************************************************************************
*
* Name : bmcUtil_create_data_fn
*
* Purpose : Create a outout data filename
*
* Description: Create based on protocol.
*
* Returns : datafile name as a string
*
*************************************************************************/
string bmcUtil_create_data_fn ( string & hostname,
string file_suffix,
bmc_protocol_enum protocol )
{
/* create the output filename */
string datafile ;
/* protocol specific output dir */
if ( protocol == BMC_PROTOCOL__REDFISHTOOL )
datafile = REDFISHTOOL_OUTPUT_DIR ;
else
datafile = IPMITOOL_OUTPUT_DIR ;
datafile.append(program_invocation_short_name);
datafile.append("_");
datafile.append(hostname);
/* add the sensor list command */
datafile.append(file_suffix);
return ( datafile );
}

View File

@ -0,0 +1,92 @@
#ifndef __INCLUDE_BMCUTIL_H__
#define __INCLUDE_BMCUTIL_H__
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Starling-X BMC Utilities Header
*/
#include "nodeBase.h" /* for ... */
#include "threadUtil.h" /* for ... thread_info_type and utilities */
#define BMC_OUTPUT_DIR ((const char *)("/var/run/bmc/"))
#define BMC_DEFAULT_INFO ((const char *)("{\"power_state\":\"off\",\"protocol\":\"ipmitool\"}"))
/* important BMC query info to log and track */
typedef struct
{
std::string product_name ;
std::string product_id ;
std::string manufacturer_name ;
std::string manufacturer_id ;
std::string device_id ;
std::string fw_version ;
std::string hw_version ;
} bmc_info_type ;
/* BMC commands */
typedef enum
{
BMC_THREAD_CMD__BMC_QUERY = 0,
BMC_THREAD_CMD__POWER_RESET,
BMC_THREAD_CMD__POWER_ON,
BMC_THREAD_CMD__POWER_OFF,
BMC_THREAD_CMD__POWER_CYCLE,
BMC_THREAD_CMD__BMC_INFO,
BMC_THREAD_CMD__POWER_STATUS,
BMC_THREAD_CMD__RESTART_CAUSE,
BMC_THREAD_CMD__BOOTDEV_PXE,
BMC_THREAD_CMD__READ_SENSORS,
BMC_THREAD_CMD__LAST
} bmc_cmd_enum ;
#define BMC_QUERY_FILE_SUFFIX ((const char *)("_root_query"))
#define BMC_INFO_FILE_SUFFIX ((const char *)("_bmc_info"))
#define BMC_POWER_CMD_FILE_SUFFIX ((const char *)("_power_cmd_result"))
#define BMC_BOOTDEV_CMD_FILE_SUFFIX ((const char *)("_bootdev"))
#define BMC_RESTART_CAUSE_FILE_SUFFIX ((const char *)("_restart_cause"))
#define BMC_POWER_STATUS_FILE_SUFFIX ((const char *)("_power_status"))
#define BMC_SENSOR_OUTPUT_FILE_SUFFIX ((const char *)("_sensor_data"))
#define BMC_MAX_RECV_RETRIES (10)
/* get the thread command name string */
string bmcUtil_getCmd_str ( int command );
string bmcUtil_getAction_str ( int action );
string bmcUtil_getProtocol_str ( bmc_protocol_enum protocol );
/* module initialization */
int bmcUtil_init ( void );
/* bmc info initialization */
void bmcUtil_info_init ( bmc_info_type & bmc_info );
/* create the a password file */
void bmcUtil_create_pw_file ( thread_info_type * info_ptr,
string pw_file_content,
bmc_protocol_enum protocol );
/* create the output filename */
string bmcUtil_create_data_fn ( string & hostname,
string file_suffix,
bmc_protocol_enum protocol );
#include "ipmiUtil.h" /* for ... mtce-common ipmi utility header */
#include "redfishUtil.h" /* for ... mtce-common redfish utility header */
#endif

View File

@ -50,10 +50,11 @@
#define MTC_CMD_FIT__AMON_SOCK ("/var/run/fit/amon_sock") /* mtcClient */
#define MTC_CMD_FIT__NO_CLSTR_RSP ("/var/run/fit/no_clstr_rsp") /* hbsClient */
#define MTC_CMD_FIT__NO_MGMNT_RSP ("/var/run/fit/no_mgmnt_rsp") /* hbsClient */
#define MTC_CMD_FIT__LINKLIST ("/var/run/fit/linklist") /* hbsAgent */
#define MTC_CMD_FIT__LINKLIST ("/var/run/fit/linklist") /* hbsAgent */
#define MTC_CMD_FIT__HBSSILENT ("/var/run/fit/hbs_silent_fault") /* hbsAgent */
#define MTC_CMD_FIT__SENSOR_DATA ("/var/run/fit/sensor_data") /* hwmond */
#define MTC_CMD_FIT__SENSOR_DATA ("/var/run/fit/sensor_data") /* hwmond */
#define MTC_CMD_FIT__POWER_CMD ("/var/run/fit/power_cmd_result") /* mtcAgent */
#define MTC_CMD_FIT__ROOT_QUERY ("/var/run/fit/root_query") /* mtcAgent */
#define MTC_CMD_FIT__MC_INFO ("/var/run/fit/mc_info") /* mtcAgent */
#define MTC_CMD_FIT__POWER_STATUS ("/var/run/fit/power_status") /* mtcAgent */
#define MTC_CMD_FIT__RESTART_CAUSE ("/var/run/fit/restart_cause") /* mtcAgent */
@ -117,8 +118,8 @@
#define FIT_CODE__FM_GET_ALARM (41)
#define FIT_CODE__FM_QRY_ALARMS (42)
#define FIT_CODE__IPMI_COMMAND_SEND (60)
#define FIT_CODE__IPMI_COMMAND_RECV (61)
#define FIT_CODE__BMC_COMMAND_SEND (60)
#define FIT_CODE__BMC_COMMAND_RECV (61)
#define FIT_CODE__START_HOST_SERVICES (70)
#define FIT_CODE__STOP_HOST_SERVICES (71)

View File

@ -19,40 +19,6 @@ using namespace std;
#include "nodeBase.h"
/* Supported Server Names */
//#define SERVER__UNKNOWN ((const char*)"Undetermined Server")
//#define SERVER__NOKIA_QUANTA_1234_GEN1 ((const char*)"Quanta Computer")
//#define SERVER__HP_PROLIANT_DL380_GEN9 ((const char*)"ProLiant DL380 Gen9")
//#define SERVER__HP_PROLIANT_DL360_GEN9 ((const char*)"ProLiant DL360 Gen9")
/* Supported Board Management Controller Names */
//#define SERVER_BMC__UNKNOWN ((const char*)"Unknown BMC")
//#define SERVER_BMC__STANDARD_ILO_V3 ((const char*)"iLO 3 Standard")
//#define SERVER_BMC__STANDARD_ILO_V4 ((const char*)"iLO 4 Standard")
/* A list of supported servers */
//typedef enum
//{
// SERVER_IS_UNKNOWN = 0,
// SERVER_IS_NOKIA__QUANTA_1234____GEN1__ILO_V4 = 1,
// SERVER_IS_HP_____PROLIANT_DL380_GEN9__ILO_V4 = 2,
// SERVER_IS_HP_____PROLIANT_DL360_GEN9__ILO_V4 = 3,
// SERVER_IS_LAST = 4
//} server_enum ;
/* Server Table Entry Type */
//typedef struct
//{
// server_enum server_code ;
// protocol_enum protocol ;
// const char * server_name ;
// const char * server_bmc ;
// const char * profile ;
//
//} server_table_entry_type ;
//server_table_entry_type * hostUtil_get_server_info ( server_enum server_code );
typedef enum
{
CLIENT_NONE = 0,

View File

@ -14,9 +14,25 @@
using namespace std;
#include "nodeBase.h" /* for ... mtce node common definitions */
#include "ipmiUtil.h" /* for ... module header */
#include "hostUtil.h" /* for ... mtce host common definitions */
#include "ipmiUtil.h" /* for ... this module header */
/***********************************************************************
*
* Name : ipmiUtil_init
*
* Purpose : Module init
*
* Description: Performs the following functions
*
* 1. creates the ipmitool runtime temp dir
*
***********************************************************************/
int ipmiUtil_init ( void )
{
daemon_make_dir(IPMITOOL_OUTPUT_DIR) ;
return(PASS);
}
/* Create a randomly named password filename */
void ipmiUtil_create_pw_fn ( thread_info_type * info_ptr, string pw )
@ -103,20 +119,8 @@ string ipmiUtil_create_request ( string cmd, string & ip, string & un, string &
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 )
void ipmiUtil_bmc_info_log ( string hostname, bmc_info_type & bmc_info, int rc )
{
if ( rc )
{
@ -126,16 +130,16 @@ void mc_info_log ( string hostname, mc_info_type & mc_info, int rc )
{
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());
bmc_info.manufacturer_name.c_str(),
bmc_info.manufacturer_id.c_str(),
bmc_info.device_id.c_str(),
bmc_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());
bmc_info.product_name.c_str(),
bmc_info.product_id.c_str(),
bmc_info.fw_version.c_str());
}
}
@ -161,10 +165,10 @@ bool _got_delimited_value ( char * buf_ptr, const char * key, const char * delim
/*****************************************************************************
*
* Name : ipmiUtil_mc_info_load
* Name : ipmiUtil_bmc_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
* output from an mc info request into the passed in bmc_info
* struct. Loaded info includes
*
* Manufacturer (id/name)
@ -198,10 +202,9 @@ bool _got_delimited_value ( char * buf_ptr, const char * key, const char * delim
**************************************************************************/
#define BUFFER (80)
int ipmiUtil_mc_info_load ( string hostname, const char * filename, mc_info_type & mc_info )
int ipmiUtil_bmc_info_load ( string hostname, const char * filename, bmc_info_type & bmc_info )
{
int rc = FAIL ;
ipmiUtil_mc_info_init ( mc_info );
if ( daemon_is_file_present ( filename ) )
{
FILE * _stream = fopen ( filename, "r" );
@ -211,22 +214,22 @@ int ipmiUtil_mc_info_load ( string hostname, const char * filename, mc_info_type
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 ))
if ( _got_delimited_value ( buffer, BMC_INFO_LABEL_FW_VERSION, BMC_INFO_LABEL_DELIMITER, bmc_info.fw_version ))
{
rc = PASS ;
continue;
}
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_HW_VERSION, MC_INFO_LABEL_DELIMITER, mc_info.hw_version ))
if ( _got_delimited_value ( buffer, BMC_INFO_LABEL_HW_VERSION, BMC_INFO_LABEL_DELIMITER, bmc_info.hw_version ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_DEVICE_ID, MC_INFO_LABEL_DELIMITER, mc_info.device_id ))
if ( _got_delimited_value ( buffer, BMC_INFO_LABEL_DEVICE_ID, BMC_INFO_LABEL_DELIMITER, bmc_info.device_id ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_PRODUCT_ID, MC_INFO_LABEL_DELIMITER, mc_info.product_id ))
if ( _got_delimited_value ( buffer, BMC_INFO_LABEL_PRODUCT_ID, BMC_INFO_LABEL_DELIMITER, bmc_info.product_id ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_PRODUCT_NAME, MC_INFO_LABEL_DELIMITER, mc_info.product_name ))
if ( _got_delimited_value ( buffer, BMC_INFO_LABEL_PRODUCT_NAME, BMC_INFO_LABEL_DELIMITER, bmc_info.product_name ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_MANUFACTURE_ID, MC_INFO_LABEL_DELIMITER, mc_info.manufacturer_id ))
if ( _got_delimited_value ( buffer, BMC_INFO_LABEL_MANUFACTURE_ID, BMC_INFO_LABEL_DELIMITER, bmc_info.manufacturer_id ))
continue;
if ( _got_delimited_value ( buffer, MC_INFO_LABEL_MANUFACTURE_NAME, MC_INFO_LABEL_DELIMITER, mc_info.manufacturer_name ))
if ( _got_delimited_value ( buffer, BMC_INFO_LABEL_MANUFACTURE_NAME, BMC_INFO_LABEL_DELIMITER, bmc_info.manufacturer_name ))
continue;
else
blog3 ("buffer: %s\n", buffer );
@ -241,6 +244,6 @@ int ipmiUtil_mc_info_load ( string hostname, const char * filename, mc_info_type
rc = FAIL_FILE_ACCESS ;
}
mc_info_log ( hostname, mc_info, rc );
ipmiUtil_bmc_info_log ( hostname, bmc_info, rc );
return (rc);
}

View File

@ -13,17 +13,20 @@
* Wind River Titanium Cloud's Maintenance Common IPMI Utilities Header
*/
#include "nodeBase.h" /* for ... */
#include "threadUtil.h" /* for ... thread utilities */
#include "bmcUtil.h" /* for ... mtce-common bmc utility header */
#define MC_INFO_LABEL_DELIMITER ((const char *)(": "))
#define MC_INFO_LABEL_FW_VERSION ((const char *)("Firmware Revision"))
#define MC_INFO_LABEL_HW_VERSION ((const char *)("Device Revision"))
#define MC_INFO_LABEL_DEVICE_ID ((const char *)("Device ID"))
#define MC_INFO_LABEL_PRODUCT_ID ((const char *)("Product ID"))
#define MC_INFO_LABEL_PRODUCT_NAME ((const char *)("Product Name"))
#define MC_INFO_LABEL_MANUFACTURE_ID ((const char *)("Manufacturer ID"))
#define MC_INFO_LABEL_MANUFACTURE_NAME ((const char *)("Manufacturer Name"))
#define THREAD_NAME__BMC ((const char *)("bmc"))
#define IPMITOOL_PATH_AND_FILENAME ((const char *)("/usr/bin/ipmitool"))
#define IPMITOOL_OUTPUT_DIR ((const char *)("/var/run/bmc/ipmitool/"))
#define BMC_INFO_LABEL_DELIMITER ((const char *)(": "))
#define BMC_INFO_LABEL_FW_VERSION ((const char *)("Firmware Revision"))
#define BMC_INFO_LABEL_HW_VERSION ((const char *)("Device Revision"))
#define BMC_INFO_LABEL_DEVICE_ID ((const char *)("Device ID"))
#define BMC_INFO_LABEL_PRODUCT_ID ((const char *)("Product ID"))
#define BMC_INFO_LABEL_PRODUCT_NAME ((const char *)("Product Name"))
#define BMC_INFO_LABEL_MANUFACTURE_ID ((const char *)("Manufacturer ID"))
#define BMC_INFO_LABEL_MANUFACTURE_NAME ((const char *)("Manufacturer Name"))
#define IPMITOOL_POWER_RESET_CMD ((const char *)("chassis power reset"))
#define IPMITOOL_POWER_RESET_RESP ((const char *)("Chassis Power Control: Reset"))
@ -46,53 +49,14 @@
#define IPMITOOL_BOOTDEV_PXE_CMD ((const char *)("chassis bootdev pxe"))
#define IPMITOOL_BOOTDEV_PXE_RESP ((const char *)("Set Boot Device to pxe"))
#define IPMITOOL_MC_INFO_CMD ((const char *)("mc info"))
#define IPMITOOL_BMC_INFO_CMD ((const char *)("mc info"))
#define IPMITOOL_CMD_FILE_SUFFIX ((const char *)("_power_cmd_result"))
#define IPMITOOL_MC_INFO_FILE_SUFFIX ((const char *)("_mc_info"))
#define IPMITOOL_RESTART_CAUSE_FILE_SUFFIX ((const char *)("_restart_cause"))
#define IPMITOOL_POWER_STATUS_FILE_SUFFIX ((const char *)("_power_status"))
#define BMC__MAX_RECV_RETRIES (10)
#define IPMITOOL_MAX_RECV_RETRIES (10)
int ipmiUtil_init ( void );
/* Warning : Changes here require 'mtc_ipmiRequest_str' string array to be updated */
typedef enum
{
IPMITOOL_THREAD_CMD__NULL = 0,
IPMITOOL_THREAD_CMD__POWER_RESET,
IPMITOOL_THREAD_CMD__POWER_ON,
IPMITOOL_THREAD_CMD__POWER_OFF,
IPMITOOL_THREAD_CMD__POWER_CYCLE,
IPMITOOL_THREAD_CMD__MC_INFO,
IPMITOOL_THREAD_CMD__POWER_STATUS,
IPMITOOL_THREAD_CMD__RESTART_CAUSE,
IPMITOOL_THREAD_CMD__BOOTDEV_PXE,
IPMITOOL_THREAD_CMD__READ_SENSORS,
IPMITOOL_THREAD_CMD__LAST
} ipmitool_cmd_enum ;
const char * getIpmiCmd_str ( int command );
const char * getIpmiAction_str ( int command );
typedef struct
{
std::string product_name ;
std::string product_id ;
std::string manufacturer_name ;
std::string manufacturer_id ;
std::string device_id ;
std::string fw_version ;
std::string hw_version ;
} mc_info_type ;
int ipmiUtil_mc_info_load ( string hostname, const char * filename, mc_info_type & mc_info );
void ipmiUtil_mc_info_init ( mc_info_type & mc_info );
int ipmiUtil_bmc_info_load ( string hostname, const char * filename, bmc_info_type & mc_info );
void ipmiUtil_mc_info_init ( bmc_info_type & mc_info );
/* Create a randomly named password filename */
void ipmiUtil_create_pw_fn ( thread_info_type * info_ptr, string pw );

View File

@ -153,10 +153,13 @@ void daemon_exit ( void );
#define BM_DNSMASQ_FILENAME ((const char *)"dnsmasq.bmc_hosts")
#define THREAD_NAME__IPMITOOL ((const char *)("ipmitool"))
/* supported BMC communication protocols ; access method */
typedef enum
{
BMC_PROTOCOL__IPMITOOL,
BMC_PROTOCOL__REDFISHTOOL,
} bmc_protocol_enum ;
#define IPMITOOL_PATH_AND_FILENAME ((const char *)("/usr/bin/ipmitool"))
#define IPMITOOL_OUTPUT_DIR ((const char *)("/var/run/ipmitool/"))
/** 'lo' interface IP address - TODO: get it from the interface */
#define LOOPBACK_IP "127.0.0.1"
@ -309,7 +312,7 @@ void daemon_exit ( void );
#define MTC_POWER_ACTION_RETRY_COUNT (10)
#define MTC_RESET_ACTION_RETRY_COUNT (5)
/* number of calls to the bm_handler while bm_access is not confirmed */
/* number of calls to the bmc_handler while bm_access is not confirmed */
#define MTC_MAX_B2B_BM_ACCESS_FAIL_COUNT_B4_ALARM (5)
/* string too long for inv */
#define MTC_TASK_DISABLE_REJ "Lock Rejected: Incomplete Migration" /* Please Enable More Worker Resources" */
@ -738,15 +741,6 @@ typedef struct
const char * get_mtcNodeCommand_str ( int cmd );
typedef enum
{
PROTOCOL__NONE = 0,
PROTOCOL__SMASH = 1,
PROTOCOL__IPMI = 2,
PROTOCOL__MAX = 3
} protocol_enum ;
/** Maintenance Commands used to specify HTTP REST API Command operations */
typedef enum
{

View File

@ -89,6 +89,7 @@
#define SM_NOTIFY_UNHEALTHY_DELAY_SECS (5)
#define MTC_MIN_ONLINE_PERIOD_SECS (7)
#define MTC_RETRY_WAIT (5)
#define MTC_FIRST_WAIT (3)
#define MTC_AGENT_TIMEOUT_EXTENSION (5)
#define MTC_LOCK_CEPH_DELAY (90)

View File

@ -0,0 +1,184 @@
/*
* Copyright (c) 2019 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*
*
* @file
* Starling-X Common Redfish 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 "jsonUtil.h" /* for ... */
#include "redfishUtil.h" /* for ... this module header */
/*************************************************************************
*
* Name : redfishUtil_init
*
* Purpose : Module init
*
* Description: Initialize redfish tool utility module.
*
* Returns : Initialization result ; always PASS (for now)
*
*************************************************************************/
int redfishUtil_init ( void )
{
daemon_make_dir(REDFISHTOOL_OUTPUT_DIR) ;
return (PASS);
}
/*************************************************************************
*
* Name : redfishUtil_is_supported
*
* Purpose : Check for redfish supported response
*
* Description: A redfish root query response that indicates redfish
* protocol support includes the following key:value.
*
* "RedfishVersion": "1.0.1",
*
* Assumptions: Must support redfish version 1.x.x or higher.
*
* Parameters : The root query response string
*
* Returns : true if redfish is supported.
* false otherwise
*
*************************************************************************/
bool redfishUtil_is_supported (string & hostname, string & response)
{
if ( response.length() > strlen(REDFISH_LABEL__FW_VERSION ))
{
string redfish_version = "" ;
/* look for error ; stderro is directed to the datafile */
if ( response.find(REDFISHTOOL_RESPONSE_ERROR) != string::npos )
{
if ( response.find(REDFISHTOOL_ERROR_STATUS_CODE__NOT_FOUND) != string::npos )
{
ilog ("%s does not support Redfish platform management",
hostname.c_str());
}
else
{
wlog ("%s redfishtool %s: %s",
hostname.c_str(),
REDFISHTOOL_RESPONSE_ERROR,
response.c_str());
}
return (false) ;
}
/* if no error then look for the redfish version number */
if ( jsonUtil_get_key_val ((char*)response.data(),
REDFISH_LABEL__FW_VERSION,
redfish_version) == PASS )
{
if ( ! redfish_version.empty() )
{
int major = 0, minor = 0, revision = 0 ;
int fields = sscanf ( redfish_version.data(),
"%d.%d.%d",
&major,
&minor,
&revision );
if (( fields ) && ( major >= REDFISH_MIN_MAJOR_VERSION ))
{
ilog ("%s bmc redfish version %s (%d.%d.%d)",
hostname.c_str(),
redfish_version.c_str(),
major, minor, revision );
return true ;
}
else
{
ilog ("%s bmc has unsupported redfish version %s (%d:%d.%d.%d)",
hostname.c_str(),
redfish_version.c_str(),
fields, major, minor, revision );
ilog ("%s response: %s", hostname.c_str(), response.c_str()); // ERIK: make blog ?
}
}
else
{
wlog ("%s bmc failed to provide redfish version\n%s",
hostname.c_str(),
response.c_str());
}
}
else
{
wlog ("%s bmc redfish root query response has no '%s' label\n%s",
hostname.c_str(),
REDFISH_LABEL__FW_VERSION,
response.c_str());
}
}
else
{
ilog ("%s bmc does not support redfish",
hostname.c_str());
}
return false ;
}
/*************************************************************************
*
* Name : redfishUtil_create_request
*
* Purpose : create redfishtool command request
*
* Description: A command request involves command options / arguements
*
* -r ip - the ip address to send the request to
* -c config_file - the bmc cfgFile (password) filename
* cmd - the redfish command to execute
* > out - the filename to where the output is directed
*
* Returns : full command request as a single string
*
*************************************************************************/
string redfishUtil_create_request ( string cmd,
string & ip,
string & config_file,
string & out )
{
/* build the command ; starting with the redfishtool binary */
string command_request = REDFISHTOOL_PATH_AND_FILENAME ;
/* specify the bmc ip address */
command_request.append(" -r ");
command_request.append(ip);
/* add the config file option and config filename */
command_request.append(" -c ");
command_request.append(config_file);
/* add the command */
command_request.append(" ");
command_request.append(cmd);
/* output filename */
command_request.append (" > ");
command_request.append (out);
/* direct stderr to stdio */
command_request.append (" 2>&1");
return (command_request);
}

View File

@ -0,0 +1,53 @@
#ifndef __INCLUDE_REDFISHUTIL_H__
#define __INCLUDE_REDFISHUTIL_H__
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Starling-X Common Redfish Utilities Header
*/
#include "bmcUtil.h" /* for ... mtce-common bmc utility header */
#define REDFISHTOOL_PATH_AND_FILENAME ((const char *)("/usr/bin/redfishtool"))
#define REDFISHTOOL_OUTPUT_DIR ((const char *)("/var/run/bmc/redfishtool/"))
#define REDFISH_LABEL__FW_VERSION ((const char *)("RedfishVersion"))
#define REDFISH_MIN_MAJOR_VERSION (1)
#define REDFISHTOOL_ROOT_QUERY_CMD ((const char *)("root"))
#define REDFISHTOOL_BMC_INFO_CMD ((const char *)("Systems get"))
#define REDFISHTOOL_POWER_RESET_CMD ((const char *)("Systems reset GracefulRestart"))
#define REDFISHTOOL_POWER_ON_CMD ((const char *)("Systems reset On"))
#define REDFISHTOOL_POWER_OFF_CMD ((const char *)("Systems reset ForceOff"))
#define REDFISHTOOL_BOOTDEV_PXE_CMD ((const char *)("Systems setBootOverride Once Pxe"))
/* no support response string
*
* redfishtool:Transport: Response Error: status_code: 404 -- Not Found
*
*/
#define REDFISHTOOL_RESPONSE_ERROR ((const char *)("Response Error"))
#define REDFISHTOOL_ERROR_STATUS_CODE__NOT_FOUND ((const char *)("status_code: 404"))
#define REDFISHTOOL_ERROR_STATUS_CODE__NOT_ALLOWED ((const char *)("status_code: 405"))
/* module init */
int redfishUtil_init ( void );
/* create a redfish tool thread request */
string redfishUtil_create_request ( string cmd,
string & ip,
string & config_file,
string & out );
/* interpret redfish root query response and check version */
bool redfishUtil_is_supported ( string & hostname, string & root_query_response );
#endif // __INCLUDE_REDFISHUTIL_H__

View File

@ -131,37 +131,37 @@ using namespace std;
#define dlog_t(format, args...) { \
if(daemon_get_cfg_ptr()->debug_level&1) \
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s:Debug : " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s:debug : " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
#define dlog1_t(format, args...) { \
if(daemon_get_cfg_ptr()->debug_level&2) \
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s:Debug2: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s:debug2: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
#define dlog2_t(format, args...) { \
if(daemon_get_cfg_ptr()->debug_level&4) \
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s:Debug4: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s:debug4: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
#define dlog3_t(format, args...) { \
if(daemon_get_cfg_ptr()->debug_level&8) \
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s:Debug8: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s:debug8: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
#define blog_t(format, args...) { \
if(daemon_get_cfg_ptr()->debug_bmgmt&1) \
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s: BMgt : " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s: bmgt : " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
#define blog1_t(format, args...) { \
if(daemon_get_cfg_ptr()->debug_bmgmt&2) \
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s: BMgt2: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s: bmgt2: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
#define blog2_t(format, args...) { \
if(daemon_get_cfg_ptr()->debug_bmgmt&4) \
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s: BMgt4: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s: bmgt4: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
#define blog3_t(format, args...) { \
if(daemon_get_cfg_ptr()->debug_bmgmt&8) \
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s: BMgt8: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
{ syslog(LOG_INFO, "[%ld.%05d] %s %s %-3s %-18s(%4d) %-24s: bmgt8: " format, gettid(), lc(), _hn(), _pn, __AREA__, __FILE__, __LINE__, __FUNCTION__, ##args) ; }}
#define THREAD_INIT_SIG (0xbabef00d)
#define MAX_PTHREADS (1) /* max number concurrent pthreads */
#define DEFAULT_THREAD_TIMEOUT_SECS (60) /* default pthread exec timout */
#define MAX_LOG_PREFIX_LEN (MAX_CHARS_HOSTNAME*4)
#define MAX_LOG_PREFIX_LEN (MAX_CHARS_ON_LINE)
#define THREAD_POST_KILL_WAIT (10) /* wait time between KILL and IDLE */
typedef enum
@ -199,7 +199,7 @@ typedef struct
int timeout ; /* timout in msecs , 0 for no timeout */
/* FSM Level Completion Control and Status */
int status ; /* FSM status ; overrides info status */
unsigned int status ; /* FSM status ; overrides info status */
bool done ; /* flag indicating thread data was consumed */
int runcount ; /* copy of info.runcount before launch ; */
int retries ; /* max thread retries */
@ -228,7 +228,7 @@ typedef struct
string hostname ; /* hostname this thread is tied to */
string name ; /* short name of the thread */
int command ; /* the command the thread should execute */
int command ; /* the command the thread should execute */
int signal ; /* parent request signal ; SIGKILL exit request */
void * extra_info_ptr ; /* pointer to thread specific command data */
char log_prefix[MAX_LOG_PREFIX_LEN]; /* preformatted log prefix */
@ -238,7 +238,7 @@ typedef struct
/* -------------------------------------------------------------------- */
pthread_t id ; /* the thread id of self */
int status ; /* thread execution status set before runcount++ */
int unsigned status ; /* thread execution status set before runcount++ */
string status_string ; /* status string representing unique error case */
int runcount ; /* thread increments just before exit - complete */
int progress ; /* incremented by thread ; show forward progress */
@ -247,6 +247,8 @@ typedef struct
int pw_file_fd ; /* file descriptor for the password file */
string password_file ; /* the name of the password file */
bmc_protocol_enum proto ; /* IPMITOOL, REDFISHTOOL, future ... */
} thread_info_type ;
/****************************************************************************/

View File

@ -66,6 +66,7 @@ Requires: libpthread.so.0()(64bit)
Requires: /usr/bin/expect
Requires: python-rtslib
Requires: /usr/bin/ipmitool
Requires: /usr/bin/redfishtool
%description
Titanium Cloud Host Maintenance services. A suite of daemons that provide
@ -167,7 +168,7 @@ Requires: libgcc_s.so.1()(64bit)
Requires: libstdc++.so.6(GLIBCXX_3.4)(64bit)
Requires: libstdc++.so.6(GLIBCXX_3.4.15)(64bit)
Requires: libpthread.so.0()(64bit)
Requires: /usr/bin/ipmitool
Requires: /usr/bin/redfishtool
%description -n mtce-hwmon
Titanium Cloud Host Maintenance Hardware Monitor Service (hwmond) adds

View File

@ -631,12 +631,13 @@ nodeLinkClass::node* nodeLinkClass::addNode( string hostname )
ptr->mnfa_graceful_recovery = false ;
/* initialize all board management variables for this host */
ptr->bmc_protocol = BMC_PROTOCOL__IPMITOOL ;
ptr->bm_ip = NONE ;
ptr->bm_type = NONE ;
ptr->bm_un = NONE ;
ptr->bm_pw = NONE ;
ptr->bm_provisioned = false ; /* assume not provisioned until learned */
ptr->bmc_provisioned = false ; /* assume not provisioned until learned */
ptr->power_on = false ; /* learned on first BMC connection */
bmc_access_data_init ( ptr ); /* init all the BMC access vars all modes */
@ -1889,7 +1890,7 @@ int nodeLinkClass::del_host ( const string uuid )
if ( nodeLinkClass::maintenance == true )
{
if ( node_ptr->bm_provisioned == true )
if ( node_ptr->bmc_provisioned == true )
{
set_bm_prov ( node_ptr, false);
}
@ -2182,7 +2183,7 @@ int nodeLinkClass::mod_host ( node_inv_type & inv )
* - its in progress,
* - there is a BMC provisioned and
* - are waiting while the actual install is in progress */
if (( node_ptr->bm_provisioned == true ) &&
if (( node_ptr->bmc_provisioned == true ) &&
( node_ptr->reinstallStage == MTC_REINSTALL__ONLINE_WAIT))
{
reinstallStageChange ( node_ptr , MTC_REINSTALL__START );
@ -2742,13 +2743,13 @@ int nodeLinkClass::add_host ( node_inv_type & inv )
node_ptr->bm_ping_info.sock = 0 ;
/* initialize the host power and reset control thread */
thread_init ( node_ptr->ipmitool_thread_ctrl,
node_ptr->ipmitool_thread_info,
thread_init ( node_ptr->bmc_thread_ctrl,
node_ptr->bmc_thread_info,
&node_ptr->thread_extra_info,
mtcThread_ipmitool,
mtcThread_bmc,
DEFAULT_THREAD_TIMEOUT_SECS,
node_ptr->hostname,
THREAD_NAME__IPMITOOL);
THREAD_NAME__BMC);
if ( adminStateOk (inv.admin) &&
operStateOk (inv.oper ) &&
@ -3922,7 +3923,7 @@ int nodeLinkClass::manage_bmc_provisioning ( struct node * node_ptr )
{
int rc = PASS ;
bool was_provisioned = node_ptr->bm_provisioned ;
bool was_provisioned = node_ptr->bmc_provisioned ;
set_bm_prov ( node_ptr, false);
if ((hostUtil_is_valid_ip_addr ( node_ptr->bm_ip )) &&
@ -3949,7 +3950,7 @@ int nodeLinkClass::manage_bmc_provisioning ( struct node * node_ptr )
ilog ("%s sending board management info update to hwmond\n", node_ptr->hostname.c_str() );
if ( ( rc = send_hwmon_command(node_ptr->hostname,MTC_CMD_MOD_HOST) ) == PASS )
{
if ( node_ptr->bm_provisioned == true )
if ( node_ptr->bmc_provisioned == true )
{
rc = send_hwmon_command(node_ptr->hostname,MTC_CMD_START_HOST);
}
@ -4052,13 +4053,18 @@ void nodeLinkClass::bmc_access_data_init ( struct nodeLinkClass::node * node_ptr
{
if ( node_ptr )
{
node_ptr->bm_accessible = false;
node_ptr->mc_info_query_active = false ;
node_ptr->mc_info_query_done = false ;
node_ptr->reset_cause_query_active = false ;
node_ptr->reset_cause_query_done = false ;
node_ptr->power_status_query_active = false;
node_ptr->power_status_query_done = false ;
node_ptr->bmc_accessible = false ;
node_ptr->bm_ping_info.ok = false ;
node_ptr->bmc_info_query_active = false ;
node_ptr->bmc_info_query_done = false ;
node_ptr->reset_cause_query_active = false ;
node_ptr->reset_cause_query_done = false ;
node_ptr->power_status_query_active = false ;
node_ptr->power_status_query_done = false ;
node_ptr->bmc_protocol_learned = false ;
node_ptr->bmc_protocol_learning = false ;
node_ptr->bmc_protocol = BMC_PROTOCOL__IPMITOOL ;
bmcUtil_info_init ( node_ptr->bmc_info );
}
}
@ -4080,20 +4086,24 @@ int nodeLinkClass::set_bm_prov ( struct nodeLinkClass::node * node_ptr, bool sta
int rc = FAIL_HOSTNAME_LOOKUP ;
if ( node_ptr != NULL )
{
ilog ("%s bmc %sprovision request (provisioned:%s)\n", // ERIC blog
/* default the bmc info file */
string bmc_info_path_n_filename = BMC_OUTPUT_DIR + node_ptr->hostname ;
ilog ("%s bmc %sprovision request (provisioned:%s)\n",
node_ptr->hostname.c_str(),
state ? "" : "de",
node_ptr->bm_provisioned ? "Yes" : "No" );
node_ptr->bmc_provisioned ? "Yes" : "No" );
/* Clear the alarm if we are starting fresh from an unprovisioned state */
if (( node_ptr->bm_provisioned == false ) && ( state == true ))
if (( node_ptr->bmc_provisioned == false ) && ( state == true ))
{
/* BMC is managed by IPMI/IPMITOOL */
/* default the bmc info file */
daemon_log ( bmc_info_path_n_filename.data(), BMC_DEFAULT_INFO );
ilog ("%s starting BM ping monitor to address '%s'\n",
node_ptr->hostname.c_str(),
node_ptr->bm_ip.c_str());
// mtcTimer_reset ( node_ptr->bm_ping_info.timer );
node_ptr->bm_ping_info.ip = node_ptr->bm_ip ;
node_ptr->bm_ping_info.stage = PINGUTIL_MONITOR_STAGE__OPEN ;
bmc_access_data_init ( node_ptr );
@ -4114,39 +4124,7 @@ int nodeLinkClass::set_bm_prov ( struct nodeLinkClass::node * node_ptr, bool sta
send_hwmon_command(node_ptr->hostname, MTC_CMD_ADD_HOST);
send_hwmon_command(node_ptr->hostname, MTC_CMD_START_HOST);
}
/* handle the case going from provisioned to not provisioned */
else if (( node_ptr->bm_provisioned == true ) && ( state == false ))
{
/* BMC is managed by IPMI/IPMITOOL */
ilog ("%s deprovisioning bmc ; accessible:%s\n",
node_ptr->hostname.c_str(),
node_ptr->bm_accessible ? "Yes" : "No" );
pingUtil_fini ( node_ptr->bm_ping_info );
bmc_access_data_init ( node_ptr );
node_ptr->bm_accessible = false;
if ( !thread_idle( node_ptr->ipmitool_thread_ctrl ) )
{
thread_kill ( node_ptr->ipmitool_thread_ctrl , node_ptr->ipmitool_thread_info);
}
node_ptr->mc_info_query_active = false ;
node_ptr->mc_info_query_done = false ;
node_ptr->reset_cause_query_active = false ;
node_ptr->reset_cause_query_done = false ;
node_ptr->power_status_query_active = false;
node_ptr->power_status_query_done = false ;
/* send a delete to hwmon if the provisioning data is NONE */
if ( hostUtil_is_valid_bm_type ( node_ptr->bm_type ) == false )
{
send_hwmon_command(node_ptr->hostname, MTC_CMD_DEL_HOST);
}
}
if (( node_ptr->bm_provisioned == false ) && ( state == true ))
{
/* start the connection timer - if it expires before we
* are 'accessible' then the BM Alarm is raised.
* Timer is further managed in mtcNodeHdlrs.cpp */
@ -4155,7 +4133,32 @@ int nodeLinkClass::set_bm_prov ( struct nodeLinkClass::node * node_ptr, bool sta
mtcTimer_start ( node_ptr->bmc_access_timer, mtcTimer_handler, MTC_MINS_2 );
}
node_ptr->bm_provisioned = state ;
/* handle the case going from provisioned to not provisioned */
else if (( node_ptr->bmc_provisioned == true ) && ( state == false ))
{
/* remove the BMC info file */
daemon_remove_file ( bmc_info_path_n_filename.data() );
ilog ("%s deprovisioning bmc ; accessible:%s\n",
node_ptr->hostname.c_str(),
node_ptr->bmc_accessible ? "Yes" : "No" );
pingUtil_fini ( node_ptr->bm_ping_info );
bmc_access_data_init ( node_ptr );
if ( !thread_idle( node_ptr->bmc_thread_ctrl ) )
{
thread_kill ( node_ptr->bmc_thread_ctrl , node_ptr->bmc_thread_info);
}
/* send a delete to hwmon if the provisioning data is NONE */
if ( hostUtil_is_valid_bm_type ( node_ptr->bm_type ) == false )
{
send_hwmon_command(node_ptr->hostname, MTC_CMD_DEL_HOST);
}
}
node_ptr->bmc_provisioned = state ;
}
return (rc);
}
@ -4893,7 +4896,7 @@ int nodeLinkClass::declare_service_ready ( string & hostname,
plog ("%s %s ready event\n",
hostname.c_str(),
MTC_SERVICE_HWMOND_NAME);
if ( node_ptr->bm_provisioned == true )
if ( node_ptr->bmc_provisioned == true )
{
send_hwmon_command ( node_ptr->hostname, MTC_CMD_ADD_HOST );
send_hwmon_command ( node_ptr->hostname, MTC_CMD_START_HOST );
@ -5129,7 +5132,7 @@ int nodeLinkClass::invoke_hwmon_action ( string & hostname, int action, string
if ( node_ptr )
{
if ( node_ptr->bm_accessible == false )
if ( node_ptr->bmc_accessible == false )
{
wlog ("%s rejecting %s hwmon action request for '%s' sensor ; BMC not accessible\n",
hostname.c_str(),
@ -6109,9 +6112,9 @@ int nodeLinkClass::adminActionChange ( struct nodeLinkClass::node * node_ptr,
(( newActionState != MTC_ADMIN_ACTION__POWERCYCLE ) &&
( newActionState != MTC_ADMIN_ACTION__POWEROFF )))
{
blog ("%s (mon:%d:prov:%d)\n", node_ptr->hostname.c_str(), node_ptr->hwmond_monitor, node_ptr->bm_provisioned );
blog ("%s (mon:%d:prov:%d)\n", node_ptr->hostname.c_str(), node_ptr->hwmond_monitor, node_ptr->bmc_provisioned );
if (( node_ptr->hwmond_monitor == false ) && ( node_ptr->bm_provisioned == true ))
if (( node_ptr->hwmond_monitor == false ) && ( node_ptr->bmc_provisioned == true ))
{
send_hwmon_command ( node_ptr->hostname, MTC_CMD_ADD_HOST );
send_hwmon_command ( node_ptr->hostname, MTC_CMD_START_HOST );
@ -6814,7 +6817,7 @@ struct nodeLinkClass::node * nodeLinkClass::get_thread_timer ( timer_t tid )
{
for ( struct node * ptr = head ; ; ptr = ptr->next )
{
if ( ptr->ipmitool_thread_ctrl.timer.tid == tid )
if ( ptr->bmc_thread_ctrl.timer.tid == tid )
{
return ptr ;
}
@ -8608,15 +8611,34 @@ void nodeLinkClass::mem_log_general_mtce_hosts ( void )
void nodeLinkClass::mem_log_bm ( struct nodeLinkClass::node * node_ptr )
{
char str[MAX_MEM_LOG_DATA] ;
snprintf (&str[0], MAX_MEM_LOG_DATA, "%s\tbm_ip:%s bm_un:%s bm_type:%s provisioned: %s\n",
snprintf (&str[0], MAX_MEM_LOG_DATA, "%s\tBMC %s %s:%s prov:%s learn:%s:%s\n",
node_ptr->hostname.c_str(),
node_ptr->bm_ip.c_str(),
bmcUtil_getProtocol_str(node_ptr->bmc_protocol).c_str(),
node_ptr->bm_un.c_str(),
node_ptr->bm_type.c_str(),
node_ptr->bm_provisioned ? "Yes" : "No" );
node_ptr->bm_ip.c_str(),
node_ptr->bmc_provisioned ? "Yes" : "No",
node_ptr->bmc_protocol_learned ? "Yes" : "No",
node_ptr->bmc_protocol_learning ? "Yes" : "No");
mem_log (str);
}
void nodeLinkClass::mem_log_ping ( struct nodeLinkClass::node * node_ptr )
{
if ( node_ptr->bmc_provisioned )
{
char str[MAX_MEM_LOG_DATA] ;
snprintf (&str[0], MAX_MEM_LOG_DATA, "%s\tPing stage:%d ok:%s mon:%s %s tid:%p\n",
node_ptr->bm_ping_info.hostname.c_str(),
node_ptr->bm_ping_info.stage,
node_ptr->bm_ping_info.ok ? "Yes" : "No",
node_ptr->bm_ping_info.monitoring ? "Yes" : "No",
node_ptr->bm_ping_info.ip.c_str(),
node_ptr->bm_ping_info.timer.tid);
mem_log (str);
}
}
void nodeLinkClass::mem_log_identity ( struct nodeLinkClass::node * node_ptr )
{
char str[MAX_MEM_LOG_DATA] ;
@ -8642,10 +8664,10 @@ void nodeLinkClass::mem_log_state1 ( struct nodeLinkClass::node * node_ptr )
av.c_str(),
node_ptr->degrade_mask);
mem_log (str);
op = operState_enum_to_str(node_ptr->operState_subf) ;
av = availStatus_enum_to_str(node_ptr->availStatus_subf);
if ( ! node_ptr->subfunction_str.empty() )
{
op = operState_enum_to_str(node_ptr->operState_subf) ;
av = availStatus_enum_to_str(node_ptr->availStatus_subf);
snprintf (&str[0], MAX_MEM_LOG_DATA, "%s\tSub-Functions: %s-%s %s-%s-%s\n",
node_ptr->hostname.c_str(),
node_ptr->function_str.c_str(),
@ -8653,8 +8675,8 @@ void nodeLinkClass::mem_log_state1 ( struct nodeLinkClass::node * node_ptr )
ad.c_str(),
op.c_str(),
av.c_str());
mem_log (str);
}
mem_log (str);
}
void nodeLinkClass::mem_log_state2 ( struct nodeLinkClass::node * node_ptr )
@ -8806,11 +8828,11 @@ void nodeLinkClass::mem_log_thread_info ( struct nodeLinkClass::node * node_ptr
char str[MAX_MEM_LOG_DATA] ;
snprintf (&str[0], MAX_MEM_LOG_DATA, "%s\tThread Stage:%d Runs:%d Progress:%d Ctrl Status:%d Thread Status:%d\n",
node_ptr->hostname.c_str(),
node_ptr->ipmitool_thread_ctrl.stage,
node_ptr->ipmitool_thread_ctrl.runcount,
node_ptr->ipmitool_thread_info.progress,
node_ptr->ipmitool_thread_ctrl.status,
node_ptr->ipmitool_thread_info.status);
node_ptr->bmc_thread_ctrl.stage,
node_ptr->bmc_thread_ctrl.runcount,
node_ptr->bmc_thread_info.progress,
node_ptr->bmc_thread_ctrl.status,
node_ptr->bmc_thread_info.status);
mem_log (str);
}
@ -8868,6 +8890,7 @@ void nodeLinkClass::memDumpNodeState ( string hostname )
mem_log_mtcalive ( node_ptr );
mem_log_stage ( node_ptr );
mem_log_bm ( node_ptr );
mem_log_ping ( node_ptr );
mem_log_test_info ( node_ptr );
mem_log_thread_info( node_ptr );
workQueue_dump ( node_ptr );

View File

@ -33,12 +33,12 @@ using namespace std;
#include "pingUtil.h" /* for ... ping_info_type */
#include "nodeCmds.h" /* for ... mtcCmd type */
#include "httpUtil.h" /* for ... libevent stuff */
#include "ipmiUtil.h" /* for ... mc_info_type */
#include "bmcUtil.h" /* for ... mtce-common board management */
#include "mtcHttpUtil.h" /* for ... libevent stuff */
#include "mtcSmgrApi.h" /* for ... mtcSmgrApi_request/handler */
#include "alarmUtil.h" /* for ... SFmAlarmDataT */
#include "mtcAlarm.h" /* for ... MTC_ALARM_ID__xx and utils */
#include "mtcThreads.h" /* for ... mtcThread_ipmitool */
#include "mtcThreads.h" /* for ... mtcThread_bmc */
/**Default back-to-back heartbeat failures for disabled-failed condition */
#define HBS_FAILURE_THRESHOLD 10
@ -146,7 +146,7 @@ private:
bool subf_enabled ;
/** set true if the BMC is provisioned */
bool bm_provisioned ;
bool bmc_provisioned ;
/** general retry counter */
@ -594,7 +594,7 @@ private:
* The BMC is 'accessible' once provisioning data is available
* and bmc is verified pingable.
**/
bool bm_accessible;
bool bmc_accessible;
/** @} private_boad_management_variables */
@ -650,15 +650,29 @@ private:
int stress_iteration ;
/* BMC Protocol Learning Controls and State */
/* specifies what BMC protocol is selected for this host
*
* defaults to 0 or BMC_PROTOCOL__IPMITOOL */
bmc_protocol_enum bmc_protocol ;
/* set true once the best BMC protocol has been learned
*
* looked at in the bmc_handler to decide learn or use bmc_protocol */
bool bmc_protocol_learned ;
/* set true while bmc protocol learning is in progress */
bool bmc_protocol_learning ;
/* for bmc ping access monitor */
ping_info_type bm_ping_info ;
/* the bmc info struct filled in and log printed by a
* call to ipmiUtil_mc_info_load. */
mc_info_type mc_info ;
/* the bmc info struct */
bmc_info_type bmc_info ;
bool mc_info_query_active ;
bool mc_info_query_done ;
bool bmc_info_query_active ;
bool bmc_info_query_done ;
bool reset_cause_query_active ;
bool reset_cause_query_done ;
@ -667,8 +681,8 @@ private:
bool power_status_query_done ;
bool power_on = false ;
/* a timer used in the bm_handler to query
* the mc_info and reset cause */
/* a timer used in the bmc_handler to query
* the bmc_info and reset cause */
struct mtc_timer bm_timer ;
/* timer used to manage the bmc access alarm */
@ -678,10 +692,10 @@ private:
* Maintenance Thread Structs
*****************************************************/
/* control data the parent uses to manage the thread */
thread_ctrl_type ipmitool_thread_ctrl ;
thread_ctrl_type bmc_thread_ctrl ;
/*info the thread uses to execute and post results */
thread_info_type ipmitool_thread_info ;
thread_info_type bmc_thread_info ;
/* extra thread info for board management control thread */
thread_extra_info_type thread_extra_info ;
@ -799,7 +813,7 @@ private:
int oos_test_handler ( struct nodeLinkClass::node * node_ptr );
int insv_test_handler ( struct nodeLinkClass::node * node_ptr );
int stress_handler ( struct nodeLinkClass::node * node_ptr );
int bm_handler ( struct nodeLinkClass::node * node_ptr );
int bmc_handler ( struct nodeLinkClass::node * node_ptr );
int degrade_handler ( struct nodeLinkClass::node * node_ptr );
int uptime_handler ( void );
@ -824,9 +838,9 @@ private:
/*****************************************************************************
*
* Name : ipmi_command_send
* Name : bmc_command_send
*
* Description: This utility starts the ipmitool command handling thread
* Description: This utility starts the bmc command handling thread
* with the specified command.
*
* Returns : PASS if all the pre-start semantic checks pass and the
@ -838,34 +852,34 @@ private:
*
*****************************************************************************/
int ipmi_command_send ( struct nodeLinkClass::node * node_ptr, int command ) ;
int bmc_command_send ( struct nodeLinkClass::node * node_ptr, int command ) ;
/*****************************************************************************
*
* Name : ipmi_command_recv
* Name : bmc_command_recv
*
* Description: This utility will check for ipmitool command thread completion.
* Description: This utility will check for bmc command thread completion.
*
* Returns : PASS is returned if the thread reports done.
* RETRY is returned if the thread has not completed.
* FAIL_RETRY is returned after 10 back-to-back calls return RETRY.
*
* Assumptions: The caller is expected to call ipmi_command_done once it has
* Assumptions: The caller is expected to call bmc_command_done once it has
* consumed the results of the thread
*
*****************************************************************************/
int ipmi_command_recv ( struct nodeLinkClass::node * node_ptr );
int bmc_command_recv ( struct nodeLinkClass::node * node_ptr );
/*****************************************************************************
*
* Name : ipmi_command_done
* Name : bmc_command_done
*
* Description: This utility frees the ipmitool command thread for next execution.
*
*****************************************************************************/
void ipmi_command_done ( struct nodeLinkClass::node * node_ptr );
void bmc_command_done ( struct nodeLinkClass::node * node_ptr );
/* default all the BMC access variaables to the "no access" state */
void bmc_access_data_init ( struct nodeLinkClass::node * node_ptr );
@ -1257,6 +1271,7 @@ private:
void mem_log_stage ( struct nodeLinkClass::node * node_ptr );
void mem_log_test_info ( struct nodeLinkClass::node * node_ptr );
void mem_log_bm ( struct nodeLinkClass::node * node_ptr );
void mem_log_ping ( struct nodeLinkClass::node * node_ptr );
void mem_log_heartbeat ( struct nodeLinkClass::node * node_ptr );
void mem_log_hbs_cnts ( struct nodeLinkClass::node * node_ptr );
void mem_log_type_info ( struct nodeLinkClass::node * node_ptr );

View File

@ -327,22 +327,33 @@ int tokenUtil_parse_uri (const string uri, daemon_config_type* config_ptr)
return(PASS);
}
void * mtcThread_ipmitool ( void * arg ) { UNUSED(arg); return NULL ; }
void * mtcThread_bmc ( void * arg ) { UNUSED(arg); return NULL ; }
int nodeLinkClass::ipmi_command_send ( struct nodeLinkClass::node * node_ptr, int command )
string bmcUtil_getProtocol_str ( bmc_protocol_enum protocol )
{
UNUSED(protocol);
return("unknown");
}
void bmcUtil_info_init ( bmc_info_type & bmc_info )
{
UNUSED(bmc_info);
}
int nodeLinkClass::bmc_command_send ( struct nodeLinkClass::node * node_ptr, int command )
{
UNUSED(node_ptr);
UNUSED(command);
return(PASS);
}
int nodeLinkClass::ipmi_command_recv ( struct nodeLinkClass::node * node_ptr )
int nodeLinkClass::bmc_command_recv ( struct nodeLinkClass::node * node_ptr )
{
UNUSED(node_ptr);
return(PASS);
}
void nodeLinkClass::ipmi_command_done ( struct nodeLinkClass::node * node_ptr )
void nodeLinkClass::bmc_command_done ( struct nodeLinkClass::node * node_ptr )
{
UNUSED(node_ptr);
}

View File

@ -23,7 +23,7 @@ SRCS += hwmonFsm.cpp
OBJS = $(SRCS:.cpp=.o)
BIN = hwmond
LDLIBS = -lstdc++ -ldaemon -lfmcommon -lcommon -lthreadUtil -lipmiUtil -lpthread -levent -ljson-c -lrt -lcrypto
LDLIBS = -lstdc++ -ldaemon -lfmcommon -lcommon -lthreadUtil -lbmcUtils -lpthread -levent -ljson-c -lrt -lcrypto
INCLUDES = -I. -I/usr/include/mtce-daemon -I/usr/include/mtce-common
INCLUDES += -I../maintenance
CCFLAGS = -g -O2 -Wall -Wextra -Werror -std=c++11 -pthread

View File

@ -311,7 +311,7 @@ typedef struct
string unit_base ; /**< Celcius, Revolutions */
string unit_rate ; /**< Minute */
protocol_enum prot ; /**< protocol to use for this sensor */
bmc_protocol_enum prot ; /**< protocol to use for this sensor */
sensor_kind_enum kind ; /**< the kind of sensor ; see definition */
sensor_unit_enum unit ; /**< the units the sensor should be displayed in */

View File

@ -192,7 +192,7 @@ void hwmonHostClass::free_host_timers ( struct hwmon_host * ptr )
mtcTimer_fini ( ptr->ping_info.timer );
mtcTimer_fini ( ptr->monitor_ctrl.timer );
mtcTimer_fini ( ptr->ipmitool_thread_ctrl.timer );
mtcTimer_fini ( ptr->bmc_thread_ctrl.timer );
}
/* Remove a hist from the linked list of hosts - may require splice action */
@ -732,13 +732,13 @@ int hwmonHostClass::add_host ( node_inv_type & inv )
host_ptr->thread_extra_info.sensor_query_request = IPMITOOL_PATH_AND_FILENAME ;
/* Sensor Monitoring Thread Initialization */
thread_init ( host_ptr->ipmitool_thread_ctrl,
host_ptr->ipmitool_thread_info,
thread_init ( host_ptr->bmc_thread_ctrl,
host_ptr->bmc_thread_info,
&host_ptr->thread_extra_info,
hwmonThread_ipmitool,
DEFAULT_THREAD_TIMEOUT_SECS,
host_ptr->hostname,
THREAD_NAME__IPMITOOL);
THREAD_NAME__BMC);
/* TODO: create a is_bm_info_valid */
if ( ( hostUtil_is_valid_ip_addr (host_ptr->bm_ip) == true ) &&
@ -1022,7 +1022,7 @@ struct hwmonHostClass::hwmon_host * hwmonHostClass::getHost_timer ( timer_t tid
{
for ( struct hwmon_host * host_ptr = hwmon_head ; ; host_ptr = host_ptr->next )
{
if ( host_ptr->ipmitool_thread_ctrl.timer.tid == tid )
if ( host_ptr->bmc_thread_ctrl.timer.tid == tid )
{
return host_ptr ;
}
@ -2187,7 +2187,7 @@ void hwmonHostClass::log_sensor_data ( struct hwmonHostClass::hwmon_host * host_
source.append (to );
source.append ("'\n");
daemon_log ( debugfile.data(), source.data());
daemon_log ( debugfile.data(), host_ptr->ipmitool_thread_info.data.data());
daemon_log ( debugfile.data(), host_ptr->bmc_thread_info.data.data());
daemon_log ( debugfile.data(), daemon_read_file ( sensor_datafile.data()).data());
daemon_log ( debugfile.data(), "---------------------------------------------------------------------\n");
}
@ -2244,11 +2244,11 @@ void hwmonHostClass::mem_log_threads ( struct hwmonHostClass::hwmon_host * hwmo
char str[MAX_MEM_LOG_DATA] ;
snprintf (&str[0], MAX_MEM_LOG_DATA, "%s\tThread Stage:%d Runs:%d Progress:%d Ctrl Status:%d Thread Status:%d\n",
hwmon_host_ptr->hostname.c_str(),
hwmon_host_ptr->ipmitool_thread_ctrl.stage,
hwmon_host_ptr->ipmitool_thread_ctrl.runcount,
hwmon_host_ptr->ipmitool_thread_info.progress,
hwmon_host_ptr->ipmitool_thread_ctrl.status,
hwmon_host_ptr->ipmitool_thread_info.status);
hwmon_host_ptr->bmc_thread_ctrl.stage,
hwmon_host_ptr->bmc_thread_ctrl.runcount,
hwmon_host_ptr->bmc_thread_info.progress,
hwmon_host_ptr->bmc_thread_ctrl.status,
hwmon_host_ptr->bmc_thread_info.status);
mem_log (str);
}

View File

@ -17,6 +17,8 @@
#include "hostClass.h"
#include "hwmonThreads.h"
#include "hwmonSensor.h"
#include "bmcUtil.h" /* for ... board mgmnt utility header */
//#include "hwmonIpmi.h" /* for ... sensor_data_type */
typedef enum
@ -91,7 +93,7 @@ class hwmonHostClass
int degrade_audit_log_throttle ;
/** set to the protocol used to communicate with this server's BMC */
protocol_enum protocol ;
bmc_protocol_enum protocol ;
/** Pointer to the previous host in the list */
struct hwmon_host * prev;
@ -125,8 +127,8 @@ class hwmonHostClass
/* the info required by the sensor read thread to issue a ipmitool
* lanplus request to read sensors over the network */
thread_ctrl_type ipmitool_thread_ctrl ; /* control data used to manage the thread */
thread_info_type ipmitool_thread_info ; /* thread info used to execute and post results */
thread_ctrl_type bmc_thread_ctrl ; /* control data used to manage the thread */
thread_info_type bmc_thread_info ; /* thread info used to execute and post results */
thread_extra_info_type thread_extra_info ; /* extra thread info for sensor monitoring */
/* Ipmi sensor monitoring control structure */

View File

@ -65,7 +65,7 @@ void hwmonHostClass::hwmon_fsm ( void )
if ( host_ptr->host_delete == true )
{
/* need to service the thread handler during the delete operation */
thread_handler ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info );
thread_handler ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info );
delete_handler ( host_ptr );
if ( this->host_deleted == true )
@ -92,7 +92,7 @@ void hwmonHostClass::hwmon_fsm ( void )
* The ipmitool thread needs to run to learn the sensors
* to begin with as well as continually monitor them
*/
thread_handler ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info );
thread_handler ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info );
pingUtil_acc_monitor ( host_ptr->ping_info );
@ -102,15 +102,15 @@ void hwmonHostClass::hwmon_fsm ( void )
{
/* ... make sure the thread sits in the
* idle state while disabled */
if ( thread_idle ( host_ptr->ipmitool_thread_ctrl ) == false )
if ( thread_idle ( host_ptr->bmc_thread_ctrl ) == false )
{
if ( thread_done ( host_ptr->ipmitool_thread_ctrl ) == true )
if ( thread_done ( host_ptr->bmc_thread_ctrl ) == true )
{
host_ptr->ipmitool_thread_ctrl.done = true ;
host_ptr->bmc_thread_ctrl.done = true ;
}
else
{
thread_kill ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info );
thread_kill ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info );
}
}
continue ;
@ -124,7 +124,7 @@ void hwmonHostClass::hwmon_fsm ( void )
else if (( host_ptr->accessible == true ) && ( host_ptr->ping_info.ok == false ))
{
wlog ("%s bmc access lost\n", host_ptr->hostname.c_str());
thread_kill ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info );
thread_kill ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info );
host_ptr->accessible = host_ptr->connected = false ;
host_ptr->sensor_query_count = 0 ;
host_ptr->bmc_fw_version.clear();
@ -174,9 +174,9 @@ void hwmonHostClass::hwmon_fsm ( void )
/* typical success path */
hwmonHostClass::ipmi_sensor_monitor ( host_ptr );
}
else if ( !thread_idle( host_ptr->ipmitool_thread_ctrl ) )
else if ( !thread_idle( host_ptr->bmc_thread_ctrl ) )
{
thread_kill ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info );
thread_kill ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info );
}
}
if ( host_ptr->want_degrade_audit )

View File

@ -17,14 +17,14 @@
#include "regexUtil.h" /* for ... regexUtil_pattern_match */
#include "tokenUtil.h" /* for ... tokenUtil_new_token */
#include "nodeUtil.h" /* for ... mtce common utilities */
#include "ipmiUtil.h" /* for ... IPMI utilties */
#include "bmcUtil.h" /* for ... mtce-common board management */
#include "hwmon.h" /* for ... service module header */
#include "hwmonUtil.h" /* for ... utilities, ie clear_logged_state */
#include "hwmonClass.h" /* for ... service class definition */
#include "hwmonIpmi.h" /* for ... QUANTA_SENSOR_PROFILE_CHECKSUM */
#include "hwmonSensor.h" /* for ... this mpodule header */
#include "hwmonHttp.h" /* for ... hwmonHttp_mod_group */
#include "hwmonAlarm.h" /* for ... hwmonAlarm_major */
#include "hwmonIpmi.h" /* for ... QUANTA_SAMPLE_PROFILE_.. */
/* Declare the Hardware Monitor Inventory Object */
hwmonHostClass hostInv ;
@ -205,10 +205,10 @@ void hwmonHostClass::timer_handler ( int sig, siginfo_t *si, void *uc)
hwmon_host_ptr->monitor_ctrl.timer.ring = true ;
return ;
}
else if (( *tid_ptr == hwmon_host_ptr->ipmitool_thread_ctrl.timer.tid ) )
else if (( *tid_ptr == hwmon_host_ptr->bmc_thread_ctrl.timer.tid ) )
{
mtcTimer_stop_int_safe ( hwmon_host_ptr->ipmitool_thread_ctrl.timer );
hwmon_host_ptr->ipmitool_thread_ctrl.timer.ring = true ;
mtcTimer_stop_int_safe ( hwmon_host_ptr->bmc_thread_ctrl.timer );
hwmon_host_ptr->bmc_thread_ctrl.timer.ring = true ;
return ;
}
else if (( *tid_ptr == hwmon_host_ptr->ping_info.timer.tid ) )
@ -777,37 +777,37 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
( host_ptr->poweron == false ) &&
( host_ptr->relearn == false ))
{
if ( host_ptr->ipmitool_thread_ctrl.id )
if ( host_ptr->bmc_thread_ctrl.id )
{
wlog ("%s sensor monitor thread is unexpectedly active ; retry soon\n", host_ptr->hostname.c_str());
thread_kill ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info );
thread_kill ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info );
sleep (1);
break ;
}
host_ptr->accounting_bad_count = 0 ;
host_ptr->ipmitool_thread_ctrl.id = 0 ;
host_ptr->ipmitool_thread_ctrl.done = false ;
host_ptr->bmc_thread_ctrl.id = 0 ;
host_ptr->bmc_thread_ctrl.done = false ;
host_ptr->ipmitool_thread_info.data.clear() ;
host_ptr->ipmitool_thread_info.status_string.clear();
host_ptr->ipmitool_thread_info.status = -1 ;
host_ptr->ipmitool_thread_info.progress = 0 ;
host_ptr->ipmitool_thread_info.id = 0 ;
host_ptr->ipmitool_thread_info.signal = 0 ;
host_ptr->ipmitool_thread_info.command = IPMITOOL_THREAD_CMD__POWER_STATUS ;
host_ptr->bmc_thread_info.data.clear() ;
host_ptr->bmc_thread_info.status_string.clear();
host_ptr->bmc_thread_info.status = -1 ;
host_ptr->bmc_thread_info.progress = 0 ;
host_ptr->bmc_thread_info.id = 0 ;
host_ptr->bmc_thread_info.signal = 0 ;
host_ptr->bmc_thread_info.command = BMC_THREAD_CMD__POWER_STATUS ;
/* Update / Setup the BMC query credentials */
host_ptr->thread_extra_info.bm_ip = host_ptr->bm_ip ;
host_ptr->thread_extra_info.bm_un = host_ptr->bm_un ;
host_ptr->thread_extra_info.bm_pw = host_ptr->bm_pw ;
rc = thread_launch ( host_ptr->ipmitool_thread_ctrl,
host_ptr->ipmitool_thread_info ) ;
rc = thread_launch ( host_ptr->bmc_thread_ctrl,
host_ptr->bmc_thread_info ) ;
if ( rc != PASS )
{
host_ptr->ipmitool_thread_info.status = rc ;
host_ptr->ipmitool_thread_info.status_string =
host_ptr->bmc_thread_info.status = rc ;
host_ptr->bmc_thread_info.status_string =
"failed to launch power query thread" ;
_stage_change ( host_ptr->hostname,
@ -817,7 +817,7 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
else
{
/* Assign the extra data pointer */
host_ptr->ipmitool_thread_info.extra_info_ptr = (void*)&host_ptr->thread_extra_info ;
host_ptr->bmc_thread_info.extra_info_ptr = (void*)&host_ptr->thread_extra_info ;
/* start an umbrella timer 5 seconds longer than
* the default thread FSM timout */
@ -834,7 +834,7 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
else if ( host_ptr->interval )
{
/* Assign the extra data pointer */
host_ptr->ipmitool_thread_info.extra_info_ptr = (void*)&host_ptr->thread_extra_info ;
host_ptr->bmc_thread_info.extra_info_ptr = (void*)&host_ptr->thread_extra_info ;
/* randomize the first audit a little so that over a swact we don't spike hwmond */
int r = (rand() % host_ptr->interval) + 1 ;
@ -891,62 +891,62 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
wlog ("%s power query thread timeout\n",
host_ptr->hostname.c_str());
thread_kill ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info );
thread_kill ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info );
}
/* check for 'thread done' completion */
else if ( thread_done( host_ptr->ipmitool_thread_ctrl ) )
else if ( thread_done( host_ptr->bmc_thread_ctrl ) )
{
/* Consume done results */
mtcTimer_reset ( host_ptr->monitor_ctrl.timer );
if ( host_ptr->ipmitool_thread_info.status )
if ( host_ptr->bmc_thread_info.status )
{
elog ("%s %s thread %2d failed (rc:%d) (%d:%d)\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_ctrl.name.c_str(),
host_ptr->ipmitool_thread_info.command,
host_ptr->ipmitool_thread_info.status,
host_ptr->ipmitool_thread_info.progress,
host_ptr->ipmitool_thread_info.runcount);
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_ctrl.name.c_str(),
host_ptr->bmc_thread_info.command,
host_ptr->bmc_thread_info.status,
host_ptr->bmc_thread_info.progress,
host_ptr->bmc_thread_info.runcount);
wlog ("%s ... %s\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_info.status_string.c_str());
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_info.status_string.c_str());
}
else
{
dlog ("%s '%s' thread '%d' command is done ; (%d:%d) (rc:%d)\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_ctrl.name.c_str(),
host_ptr->ipmitool_thread_info.command,
host_ptr->ipmitool_thread_info.progress,
host_ptr->ipmitool_thread_info.runcount,
host_ptr->ipmitool_thread_info.status);
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_ctrl.name.c_str(),
host_ptr->bmc_thread_info.command,
host_ptr->bmc_thread_info.progress,
host_ptr->bmc_thread_info.runcount,
host_ptr->bmc_thread_info.status);
blog2("%s ... status: %s\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_info.status_string.c_str());
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_info.status_string.c_str());
#ifdef WANT_FIT_TESTING
if ( daemon_want_fit ( FIT_CODE__HWMON__NO_DATA, host_ptr->hostname ))
{
host_ptr->ipmitool_thread_info.data.clear ();
host_ptr->ipmitool_thread_info.status = 0 ;
host_ptr->ipmitool_thread_info.status_string.clear ();
host_ptr->bmc_thread_info.data.clear ();
host_ptr->bmc_thread_info.status = 0 ;
host_ptr->bmc_thread_info.status_string.clear ();
slog ("%s FIT No Power Status Data\n", host_ptr->hostname.c_str());
}
#endif
if ( host_ptr->ipmitool_thread_info.data.empty())
if ( host_ptr->bmc_thread_info.data.empty())
{
wlog ("%s power query status empty ; retrying query\n",
host_ptr->hostname.c_str());
}
else if ( host_ptr->ipmitool_thread_info.data.find (IPMITOOL_POWER_ON_STATUS) == string::npos )
else if ( host_ptr->bmc_thread_info.data.find (IPMITOOL_POWER_ON_STATUS) == string::npos )
{
ilog ("%s %s\n", host_ptr->hostname.c_str(),
host_ptr->ipmitool_thread_info.data.c_str());
host_ptr->bmc_thread_info.data.c_str());
wlog ("%s sensor learning delayed ; need power on\n",
host_ptr->hostname.c_str());
@ -954,14 +954,14 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
else
{
ilog ("%s %s\n", host_ptr->hostname.c_str(),
host_ptr->ipmitool_thread_info.data.c_str());
host_ptr->bmc_thread_info.data.c_str());
/* OK, this is what we have been waiting for */
host_ptr->poweron = true ;
}
}
host_ptr->ipmitool_thread_ctrl.done = true ;
host_ptr->bmc_thread_ctrl.done = true ;
if ( host_ptr->poweron == false )
{
@ -1007,11 +1007,11 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
/* if there was a previous connection failure being handled
* then give it time to resolve */
if ( !thread_idle ( host_ptr->ipmitool_thread_ctrl ) )
if ( !thread_idle ( host_ptr->bmc_thread_ctrl ) )
{
wlog ("%s rejecting thread run stage change ; FSM not IDLE (thread stage:%s)\n",
host_ptr->hostname.c_str(),
thread_stage(host_ptr->ipmitool_thread_ctrl).c_str());
thread_stage(host_ptr->bmc_thread_ctrl).c_str());
_stage_change ( host_ptr->hostname,
host_ptr->monitor_ctrl.stage,
@ -1061,10 +1061,10 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
******************************************************************/
case HWMON_SENSOR_MONITOR__READ:
{
if ( host_ptr->ipmitool_thread_ctrl.id )
if ( host_ptr->bmc_thread_ctrl.id )
{
host_ptr->ipmitool_thread_info.status = FAIL_THREAD_RUNNING ;
host_ptr->ipmitool_thread_info.status_string =
host_ptr->bmc_thread_info.status = FAIL_THREAD_RUNNING ;
host_ptr->bmc_thread_info.status_string =
"sensor monitor thread is unexpectedly active ; handling as failure" ;
_stage_change ( host_ptr->hostname,
host_ptr->monitor_ctrl.stage,
@ -1073,16 +1073,16 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
}
host_ptr->accounting_bad_count = 0 ;
host_ptr->ipmitool_thread_ctrl.id = 0 ;
host_ptr->ipmitool_thread_ctrl.done = false ;
host_ptr->bmc_thread_ctrl.id = 0 ;
host_ptr->bmc_thread_ctrl.done = false ;
host_ptr->ipmitool_thread_info.data.clear() ;
host_ptr->ipmitool_thread_info.status_string.clear();
host_ptr->ipmitool_thread_info.status = -1 ;
host_ptr->ipmitool_thread_info.progress = 0 ;
host_ptr->ipmitool_thread_info.id = 0 ;
host_ptr->ipmitool_thread_info.signal = 0 ;
host_ptr->ipmitool_thread_info.command = IPMITOOL_THREAD_CMD__READ_SENSORS ;
host_ptr->bmc_thread_info.data.clear() ;
host_ptr->bmc_thread_info.status_string.clear();
host_ptr->bmc_thread_info.status = -1 ;
host_ptr->bmc_thread_info.progress = 0 ;
host_ptr->bmc_thread_info.id = 0 ;
host_ptr->bmc_thread_info.signal = 0 ;
host_ptr->bmc_thread_info.command = BMC_THREAD_CMD__READ_SENSORS ;
/* Update / Setup the BMC query credentials */
host_ptr->thread_extra_info.bm_ip = host_ptr->bm_ip ;
@ -1090,11 +1090,11 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
host_ptr->thread_extra_info.bm_pw = host_ptr->bm_pw ;
rc = thread_launch ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info ) ;
rc = thread_launch ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info ) ;
if ( rc != PASS )
{
host_ptr->ipmitool_thread_info.status = rc ;
host_ptr->ipmitool_thread_info.status_string =
host_ptr->bmc_thread_info.status = rc ;
host_ptr->bmc_thread_info.status_string =
"failed to launch sensor monitoring thread" ;
_stage_change ( host_ptr->hostname,
@ -1149,8 +1149,8 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
if ( mtcTimer_expired ( host_ptr->monitor_ctrl.timer ) )
{
host_ptr->monitor_ctrl.timer.ring = false ;
host_ptr->ipmitool_thread_info.status = FAIL_TIMEOUT ;
host_ptr->ipmitool_thread_info.status_string =
host_ptr->bmc_thread_info.status = FAIL_TIMEOUT ;
host_ptr->bmc_thread_info.status_string =
"timeout waiting for sensor read data" ;
_stage_change ( host_ptr->hostname,
@ -1159,34 +1159,34 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
}
/* check for 'thread done' completion */
else if ( thread_done( host_ptr->ipmitool_thread_ctrl ) )
else if ( thread_done( host_ptr->bmc_thread_ctrl ) )
{
/* Consume done results */
mtcTimer_stop ( host_ptr->monitor_ctrl.timer );
if ( host_ptr->ipmitool_thread_info.status ) // == FAIL_SYSTEM_CALL )
if ( host_ptr->bmc_thread_info.status ) // == FAIL_SYSTEM_CALL )
{
if ( ++host_ptr->ipmitool_thread_ctrl.retries < MAX_THREAD_RETRIES )
if ( ++host_ptr->bmc_thread_ctrl.retries < MAX_THREAD_RETRIES )
{
elog ("%s %s thread %2d failed (rc:%d) (try %d of %d) (%d:%d)\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_ctrl.name.c_str(),
host_ptr->ipmitool_thread_info.command,
host_ptr->ipmitool_thread_info.status,
host_ptr->ipmitool_thread_ctrl.retries,
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_ctrl.name.c_str(),
host_ptr->bmc_thread_info.command,
host_ptr->bmc_thread_info.status,
host_ptr->bmc_thread_ctrl.retries,
MAX_THREAD_RETRIES,
host_ptr->ipmitool_thread_info.progress,
host_ptr->ipmitool_thread_info.runcount);
host_ptr->bmc_thread_info.progress,
host_ptr->bmc_thread_info.runcount);
/* don't flood the logs with the same error data over and over */
if ( host_ptr->ipmitool_thread_ctrl.retries == 1 )
if ( host_ptr->bmc_thread_ctrl.retries == 1 )
{
blog ("%s ... %s\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_info.status_string.c_str());
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_info.status_string.c_str());
}
host_ptr->ipmitool_thread_ctrl.done = true ;
host_ptr->bmc_thread_ctrl.done = true ;
mtcTimer_start ( host_ptr->monitor_ctrl.timer, hwmonTimer_handler, THREAD_RETRY_DELAY_SECS );
_stage_change ( host_ptr->hostname,
host_ptr->monitor_ctrl.stage,
@ -1195,53 +1195,53 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
}
#ifdef WANT_THIS
/* don't flood the logs with the same error data over and over */
if ( host_ptr->ipmitool_thread_ctrl.retries > 1 )
if ( host_ptr->bmc_thread_ctrl.retries > 1 )
{
wlog ("%s %s thread '%d' command is done ; (%d:%d) (rc:%d)\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_ctrl.name.c_str(),
host_ptr->ipmitool_thread_info.command,
host_ptr->ipmitool_thread_info.progress,
host_ptr->ipmitool_thread_info.runcount,
host_ptr->ipmitool_thread_info.status);
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_ctrl.name.c_str(),
host_ptr->bmc_thread_info.command,
host_ptr->bmc_thread_info.progress,
host_ptr->bmc_thread_info.runcount,
host_ptr->bmc_thread_info.status);
blog ("%s ... data: %s\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_info.status_string.c_str());
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_info.status_string.c_str());
}
#endif
}
else
{
dlog ("%s '%s' thread '%d' command is done ; (%d:%d) (rc:%d)\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_ctrl.name.c_str(),
host_ptr->ipmitool_thread_info.command,
host_ptr->ipmitool_thread_info.progress,
host_ptr->ipmitool_thread_info.runcount,
host_ptr->ipmitool_thread_info.status);
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_ctrl.name.c_str(),
host_ptr->bmc_thread_info.command,
host_ptr->bmc_thread_info.progress,
host_ptr->bmc_thread_info.runcount,
host_ptr->bmc_thread_info.status);
blog2 ("%s ... data: %s\n",
host_ptr->ipmitool_thread_ctrl.hostname.c_str(),
host_ptr->ipmitool_thread_info.status_string.c_str());
host_ptr->bmc_thread_ctrl.hostname.c_str(),
host_ptr->bmc_thread_info.status_string.c_str());
}
host_ptr->ipmitool_thread_ctrl.done = true ;
host_ptr->ipmitool_thread_ctrl.retries = 0 ;
host_ptr->bmc_thread_ctrl.done = true ;
host_ptr->bmc_thread_ctrl.retries = 0 ;
#ifdef WANT_FIT_TESTING
if ( daemon_want_fit ( FIT_CODE__HWMON__NO_DATA, host_ptr->hostname ))
{
host_ptr->ipmitool_thread_info.data.clear ();
host_ptr->ipmitool_thread_info.status = 0 ;
host_ptr->ipmitool_thread_info.status_string.clear ();
host_ptr->bmc_thread_info.data.clear ();
host_ptr->bmc_thread_info.status = 0 ;
host_ptr->bmc_thread_info.status_string.clear ();
}
#endif
if ( host_ptr->ipmitool_thread_info.status == PASS )
if ( host_ptr->bmc_thread_info.status == PASS )
{
/* NOTE: This parsing method is not leaking memory ; verified ! */
json_bool status ;
struct json_object * req_obj = (struct json_object *)(NULL) ;
struct json_object * raw_obj = json_tokener_parse( host_ptr->ipmitool_thread_info.data.data() );
struct json_object * raw_obj = json_tokener_parse( host_ptr->bmc_thread_info.data.data() );
if ( raw_obj )
{
/* Look for ... IPMITOOL_JSON__SENSOR_DATA_MESSAGE_HEADER */
@ -1252,14 +1252,14 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
host_ptr->json_ipmi_sensors = msg_ptr ;
if ( msg_ptr )
{
host_ptr->ipmitool_thread_info.status = ipmi_load_sensor_samples ( host_ptr , msg_ptr);
if ( host_ptr->ipmitool_thread_info.status == PASS )
host_ptr->bmc_thread_info.status = ipmi_load_sensor_samples ( host_ptr , msg_ptr);
if ( host_ptr->bmc_thread_info.status == PASS )
{
if ( host_ptr->samples != host_ptr->sensors )
{
if ( host_ptr->quanta_server == false )
{
ilog ("%s read %d sensor samples but expected %d\n",
blog ("%s read %d sensor samples but expected %d\n",
host_ptr->hostname.c_str(),
host_ptr->samples,
host_ptr->sensors );
@ -1270,34 +1270,34 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
}
else
{
host_ptr->ipmitool_thread_info.status_string = "failed to load sensor data" ;
host_ptr->bmc_thread_info.status_string = "failed to load sensor data" ;
}
}
else
{
host_ptr->ipmitool_thread_info.status_string = "failed to get json message after header" ;
host_ptr->ipmitool_thread_info.status = FAIL_JSON_PARSE ;
host_ptr->bmc_thread_info.status_string = "failed to get json message after header" ;
host_ptr->bmc_thread_info.status = FAIL_JSON_PARSE ;
}
}
else
{
host_ptr->ipmitool_thread_info.status_string = "failed to find '" ;
host_ptr->ipmitool_thread_info.status_string.append(IPMITOOL_JSON__SENSOR_DATA_MESSAGE_HEADER);
host_ptr->ipmitool_thread_info.status_string.append("' label") ;
host_ptr->ipmitool_thread_info.status = FAIL_JSON_PARSE ;
host_ptr->bmc_thread_info.status_string = "failed to find '" ;
host_ptr->bmc_thread_info.status_string.append(IPMITOOL_JSON__SENSOR_DATA_MESSAGE_HEADER);
host_ptr->bmc_thread_info.status_string.append("' label") ;
host_ptr->bmc_thread_info.status = FAIL_JSON_PARSE ;
}
}
else
{
host_ptr->ipmitool_thread_info.status_string = "failed to parse ipmitool sensor data string" ;
host_ptr->ipmitool_thread_info.status = FAIL_JSON_PARSE ;
host_ptr->bmc_thread_info.status_string = "failed to parse ipmitool sensor data string" ;
host_ptr->bmc_thread_info.status = FAIL_JSON_PARSE ;
}
if (raw_obj) json_object_put(raw_obj);
if (req_obj) json_object_put(req_obj);
}
if ( host_ptr->ipmitool_thread_info.status )
if ( host_ptr->bmc_thread_info.status )
{
/* Handle thread error status */
if ( host_ptr->groups == 0 )
@ -1369,10 +1369,10 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
/* Handle cases where we got an incomplete sensor reading */
if ( host_ptr->thread_extra_info.samples == 0 )
{
if ( host_ptr->ipmitool_thread_info.status == PASS )
if ( host_ptr->bmc_thread_info.status == PASS )
{
host_ptr->ipmitool_thread_info.status = FAIL_INVALID_DATA ;
host_ptr->ipmitool_thread_info.status_string = "incomplete sensor data reading" ;
host_ptr->bmc_thread_info.status = FAIL_INVALID_DATA ;
host_ptr->bmc_thread_info.status_string = "incomplete sensor data reading" ;
}
_stage_change ( host_ptr->hostname,
host_ptr->monitor_ctrl.stage,
@ -1914,18 +1914,18 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
case HWMON_SENSOR_MONITOR__FAIL:
{
host_ptr->ping_info.ok = false ;
host_ptr->ipmitool_thread_ctrl.retries = 0 ;
host_ptr->bmc_thread_ctrl.retries = 0 ;
mtcTimer_reset ( host_ptr->monitor_ctrl.timer );
if ( host_ptr->ipmitool_thread_info.status )
if ( host_ptr->bmc_thread_info.status )
{
elog ("%s sensor monitoring failure (rc:%d)\n",
host_ptr->hostname.c_str(),
host_ptr->ipmitool_thread_info.status );
if ( host_ptr->ipmitool_thread_info.data.length() )
host_ptr->bmc_thread_info.status );
if ( host_ptr->bmc_thread_info.data.length() )
{
string _temp = host_ptr->ipmitool_thread_info.status_string ;
string _temp = host_ptr->bmc_thread_info.status_string ;
size_t pos = _temp.find ("-f", 0) ;
if ( pos != std::string::npos )
@ -1939,17 +1939,17 @@ int hwmonHostClass::ipmi_sensor_monitor ( struct hwmonHostClass::hwmon_host * ho
{
elog ("%s ... %s\n",
host_ptr->hostname.c_str(),
host_ptr->ipmitool_thread_info.status_string.c_str());
host_ptr->bmc_thread_info.status_string.c_str());
}
}
}
if ( host_ptr->ipmitool_thread_ctrl.id )
if ( host_ptr->bmc_thread_ctrl.id )
{
slog ("%s sensor monitor thread is unexpectedly active ; handling as failure\n",
host_ptr->hostname.c_str());
thread_kill ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info );
thread_kill ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info );
}
if ( host_ptr->interval )
@ -2007,10 +2007,10 @@ int hwmonHostClass::delete_handler ( struct hwmonHostClass::hwmon_host * host_pt
set_bm_prov ( host_ptr, false);
}
if ( host_ptr->ipmitool_thread_ctrl.stage != THREAD_STAGE__IDLE )
if ( host_ptr->bmc_thread_ctrl.stage != THREAD_STAGE__IDLE )
{
int delay = THREAD_POST_KILL_WAIT ;
thread_kill ( host_ptr->ipmitool_thread_ctrl , host_ptr->ipmitool_thread_info) ;
thread_kill ( host_ptr->bmc_thread_ctrl , host_ptr->bmc_thread_info) ;
ilog ("%s thread active ; sending kill ; waiting %d seconds\n",
host_ptr->hostname.c_str(), delay );
@ -2030,14 +2030,14 @@ int hwmonHostClass::delete_handler ( struct hwmonHostClass::hwmon_host * host_pt
{
if ( mtcTimer_expired ( host_ptr->hostTimer ) )
{
if ( host_ptr->ipmitool_thread_ctrl.stage != THREAD_STAGE__IDLE )
if ( host_ptr->bmc_thread_ctrl.stage != THREAD_STAGE__IDLE )
{
if ( host_ptr->retries++ < 3 )
{
wlog ("%s still waiting on active thread ; sending another kill signal (try %d or %d)\n",
host_ptr->hostname.c_str(), host_ptr->retries, 3 );
thread_kill ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info ) ;
thread_kill ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info ) ;
mtcTimer_start ( host_ptr->hostTimer, hwmonTimer_handler, THREAD_POST_KILL_WAIT );
break ;
}
@ -2525,10 +2525,10 @@ void hwmonHostClass::monitor_soon ( struct hwmonHostClass::hwmon_host * host_ptr
host_ptr->hostname.c_str(),
host_ptr->monitor_ctrl.stage);
if ( host_ptr->ipmitool_thread_ctrl.id )
if ( host_ptr->bmc_thread_ctrl.id )
{
ilog ("%s stopping current thread (%lu)\n", host_ptr->hostname.c_str(), host_ptr->ipmitool_thread_ctrl.id );
thread_kill ( host_ptr->ipmitool_thread_ctrl, host_ptr->ipmitool_thread_info );
ilog ("%s stopping current thread (%lu)\n", host_ptr->hostname.c_str(), host_ptr->bmc_thread_ctrl.id );
thread_kill ( host_ptr->bmc_thread_ctrl, host_ptr->bmc_thread_info );
/* have to wait a bit longer than THREAD_POST_KILL_WAIT for the thread kill to happen */
delay += THREAD_POST_KILL_WAIT ;

View File

@ -351,18 +351,18 @@ int hwmonHostClass::ipmi_load_sensor_samples ( struct hwmonHostClass::hwmon_host
else
{
wlog ("%s invalid sensor data:%s\n", host_ptr->hostname.c_str(), sensor_data.c_str());
host_ptr->ipmitool_thread_info.status_string =
host_ptr->bmc_thread_info.status_string =
"failed to load sensor sample data from incoming json string" ;
host_ptr->ipmitool_thread_info.status = FAIL_JSON_PARSE ;
host_ptr->bmc_thread_info.status = FAIL_JSON_PARSE ;
break ;
}
}
else
{
host_ptr->ipmitool_thread_info.status_string = "sensor data parse error for index '" ;
host_ptr->ipmitool_thread_info.status_string.append(itos(host_ptr->thread_extra_info.samples));
host_ptr->ipmitool_thread_info.status_string.append("'");
host_ptr->ipmitool_thread_info.status = FAIL_JSON_PARSE ;
host_ptr->bmc_thread_info.status_string = "sensor data parse error for index '" ;
host_ptr->bmc_thread_info.status_string.append(itos(host_ptr->thread_extra_info.samples));
host_ptr->bmc_thread_info.status_string.append("'");
host_ptr->bmc_thread_info.status = FAIL_JSON_PARSE ;
break ;
}
host_ptr->samples++ ;
@ -371,12 +371,12 @@ int hwmonHostClass::ipmi_load_sensor_samples ( struct hwmonHostClass::hwmon_host
}
else
{
host_ptr->ipmitool_thread_info.status_string = "failed to find '" ;
host_ptr->ipmitool_thread_info.status_string.append(IPMITOOL_JSON__SENSORS_LABEL);
host_ptr->ipmitool_thread_info.status_string.append("' label") ;
host_ptr->ipmitool_thread_info.status = FAIL_JSON_PARSE ;
host_ptr->bmc_thread_info.status_string = "failed to find '" ;
host_ptr->bmc_thread_info.status_string.append(IPMITOOL_JSON__SENSORS_LABEL);
host_ptr->bmc_thread_info.status_string.append("' label") ;
host_ptr->bmc_thread_info.status = FAIL_JSON_PARSE ;
}
return (host_ptr->ipmitool_thread_info.status);
return (host_ptr->bmc_thread_info.status);
}
void _generate_transient_log ( sensor_type * sensor_ptr )
@ -636,7 +636,7 @@ int hwmonHostClass::ipmi_update_sensors ( struct hwmonHostClass::hwmon_host * ho
ipmi_status);
sensor_data_print (host_ptr->sample[j]);
blog3 ("%s ... %s\n", host_ptr->hostname.c_str(), host_ptr->ipmitool_thread_info.data.c_str());
blog3 ("%s ... %s\n", host_ptr->hostname.c_str(), host_ptr->bmc_thread_info.data.c_str());
host_ptr->sensor[i].sample_severity = HWMON_SEVERITY_MINOR ;
}
@ -699,7 +699,7 @@ int hwmonHostClass::ipmi_update_sensors ( struct hwmonHostClass::hwmon_host * ho
ipmi_status);
sensor_data_print (host_ptr->sample[j]);
blog3 ("%s ... %s\n", host_ptr->hostname.c_str(), host_ptr->ipmitool_thread_info.data.c_str());
blog3 ("%s ... %s\n", host_ptr->hostname.c_str(), host_ptr->bmc_thread_info.data.c_str());
host_ptr->sensor[i].sample_severity = HWMON_SEVERITY_MINOR ;
}

View File

@ -170,7 +170,7 @@ void hwmonSensor_init ( string & hostname , sensor_type * sensor_ptr )
sensor_ptr->unit_rate.clear();
sensor_ptr->unit_modifier.clear();
sensor_ptr->prot = PROTOCOL__NONE ;
sensor_ptr->prot = BMC_PROTOCOL__IPMITOOL ;
sensor_ptr->kind = SENSOR_KIND__NONE ;
sensor_ptr->unit = SENSOR_UNIT__NONE ;

View File

@ -25,13 +25,12 @@ using namespace std;
#include "daemon_common.h"
#include "nodeBase.h"
#include "nodeBase.h" /* for ... mtce node common definitions */
#include "bmcUtil.h" /* for ... mtce-common board management */
#include "hostUtil.h" /* for ... mtce host common definitions */
#include "nodeMacro.h"
#include "ipmiUtil.h"
#include "threadUtil.h"
#include "hwmonThreads.h" /* for ... IPMITOOL_THREAD_CMD__READ_SENSORS */
#include "hwmonThreads.h" /* for ... BMC_THREAD_CMD__READ_SENSORS */
#include "hwmonIpmi.h" /* for ... MAX_IPMITOOL_PARSE_ERRORS */
#include "hwmonClass.h" /* for ... thread_extra_info_type */
@ -331,7 +330,7 @@ void * hwmonThread_ipmitool ( void * arg )
extra_ptr->samples = samples = 0 ;
switch ( info_ptr->command )
{
case IPMITOOL_THREAD_CMD__POWER_STATUS:
case BMC_THREAD_CMD__POWER_STATUS:
{
int rc = PASS ;
@ -349,7 +348,7 @@ void * hwmonThread_ipmitool ( void * arg )
}
/**************** Create the password file *****************/
ipmiUtil_create_pw_fn ( info_ptr, extra_ptr->bm_pw ) ;
bmcUtil_create_pw_file ( info_ptr, extra_ptr->bm_pw, BMC_PROTOCOL__IPMITOOL) ;
if ( info_ptr->password_file.empty() )
{
info_ptr->status_string = "failed to get a temporary password filename" ;
@ -362,7 +361,10 @@ void * hwmonThread_ipmitool ( void * arg )
/*************** Create the output filename ***************/
string ipmitool_datafile =
ipmiUtil_create_data_fn (info_ptr->hostname, IPMITOOL_POWER_STATUS_FILE_SUFFIX ) ;
bmcUtil_create_data_fn (info_ptr->hostname,
BMC_POWER_STATUS_FILE_SUFFIX,
BMC_PROTOCOL__IPMITOOL ) ;
dlog_t ("%s power query filename : %s\n",
info_ptr->log_prefix,
ipmitool_datafile.c_str());
@ -434,7 +436,7 @@ void * hwmonThread_ipmitool ( void * arg )
}
break ;
}
case IPMITOOL_THREAD_CMD__READ_SENSORS:
case BMC_THREAD_CMD__READ_SENSORS:
{
int rc = PASS ;
@ -464,7 +466,9 @@ void * hwmonThread_ipmitool ( void * arg )
/*************** Create the output filename ***************/
string sensor_datafile =
ipmiUtil_create_data_fn (info_ptr->hostname, IPMITOOL_SENSOR_OUTPUT_FILE_SUFFIX ) ;
bmcUtil_create_data_fn (info_ptr->hostname,
IPMITOOL_SENSOR_OUTPUT_FILE_SUFFIX,
BMC_PROTOCOL__IPMITOOL ) ;
dlog_t ("%s sensor output file%s\n",
info_ptr->log_prefix,
@ -761,7 +765,7 @@ ipmitool_thread_done:
pthread_signal_handler ( info_ptr );
/* Sensor reading specific exit */
if ( info_ptr->command == IPMITOOL_THREAD_CMD__READ_SENSORS )
if ( info_ptr->command == BMC_THREAD_CMD__READ_SENSORS )
{
if ( parse_errors )
{

View File

@ -678,8 +678,8 @@ bool got_delimited_value ( char * buf_ptr,
#define BUFFER (80)
#define MC_INFO_LABEL_FW_VERSION ((const char *)("Firmware Revision"))
#define MC_INFO_LABEL_DELIMITER ((const char *)(": "))
#define BMC_INFO_LABEL_FW_VERSION ((const char *)("Firmware Revision"))
#define BMC_INFO_LABEL_DELIMITER ((const char *)(": "))
string get_bmc_version_string ( string hostname,
const char * filename )
{
@ -693,8 +693,8 @@ string get_bmc_version_string ( string hostname,
MEMSET_ZERO(buffer);
while ( fgets (buffer, BUFFER, _stream) )
{
if ( got_delimited_value ( buffer, MC_INFO_LABEL_FW_VERSION,
MC_INFO_LABEL_DELIMITER,
if ( got_delimited_value ( buffer, BMC_INFO_LABEL_FW_VERSION,
BMC_INFO_LABEL_DELIMITER,
bmc_fw_version ))
{
break ;

View File

@ -8,7 +8,7 @@ SHELL = /bin/bash
SRCS = mtcAlarm.cpp
SRCS += mtcThreads.cpp
SRCS += mtcIpmiUtil.cpp
SRCS += mtcBmcUtil.cpp
SRCS += mtcNodeHdlrs.cpp
SRCS += mtcSubfHdlrs.cpp
SRCS += mtcNodeFsm.cpp
@ -32,7 +32,7 @@ CONTROL_OBJS += ../common/nodeClass.o
CONTROL_OBJS = mtcAlarm.o
CONTROL_OBJS += mtcThreads.o
CONTROL_OBJS += mtcIpmiUtil.o
CONTROL_OBJS += mtcBmcUtil.o
CONTROL_OBJS += mtcNodeCtrl.o
CONTROL_OBJS += mtcNodeFsm.o
CONTROL_OBJS += mtcNodeHdlrs.o
@ -51,7 +51,7 @@ CONTROL_OBJS += ../common/nodeClass.o
OBJS = $(SRCS:.cpp=.o)
BINS = mtcAgent mtcClient
LDLIBS += -lstdc++ -ldaemon -lcommon -lthreadUtil -lipmiUtil -lfmcommon -lalarm -lpthread -lrt -levent -ljson-c -lamon -lcrypto -luuid
LDLIBS += -lstdc++ -ldaemon -lcommon -lthreadUtil -lbmcUtils -lfmcommon -lalarm -lpthread -lrt -levent -ljson-c -lamon -lcrypto -luuid
INCLUDES = -I. -I/usr/include/mtce-daemon -I/usr/include/mtce-common
INCLUDES += -I../common -I../alarm -I../heartbeat -I../hwmon -I../public
CCFLAGS += -g -O2 -Wall -Wextra -Werror -Wno-missing-braces

View File

@ -1,297 +0,0 @@
#ifndef __INCLUDE_IPMICLIENT_HH__
#define __INCLUDE_IPMICLIENT_HH__
/*
* Copyright (c) 2016 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River CGTS Platform IPMI Client Daemon
*/
/*
*
* ------------------------------
* sensor_monitor_ready: outgoing message - indicates service just started and needs configuration
* ------------------------------
*
* The sensor monitor will configure itself based off the content of the
* following formatted configuration message.
*
* { "sensor_monitor_ready":
* {
* "hostname":"compute-0"
* }
* }
*
*
* ------------------------------
* ipmitool_sensor_monitor_config: incoming message
* ------------------------------
*
* The sensor monitor will configure itself based off the content of the
* following formatted configuration message.
*
* { "ipmitool_sensor_monitor_config":
* {
* "hostname":"compute-0",
* "interval":120,
* "analog" :true,
* "discrete":false
* }
* }
*
* ---------------------------------------
* ipmitool_sensor_monitor_config_response: outgoing message
* ---------------------------------------
*
* This is a config response message. Normally a pass but if there
* is a configuration error then a return code and message are provided.
*
* { "ipmitool_sensor_monitor_config_response":
* {
* "hostname":"compute-0",
* "status": <number>,
* "status_string":"<pass | error message>"
* }
* }
*
* --------------------------------
* ipmitool_sensor_threshold_config: incoming message - NOT YET SUPPORTED IMPLEMENTATION
* --------------------------------
*
* Specify only the thresholds that need to be changed.
*
* { "ipmitool_sensor_threshold_config":
* [
* {
* "hostname":"compute-0",
* "n":"Temp_CPU0",
* "lcr":"90.000",
* "lnc":"85.000"
* }
* ]
* }
*
*
* --------------------
* ipmitool_sensor_data: outgoing message
* --------------------
*
* The sensor data is formatted in a json style string that is sent
* to the hardware monitor daemon on the active controller as
* specified by the aformentioned configuration command.
*
* The following is a brief 3 sensor example of the expected
* ipmitool output and json string conversion that is sent to
* hardware mon.
*
* ipmitool output:
*
* Temp_CPU0 | 54.000 | % degrees C | ok | na | na | na | 86.000 | 87.000 | na
* PSU2 Input | 0.000 | % Watts | cr | na | 0.000 | na | na | na | na
* Critical IRQ | 0x0 | discrete | 0x0080| na | na | na | na | na | na
* Fan_SYS0_2 | 4700.000 | % RPM | ok | na | 500.000 | 1000.000 | na | na | na
*
* Message Design Strategy:
* 1. Maintain all the ipmitool output information so that it is available
* to the hardware monitor for future enhancements without the need to
* change the client side messaging.
* 2. Validate the format of the ipmitool output and report on any errors
* observed in a status field of the response string.
* 3. Deliver an industry standard json string formated message
* 4. Provide an overall status field indicating any formatting errors
* detected in the sensor data output format. This is not a summary
* status of the sensor data.
* 5. minimize the amount of data sent
* - use short sensor record labels
* n = name
* v = sensor reading value
* u = unit format used when interpreting the data
* s = correlated status
* - ipmitool labels for thresholds but only include labels for values that are not 'na'
* unr = Upper Non-Recoverable
* ucr = Upper Critical
* unc = Upper Non-Critical
* lnc = Lower Non-Critical
* lcr = Lower Critical
* lnr = Lower Non-Recoverable
*
* Json String: sensor data exacluded
* -----------
*
* {
* "ipmitool_sensor_data":
* {
* "hostname" :"compute-0",
* "status" : 0,
* "status_string" : "pass",
* "analog" :
* [
* { },
* { },
* { }
* ],
* "discrete":
* [
*
* ]
* }
*}
*
* Jason String: full
* -------------
*
*{
* "ipmitool_sensor_data":
* {
* "hostname" : "compute-0",
* "status" : 0,
* "status_string": "pass",
* "analog":[
* {
* "n":"Temp_CPU0",
* "v":"54.000",
* "u":"% degrees C",
* "s":"ok",
* "unc":"86.000",
* "ucr":"87.000"
* },
* {
* "n":"PSU2 Input",
* "v":"0.000",
* "u":"% Watts",
* "s":"cr",
* "lcr":"0.000"
* },
* {
* "n":"Fan_SYS0_2",
* "v":"4700.00",
* "u":"% RPM",
* "s":"ok",
* "lcr":"500.000",
* "lnc":"1000.000"
* }
* ],
* "discrete":[
* {
* "n":"Critical IRQ",
* "v":"0x0",
* "s":"0x0080"
* }
* ]
* }
*}
*
*
*/
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
using namespace std;
#include "msgClass.h" /* for ... msgClassSock */
#define MAX_HOST_SENSORS (100)
/* Control structure used for ipmitool related functions ; like sensor monitoring */
#define DEFAULT_IPMITOOL_SENSOR_MONITORING_PERIOD_SECS (120) /* 2 minutes */
#define IPMITOOL_JSON__MONITOR_READY_HEADER ((const char *)("sensor_monitor_ready"))
#define IPMITOOL_JSON__CONFIG_REQUEST_HEADER ((const char *)("ipmitool_sensor_monitor_config"))
#define IPMITOOL_JSON__CONFIG_RESPONSE_HEADER ((const char *)("ipmitool_sensor_monitor_config_response"))
#define IPMITOOL_JSON__SENSOR_DATA_MESSAGE_HEADER ((const char *)("ipmitool_sensor_data"))
#define IPMITOOL_JSON__ANALOG_LABEL ((const char *)("analog"))
#define IPMITOOL_JSON__DISCRETE_LABEL ((const char *)("discrete"))
#define IPMITOOL_SENSOR_QUERY_CMD ((const char *)(" sensor list"))
// #define IPMITOOL_SENSOR_OUTPUT_FILE ((const char *)("/tmp/ipmitool_sensor_data"))
#define IPMITOOL_SENSOR_OUTPUT_FILE ((const char *)("/var/run/ipmitool_sensor_data"))
#define IPMITOOL_PATH_AND_FILENAME ((const char *)("/usr/bin/ipmitool"))
#define IPMITOOL_PATH_AND_FILENAME_V ((const char *)("/home/sysadmin/test/ipmitool"))
#define IPMITOOL_MAX_FIELD_LEN (64)
typedef struct
{
char name [IPMITOOL_MAX_FIELD_LEN] ; /* sensor name */
char value [IPMITOOL_MAX_FIELD_LEN] ; /* sensor value */
char unit [IPMITOOL_MAX_FIELD_LEN] ; /* sensor unit type */
char status [IPMITOOL_MAX_FIELD_LEN] ; /* status - ok, nc, cr, nr */
char lnr [IPMITOOL_MAX_FIELD_LEN] ; /* Lower Non-Recoverable */
char lcr [IPMITOOL_MAX_FIELD_LEN] ; /* Lower Critical */
char lnc [IPMITOOL_MAX_FIELD_LEN] ; /* Lower Non-Critical */
char unc [IPMITOOL_MAX_FIELD_LEN] ; /* Upper Non-Critical */
char ucr [IPMITOOL_MAX_FIELD_LEN] ; /* Upper Critical */
char unr [IPMITOOL_MAX_FIELD_LEN] ; /* Upper Non-Recoverable */
} ipmitool_sample_type ;
#define IPMITOOL_FIT_LINE_LEN (1000)
typedef struct
{
bool enable ;
bool exclude_discrete_sensors ;
bool include_discrete_sensors ;
bool exclude_analog_sensors ;
bool include_analog_sensors ;
bool exclude_sensors ;
int code ;
char json [IPMITOOL_FIT_LINE_LEN] ;
} ipmiClient_fit_type ;
typedef struct
{
bool init ; /**< service initialized */
bool configured ; /**< config command was received */
int interval ; /**< audit interval in seconds */
struct mtc_timer timer ; /**< interval audit timer */
bool want_analog_sensors ; /**< true to send analog sensor data */
bool want_discrete_sensors ; /**< true to send discrete sensor data */
int analog_sensors ; /**< number of analog sensors in a dump */
int discrete_sensors ; /**< number of discrete sensors in a dump */
string hostname ; /**< this hosts name */
string config_request ; /**< original config request string */
string query_request ; /**< sensor query system call request */
string status_string ; /**< empty or error log message */
int parse_errors ; /**< parse or unreadable sensor count */
int status ; /**< configuration request exec status */
msgClassSock* sensor_tx_sock ; /**< sensor data tx socket interface */
int sensor_rx_port ; /**< the hwmond port to send data to */
ipmiClient_fit_type fit ; /**< manage fault insertion testing */
} ipmiClient_ctrl_type ;
/* module open and close */
void ipmiClient_init ( char * hostname );
void ipmiClient_fini ( void );
void ipmiClient_configure ( void ); /* called by daemon_configure */
/* service utilities */
int ipmiClient_config ( char * config_ptr );
int ipmiClient_ready ( string hostname );
int ipmiClient_query ( void );
/* These are interfaces used to manage the socket used
* to transmit sensor data to the Hardware Monitor.
*
* ipmiClient_socket_open passes in the Hardware
* Monitor's receive port number.
*/
int ipmiClient_socket_open ( int sensor_rx_port , string & iface );
void ipmiClient_socket_close ( void );
bool ipmiClient_socket_ok ( void );
/* returns the sensor monitor timer id */
timer_t ipmiClient_tid ( void );
#endif

View File

@ -0,0 +1,372 @@
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*
*
* @file
* Wind River Titanium Cloud Maintenance BMC Utilities
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
#include "nodeBase.h" /* for ... mtce common definitions */
#include "nodeClass.h" /* for ... */
#include "bmcUtil.h" /* for ... mtce-common bmc utility header */
/*****************************************************************************
*
* Name : bmc_command_send
*
* Description: This utility starts the bmc command handling thread
* with the specified command.
*
* Returns : PASS if all the pre-start semantic checks pass and the
* thread was started.
*
* Otherwise the thread was not started and some non zero
* FAIL_xxxx code is returned after a representative design
* log is generated.
*
*****************************************************************************/
int nodeLinkClass::bmc_command_send ( struct nodeLinkClass::node * node_ptr,
int command )
{
int rc = PASS ;
node_ptr->bmc_thread_info.command = command ;
/* Update / Setup the BMC access credentials */
node_ptr->thread_extra_info.bm_ip = node_ptr->bm_ip ;
node_ptr->thread_extra_info.bm_un = node_ptr->bm_un ;
node_ptr->thread_extra_info.bm_pw = node_ptr->bm_pw ;
node_ptr->thread_extra_info.bm_type = node_ptr->bm_type ;
/* Special case handliong for Redfish Root (BMC) Query command.
* Current protocol override for this command that only applies
* to redfish and used for the bmc protocol learning process. */
if ( command == BMC_THREAD_CMD__BMC_QUERY )
node_ptr->bmc_thread_info.proto = BMC_PROTOCOL__REDFISHTOOL ;
else
node_ptr->bmc_thread_info.proto = node_ptr->bmc_protocol ;
#ifdef WANT_FIT_TESTING
{
bool want_fit = false ;
int fit = FIT_CODE__BMC_COMMAND_SEND ;
if ( daemon_want_fit ( fit, node_ptr->hostname, "root_query" ) == true )
{
want_fit = true ;
}
else if ( daemon_want_fit ( fit, node_ptr->hostname, "bmc_info" ) == true )
{
want_fit = true ;
}
else if (( command == BMC_THREAD_CMD__POWER_STATUS ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_status" ) == true ))
{
want_fit = true ;
}
else if ( daemon_want_fit ( fit, node_ptr->hostname, "reset_cause" ) == true )
{
want_fit = true ;
}
else if (( command == BMC_THREAD_CMD__POWER_RESET ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "reset" ) == true ))
{
want_fit = true ;
}
else if (( command == BMC_THREAD_CMD__POWER_ON ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_on" ) == true ))
{
want_fit = true ;
}
else if (( command == BMC_THREAD_CMD__POWER_OFF ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_off" ) == true ))
{
want_fit = true ;
}
else if (( command == BMC_THREAD_CMD__POWER_CYCLE ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_cycle" ) == true ))
{
want_fit = true ;
}
else if (( command == BMC_THREAD_CMD__BOOTDEV_PXE ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "netboot_pxe" ) == true ))
{
want_fit = true ;
}
if ( want_fit == true )
{
slog ("%s FIT %s\n", node_ptr->hostname.c_str(), bmcUtil_getCmd_str(command).c_str() );
node_ptr->bmc_thread_info.status = node_ptr->bmc_thread_ctrl.status = rc = FAIL_FIT ;
node_ptr->bmc_thread_info.status_string = "bmc_command_send fault insertion failure" ;
return ( rc );
}
}
#endif
if (( hostUtil_is_valid_ip_addr ( node_ptr->thread_extra_info.bm_ip ) == true ) &&
( !node_ptr->thread_extra_info.bm_un.empty() ) &&
( !node_ptr->thread_extra_info.bm_pw.empty ()))
{
node_ptr->bmc_thread_ctrl.status = rc =
thread_launch ( node_ptr->bmc_thread_ctrl,
node_ptr->bmc_thread_info ) ;
if ( rc != PASS )
{
elog ("%s failed to launch power control thread (rc:%d)\n",
node_ptr->hostname.c_str(), rc );
}
else
{
blog ("%s %s thread launched with the '%s' command\n",
node_ptr->hostname.c_str(),
node_ptr->bmc_thread_ctrl.name.c_str(),
bmcUtil_getCmd_str(node_ptr->bmc_thread_info.command).c_str());
}
node_ptr->bmc_thread_ctrl.retries = 0 ;
}
else
{
node_ptr->bmc_thread_ctrl.status = rc =
node_ptr->bmc_thread_info.status = FAIL_INVALID_DATA ;
node_ptr->bmc_thread_info.status_string = "one or more bmc credentials are invalid" ;
wlog ("%s %s %s %s\n", node_ptr->hostname.c_str(),
hostUtil_is_valid_ip_addr (
node_ptr->thread_extra_info.bm_ip ) ? "" : "bm_ip:invalid",
node_ptr->thread_extra_info.bm_un.empty() ? "bm_un:empty" : "",
node_ptr->thread_extra_info.bm_pw.empty() ? "bm_pw:empty" : "");
}
return (rc);
}
/*****************************************************************************
*
* Name : bmc_command_recv
*
* Description: This utility will check for bmc command thread completion.
*
* Returns : PASS is returned if the thread reports done.
* RETRY is returned if the thread has not completed.
* FAIL_RETRY is returned after 10 back-to-back calls return RETRY.
*
*****************************************************************************/
int nodeLinkClass::bmc_command_recv ( struct nodeLinkClass::node * node_ptr )
{
int rc = RETRY ;
/* check for 'thread done' completion */
if ( thread_done( node_ptr->bmc_thread_ctrl ) == true )
{
if ( node_ptr->bmc_protocol == BMC_PROTOCOL__REDFISHTOOL )
{
/* handle the redfishtool root query as a special case because
* it is likely to fail and we don't want un-necessary error logs */
if ( node_ptr->bmc_thread_info.command == BMC_THREAD_CMD__BMC_QUERY )
{
if (( rc = node_ptr->bmc_thread_info.status ) != PASS )
{
blog2 ("%s %s command failed (%s) (data:%s) (rc:%d:%d:%s)\n",
node_ptr->hostname.c_str(),
bmcUtil_getCmd_str(node_ptr->bmc_thread_info.command).c_str(),
bmcUtil_getProtocol_str(node_ptr->bmc_protocol).c_str(),
node_ptr->bmc_thread_info.data.c_str(),
rc,
node_ptr->bmc_thread_info.status,
node_ptr->bmc_thread_info.status_string.c_str());
}
else
{
ilog("%s Redfish Root Query:\n%s",
node_ptr->hostname.c_str(),
node_ptr->bmc_thread_info.data.c_str());
}
}
else if (( rc = node_ptr->bmc_thread_info.status ) != PASS )
{
elog ("%s %s command failed (%s) (data:%s) (rc:%d:%d:%s)\n",
node_ptr->hostname.c_str(),
bmcUtil_getCmd_str(node_ptr->bmc_thread_info.command).c_str(),
bmcUtil_getProtocol_str(node_ptr->bmc_protocol).c_str(),
node_ptr->bmc_thread_info.data.c_str(),
rc,
node_ptr->bmc_thread_info.status,
node_ptr->bmc_thread_info.status_string.c_str());
}
else
{
ilog ("TODO: Handle RedfishTool Response:\n%s",
node_ptr->bmc_thread_info.data.c_str() );
rc = PASS ;
}
}
else /* default is ipmi */
{
if (( rc = node_ptr->bmc_thread_info.status ) != PASS )
{
elog ("%s %s command failed (%s) (data:%s) (rc:%d:%d:%s)\n",
node_ptr->hostname.c_str(),
bmcUtil_getCmd_str(node_ptr->bmc_thread_info.command).c_str(),
bmcUtil_getProtocol_str(node_ptr->bmc_protocol).c_str(),
node_ptr->bmc_thread_info.data.c_str(),
rc,
node_ptr->bmc_thread_info.status,
node_ptr->bmc_thread_info.status_string.c_str());
}
else
{
if ( node_ptr->bmc_thread_info.command == BMC_THREAD_CMD__POWER_RESET )
{
if ( node_ptr->bmc_thread_info.data.find(IPMITOOL_POWER_RESET_RESP) == std::string::npos )
rc = FAIL_RESET_CONTROL ;
}
else if ( node_ptr->bmc_thread_info.command == BMC_THREAD_CMD__POWER_OFF )
{
if ( node_ptr->bmc_thread_info.data.find(IPMITOOL_POWER_OFF_RESP) == std::string::npos )
rc = FAIL_POWER_CONTROL ;
}
else if ( node_ptr->bmc_thread_info.command == BMC_THREAD_CMD__POWER_ON )
{
if ( node_ptr->bmc_thread_info.data.find(IPMITOOL_POWER_ON_RESP) == std::string::npos )
rc = FAIL_POWER_CONTROL ;
}
else if ( node_ptr->bmc_thread_info.command == BMC_THREAD_CMD__POWER_CYCLE )
{
if ( node_ptr->bmc_thread_info.data.find(IPMITOOL_POWER_CYCLE_RESP) == std::string::npos )
rc = FAIL_POWER_CONTROL ;
}
if ( rc )
{
node_ptr->bmc_thread_info.status = rc ;
node_ptr->bmc_thread_info.status_string = ("power command failed");
wlog ("%s %s Response: %s\n",
node_ptr->hostname.c_str(),
bmcUtil_getCmd_str(
node_ptr->bmc_thread_info.command).c_str(),
node_ptr->bmc_thread_info.data.c_str());
}
else
{
blog ("%s %s Response: %s\n",
node_ptr->hostname.c_str(),
bmcUtil_getCmd_str(
node_ptr->bmc_thread_info.command).c_str(),
node_ptr->bmc_thread_info.data.c_str());
}
}
}
#ifdef WANT_FIT_TESTING
if ( rc == PASS )
{
bool want_fit = false ;
int fit = FIT_CODE__BMC_COMMAND_RECV ;
if ( daemon_want_fit ( fit, node_ptr->hostname, "root_query" ) == true )
{
want_fit = true ;
}
if ( daemon_want_fit ( fit, node_ptr->hostname, "bmc_info" ) == true )
{
want_fit = true ;
}
else if ( daemon_want_fit ( fit, node_ptr->hostname, "reset_cause" ) == true )
{
want_fit = true ;
}
else if (( node_ptr->bmc_thread_info.command == BMC_THREAD_CMD__POWER_RESET ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "reset" ) == true ))
{
want_fit = true ;
}
else if (( node_ptr->bmc_thread_info.command == BMC_THREAD_CMD__POWER_ON ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_on" ) == true ))
{
want_fit = true ;
}
else if (( node_ptr->bmc_thread_info.command == BMC_THREAD_CMD__POWER_OFF ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_off" ) == true ))
{
want_fit = true ;
}
else if (( node_ptr->bmc_thread_info.command == BMC_THREAD_CMD__POWER_CYCLE ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_cycle" ) == true ))
{
want_fit = true ;
}
if ( want_fit == true )
{
node_ptr->bmc_thread_info.status = rc = FAIL_FIT ;
node_ptr->bmc_thread_info.status_string = "bmc_command_recv fault insertion failure" ;
}
}
#endif
}
/* handle max retries reached */
else if ( node_ptr->bmc_thread_ctrl.retries++ >= BMC__MAX_RECV_RETRIES )
{
wlog ("%s %s command timeout (%d of %d)\n",
node_ptr->hostname.c_str(),
bmcUtil_getCmd_str(node_ptr->bmc_thread_info.command).c_str(),
node_ptr->bmc_thread_ctrl.retries,
BMC__MAX_RECV_RETRIES);
rc = FAIL_RETRY;
}
/* handle progressive retry */
else
{
if ( node_ptr->bmc_thread_ctrl.id == 0 )
{
slog ("%s %s command not-running\n",
node_ptr->hostname.c_str(),
bmcUtil_getCmd_str(node_ptr->bmc_thread_info.command).c_str());
rc = FAIL_NOT_ACTIVE ;
}
else
{
ilog ("%s %s command in-progress (polling %d of %d)\n",
node_ptr->hostname.c_str(),
bmcUtil_getCmd_str(node_ptr->bmc_thread_info.command).c_str(),
node_ptr->bmc_thread_ctrl.retries,
BMC__MAX_RECV_RETRIES);
rc = RETRY ;
}
}
if ( rc != RETRY )
{
node_ptr->bmc_thread_ctrl.done = true ;
node_ptr->bmc_thread_ctrl.retries = 0 ;
node_ptr->bmc_thread_ctrl.id = 0 ;
node_ptr->bmc_thread_info.id = 0 ;
node_ptr->bmc_thread_info.command = 0 ;
}
return (rc);
}
/*****************************************************************************
*
* Name : bmc_command_done
*
* Description: This utility frees the ipmitool command thread for next execution.
*
*****************************************************************************/
void nodeLinkClass::bmc_command_done ( struct nodeLinkClass::node * node_ptr )
{
node_ptr->bmc_thread_ctrl.done = true ;
}

View File

@ -0,0 +1,16 @@
#ifndef __INCLUDE_MTCBMCUTIL_H__
#define __INCLUDE_MTCBMCUTIL_H__
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River Titanium Cloud's Maintenance IPMI Utilities Header
*/
#endif

View File

@ -471,7 +471,7 @@ int nodeLinkClass::cmd_handler ( struct nodeLinkClass::node * node_ptr )
}
case MTC_CMD_STAGE__RESET:
{
if (( node_ptr->bm_provisioned == true ) && ( node_ptr->bm_accessible == true ))
if (( node_ptr->bmc_provisioned == true ) && ( node_ptr->bmc_accessible == true ))
{
plog ("%s Performing RESET over Board Management Interface\n", node_ptr->hostname.c_str());
if ( node_ptr->cmd.task == true )
@ -480,7 +480,7 @@ int nodeLinkClass::cmd_handler ( struct nodeLinkClass::node * node_ptr )
}
/* bmc power control reset by ipmitool */
rc = ipmi_command_send ( node_ptr, IPMITOOL_THREAD_CMD__POWER_RESET );
rc = bmc_command_send ( node_ptr, BMC_THREAD_CMD__POWER_RESET );
if ( rc == PASS )
{
@ -498,11 +498,11 @@ int nodeLinkClass::cmd_handler ( struct nodeLinkClass::node * node_ptr )
}
else
{
if ( node_ptr->bm_provisioned == false )
if ( node_ptr->bmc_provisioned == false )
{
wlog ("%s Board Management Interface not provisioned\n", node_ptr->hostname.c_str());
}
else if ( node_ptr->bm_accessible == false )
else if ( node_ptr->bmc_accessible == false )
{
wlog ("%s Board Management Interface not accessible\n", node_ptr->hostname.c_str());
}
@ -519,7 +519,7 @@ int nodeLinkClass::cmd_handler ( struct nodeLinkClass::node * node_ptr )
int delay = (((offline_period*offline_threshold)/1000)+3);
/* bmc power control reset by ipmitool */
rc = ipmi_command_recv ( node_ptr );
rc = bmc_command_recv ( node_ptr );
if ( rc == RETRY )
{
mtcTimer_start ( node_ptr->mtcCmd_timer, mtcTimer_handler, MTC_IPMITOOL_REQUEST_DELAY );
@ -618,11 +618,11 @@ int nodeLinkClass::cmd_handler ( struct nodeLinkClass::node * node_ptr )
case MTC_CMD_STAGE__IPMI_COMMAND_SEND:
{
if ( ipmi_command_send ( node_ptr, node_ptr->cmdReq ) != PASS )
if ( bmc_command_send ( node_ptr, node_ptr->cmdReq ) != PASS )
{
elog ("%s IPMI %s Send Failed\n",
node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->cmdReq));
bmcUtil_getCmd_str(node_ptr->cmdReq).c_str());
node_ptr->mtcCmd_work_fifo_ptr->status = FAIL_RETRY ;
node_ptr->mtcCmd_work_fifo_ptr->stage = MTC_CMD_STAGE__DONE ;
@ -631,7 +631,7 @@ int nodeLinkClass::cmd_handler ( struct nodeLinkClass::node * node_ptr )
{
plog ("%s IPMI %s Requested\n",
node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->cmdReq));
bmcUtil_getCmd_str(node_ptr->cmdReq).c_str());
mtcTimer_start ( node_ptr->mtcCmd_timer, mtcTimer_handler, MTC_IPMITOOL_REQUEST_DELAY );
node_ptr->mtcCmd_work_fifo_ptr->stage = MTC_CMD_STAGE__IPMI_COMMAND_RECV ;
@ -643,7 +643,7 @@ int nodeLinkClass::cmd_handler ( struct nodeLinkClass::node * node_ptr )
{
if ( mtcTimer_expired ( node_ptr->mtcCmd_timer ) )
{
rc = ipmi_command_recv ( node_ptr );
rc = bmc_command_recv ( node_ptr );
if ( rc == RETRY )
{
mtcTimer_start ( node_ptr->mtcCmd_timer, mtcTimer_handler, MTC_SECS_5 ) ;
@ -652,12 +652,12 @@ int nodeLinkClass::cmd_handler ( struct nodeLinkClass::node * node_ptr )
else if ( rc == PASS )
{
plog ("%s IPMI %s Successful\n", node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->cmdReq));
bmcUtil_getCmd_str(node_ptr->cmdReq).c_str());
}
else
{
plog ("%s IPMI %s Requested\n", node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->cmdReq));
bmcUtil_getCmd_str(node_ptr->cmdReq).c_str());
}
node_ptr->mtcCmd_work_fifo_ptr->status = rc ;
node_ptr->mtcCmd_work_fifo_ptr->stage = MTC_CMD_STAGE__OFFLINE_CHECK ;

View File

@ -1,348 +0,0 @@
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*
*
* @file
* Wind River Titanium Cloud Maintenance IPMI Utilities
*/
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
#include "nodeBase.h" /* for ... mtce common definitions */
#include "nodeClass.h" /* for ... */
/* IPMI Command strings */
const char mtc_ipmiRequest_str[IPMITOOL_THREAD_CMD__LAST][20] =
{
"null",
"Reset",
"Power-On",
"Power-Off",
"Power-Cycle",
"Query BMC Info",
"Query Power Status",
"Query Reset Reason"
};
const char * getIpmiCmd_str ( int command )
{
if (( command > IPMITOOL_THREAD_CMD__NULL ) &&
( command < IPMITOOL_THREAD_CMD__LAST ))
{
return (&mtc_ipmiRequest_str[command][0]);
}
slog ("Invalid command (%d)\n", command );
return (&mtc_ipmiRequest_str[IPMITOOL_THREAD_CMD__NULL][0]);
}
const char mtc_ipmiAction_str[IPMITOOL_THREAD_CMD__LAST][30] =
{
"null",
"resetting",
"powering on",
"powering off",
"power cycling",
"querying bmc info",
"querying power status",
"querying reset cause"
};
const char * getIpmiAction_str ( int command )
{
if (( command > IPMITOOL_THREAD_CMD__NULL ) &&
( command < IPMITOOL_THREAD_CMD__LAST ))
{
return (&mtc_ipmiAction_str[command][0]);
}
slog ("Invalid command (%d)\n", command );
return (&mtc_ipmiAction_str[IPMITOOL_THREAD_CMD__NULL][0]);
}
/*****************************************************************************
*
* Name : ipmi_command_send
*
* Description: This utility starts the ipmitool command handling thread
* with the specified command.
*
* Returns : PASS if all the pre-start semantic checks pass and the
* thread was started.
*
* Otherwise the thread was not started and some non zero
* FAIL_xxxx code is returned after a representative design
* log is generated.
*
*****************************************************************************/
int nodeLinkClass::ipmi_command_send ( struct nodeLinkClass::node * node_ptr, int command )
{
int rc = PASS ;
node_ptr->ipmitool_thread_info.command = command ;
/* Update / Setup the BMC access credentials */
node_ptr->thread_extra_info.bm_ip = node_ptr->bm_ip ;
node_ptr->thread_extra_info.bm_un = node_ptr->bm_un ;
node_ptr->thread_extra_info.bm_pw = node_ptr->bm_pw ;
node_ptr->thread_extra_info.bm_type = node_ptr->bm_type ;
#ifdef WANT_FIT_TESTING
{
bool want_fit = false ;
int fit = FIT_CODE__IPMI_COMMAND_SEND ;
int command = node_ptr->ipmitool_thread_info.command ;
if ( daemon_want_fit ( fit, node_ptr->hostname, "mc_info" ) == true )
{
want_fit = true ;
}
else if (( command == IPMITOOL_THREAD_CMD__POWER_STATUS ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_status" ) == true ))
{
want_fit = true ;
}
else if ( daemon_want_fit ( fit, node_ptr->hostname, "reset_cause" ) == true )
{
want_fit = true ;
}
else if (( command == IPMITOOL_THREAD_CMD__POWER_RESET ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "reset" ) == true ))
{
want_fit = true ;
}
else if (( command == IPMITOOL_THREAD_CMD__POWER_ON ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_on" ) == true ))
{
want_fit = true ;
}
else if (( command == IPMITOOL_THREAD_CMD__POWER_OFF ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_off" ) == true ))
{
want_fit = true ;
}
else if (( command == IPMITOOL_THREAD_CMD__POWER_CYCLE ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_cycle" ) == true ))
{
want_fit = true ;
}
else if (( command == IPMITOOL_THREAD_CMD__BOOTDEV_PXE ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "netboot_pxe" ) == true ))
{
want_fit = true ;
}
if ( want_fit == true )
{
slog ("%s FIT %s\n", node_ptr->hostname.c_str(), getIpmiCmd_str(command) );
node_ptr->ipmitool_thread_info.status = node_ptr->ipmitool_thread_ctrl.status = rc = FAIL_FIT ;
node_ptr->ipmitool_thread_info.status_string = "ipmi_command_send fault insertion failure" ;
return ( rc );
}
}
#endif
if (( hostUtil_is_valid_ip_addr ( node_ptr->thread_extra_info.bm_ip ) == true ) &&
( !node_ptr->thread_extra_info.bm_un.empty() ) &&
( !node_ptr->thread_extra_info.bm_pw.empty ()))
{
node_ptr->ipmitool_thread_ctrl.status = rc =
thread_launch ( node_ptr->ipmitool_thread_ctrl,
node_ptr->ipmitool_thread_info ) ;
if ( rc != PASS )
{
elog ("%s failed to launch power control thread (rc:%d)\n",
node_ptr->hostname.c_str(), rc );
}
else
{
dlog ("%s %s %s thread launched\n", node_ptr->hostname.c_str(),
node_ptr->ipmitool_thread_ctrl.name.c_str(),
getIpmiCmd_str(node_ptr->ipmitool_thread_info.command) );
}
node_ptr->ipmitool_thread_ctrl.retries = 0 ;
}
else
{
node_ptr->ipmitool_thread_ctrl.status = rc =
node_ptr->ipmitool_thread_info.status = FAIL_INVALID_DATA ;
node_ptr->ipmitool_thread_info.status_string = "one or more bmc credentials are invalid" ;
wlog ("%s %s %s %s\n", node_ptr->hostname.c_str(),
hostUtil_is_valid_ip_addr ( node_ptr->thread_extra_info.bm_ip ) ? "" : "bm_ip:invalid",
node_ptr->thread_extra_info.bm_un.empty() ? "bm_un:empty" : "",
node_ptr->thread_extra_info.bm_pw.empty() ? "bm_pw:empty" : "");
}
return (rc);
}
/*****************************************************************************
*
* Name : ipmi_command_recv
*
* Description: This utility will check for ipmitool command thread completion.
*
* Returns : PASS is returned if the thread reports done.
* RETRY is returned if the thread has not completed.
* FAIL_RETRY is returned after 10 back-to-back calls return RETRY.
*
*****************************************************************************/
int nodeLinkClass::ipmi_command_recv ( struct nodeLinkClass::node * node_ptr )
{
int rc = RETRY ;
/* check for 'thread done' completion */
if ( thread_done( node_ptr->ipmitool_thread_ctrl ) == true )
{
if (( rc = node_ptr->ipmitool_thread_info.status ) != PASS )
{
elog ("%s %s command failed (rc:%d)\n",
node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->ipmitool_thread_info.command),
rc );
}
else
{
if ( node_ptr->ipmitool_thread_info.command == IPMITOOL_THREAD_CMD__POWER_RESET )
{
if ( node_ptr->ipmitool_thread_info.data.find(IPMITOOL_POWER_RESET_RESP) == std::string::npos )
rc = FAIL_RESET_CONTROL ;
}
else if ( node_ptr->ipmitool_thread_info.command == IPMITOOL_THREAD_CMD__POWER_OFF )
{
if ( node_ptr->ipmitool_thread_info.data.find(IPMITOOL_POWER_OFF_RESP) == std::string::npos )
rc = FAIL_POWER_CONTROL ;
}
else if ( node_ptr->ipmitool_thread_info.command == IPMITOOL_THREAD_CMD__POWER_ON )
{
if ( node_ptr->ipmitool_thread_info.data.find(IPMITOOL_POWER_ON_RESP) == std::string::npos )
rc = FAIL_POWER_CONTROL ;
}
else if ( node_ptr->ipmitool_thread_info.command == IPMITOOL_THREAD_CMD__POWER_CYCLE )
{
if ( node_ptr->ipmitool_thread_info.data.find(IPMITOOL_POWER_CYCLE_RESP) == std::string::npos )
rc = FAIL_POWER_CONTROL ;
}
if ( rc )
{
node_ptr->ipmitool_thread_info.status = rc ;
node_ptr->ipmitool_thread_info.status_string = ("power command failed");
wlog ("%s %s Response: %s\n", node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->ipmitool_thread_info.command),
node_ptr->ipmitool_thread_info.data.c_str());
}
else
{
blog ("%s %s Response: %s\n", node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->ipmitool_thread_info.command),
node_ptr->ipmitool_thread_info.data.c_str());
}
}
#ifdef WANT_FIT_TESTING
if ( rc == PASS )
{
bool want_fit = false ;
int fit = FIT_CODE__IPMI_COMMAND_RECV ;
if ( daemon_want_fit ( fit, node_ptr->hostname, "mc_info" ) == true )
{
want_fit = true ;
}
else if ( daemon_want_fit ( fit, node_ptr->hostname, "reset_cause" ) == true )
{
want_fit = true ;
}
else if (( node_ptr->ipmitool_thread_info.command == IPMITOOL_THREAD_CMD__POWER_RESET ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "reset" ) == true ))
{
want_fit = true ;
}
else if (( node_ptr->ipmitool_thread_info.command == IPMITOOL_THREAD_CMD__POWER_ON ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_on" ) == true ))
{
want_fit = true ;
}
else if (( node_ptr->ipmitool_thread_info.command == IPMITOOL_THREAD_CMD__POWER_OFF ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_off" ) == true ))
{
want_fit = true ;
}
else if (( node_ptr->ipmitool_thread_info.command == IPMITOOL_THREAD_CMD__POWER_CYCLE ) &&
( daemon_want_fit ( fit, node_ptr->hostname, "power_cycle" ) == true ))
{
want_fit = true ;
}
if ( want_fit == true )
{
node_ptr->ipmitool_thread_info.status = rc = FAIL_FIT ;
node_ptr->ipmitool_thread_info.status_string = "ipmi_command_recv fault insertion failure" ;
}
}
#endif
}
/* handle max retries reached */
else if ( node_ptr->ipmitool_thread_ctrl.retries++ >= IPMITOOL_MAX_RECV_RETRIES )
{
elog ("%s %s command timeout (%d of %d)\n",
node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->ipmitool_thread_info.command),
node_ptr->ipmitool_thread_ctrl.retries,
IPMITOOL_MAX_RECV_RETRIES);
rc = FAIL_RETRY;
}
/* handle progressive retry */
else
{
if ( node_ptr->ipmitool_thread_ctrl.id == 0 )
{
slog ("%s %s command not-running\n",
node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->ipmitool_thread_info.command));
rc = FAIL_NOT_ACTIVE ;
}
else
{
ilog ("%s %s command in-progress (polling %d of %d)\n",
node_ptr->hostname.c_str(),
getIpmiCmd_str(node_ptr->ipmitool_thread_info.command),
node_ptr->ipmitool_thread_ctrl.retries,
IPMITOOL_MAX_RECV_RETRIES);
rc = RETRY ;
}
}
if ( rc != RETRY )
{
node_ptr->ipmitool_thread_ctrl.done = true ;
node_ptr->ipmitool_thread_ctrl.retries = 0 ;
node_ptr->ipmitool_thread_ctrl.id = 0 ;
node_ptr->ipmitool_thread_info.id = 0 ;
node_ptr->ipmitool_thread_info.command = 0 ;
}
return (rc);
}
/*****************************************************************************
*
* Name : ipmi_command_done
*
* Description: This utility frees the ipmitool command thread for next execution.
*
*****************************************************************************/
void nodeLinkClass::ipmi_command_done ( struct nodeLinkClass::node * node_ptr )
{
node_ptr->ipmitool_thread_ctrl.done = true ;
}

View File

@ -1,89 +0,0 @@
#ifndef __INCLUDE_MTCIPMIUTIL_H__
#define __INCLUDE_MTCIPMIUTIL_H__
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River Titanium Cloud's Maintenance IPMI Utilities Header
*/
#include "nodeBase.h" /* for ... */
#define MC_INFO_LABEL_DELIMITER ((const char *)(": "))
#define MC_INFO_LABEL_FW_VERSION ((const char *)("Firmware Revision"))
#define MC_INFO_LABEL_HW_VERSION ((const char *)("Device Revision"))
#define MC_INFO_LABEL_DEVICE_ID ((const char *)("Device ID"))
#define MC_INFO_LABEL_PRODUCT_ID ((const char *)("Product ID"))
#define MC_INFO_LABEL_PRODUCT_NAME ((const char *)("Product Name"))
#define MC_INFO_LABEL_MANUFACTURE_ID ((const char *)("Manufacturer ID"))
#define MC_INFO_LABEL_MANUFACTURE_NAME ((const char *)("Manufacturer Name"))
#define IPMITOOL_POWER_RESET_CMD ((const char *)("chassis power reset"))
#define IPMITOOL_POWER_RESET_RESP ((const char *)("Chassis Power Control: Reset"))
#define IPMITOOL_POWER_OFF_CMD ((const char *)("chassis power off"))
#define IPMITOOL_POWER_OFF_RESP ((const char *)("Chassis Power Control: Down/Off"))
#define IPMITOOL_POWER_ON_CMD ((const char *)("chassis power on"))
#define IPMITOOL_POWER_ON_RESP ((const char *)("Chassis Power Control: Up/On"))
#define IPMITOOL_POWER_CYCLE_CMD ((const char *)("chassis power cycle"))
#define IPMITOOL_POWER_CYCLE_RESP ((const char *)("Chassis Power Control: Cycle"))
#define IPMITOOL_POWER_STATUS_CMD ((const char *)("chassis power status"))
#define IPMITOOL_POWER_ON_STATUS ((const char *)("Chassis Power is on"))
#define IPMITOOL_POWER_OFF_STATUS ((const char *)("Chassis Power is off"))
#define IPMITOOL_RESTART_CAUSE_CMD ((const char *)("chassis restart_cause"))
#define IPMITOOL_MC_INFO_CMD ((const char *)("mc info"))
#define IPMITOOL_CMD_FILE_SUFFIX ((const char *)("_power_cmd_result"))
#define IPMITOOL_MC_INFO_FILE_SUFFIX ((const char *)("_mc_info"))
#define IPMITOOL_RESTART_CAUSE_FILE_SUFFIX ((const char *)("_restart_cause"))
#define IPMITOOL_POWER_STATUS_FILE_SUFFIX ((const char *)("_power_status"))
#define IPMITOOL_MAX_RECV_RETRIES (10)
/* Warning : Changes here require 'mtc_ipmiRequest_str' string array to be updated */
typedef enum
{
IPMITOOL_THREAD_CMD__NULL = 0,
IPMITOOL_THREAD_CMD__POWER_RESET,
IPMITOOL_THREAD_CMD__POWER_ON,
IPMITOOL_THREAD_CMD__POWER_OFF,
IPMITOOL_THREAD_CMD__POWER_CYCLE,
IPMITOOL_THREAD_CMD__MC_INFO,
IPMITOOL_THREAD_CMD__POWER_STATUS,
IPMITOOL_THREAD_CMD__RESTART_CAUSE,
IPMITOOL_THREAD_CMD__LAST
} ipmitool_cmd_enum ;
const char * getIpmiCmd_str ( int command );
const char * getIpmiAction_str ( int command );
typedef struct
{
std::string product_name ;
std::string product_id ;
std::string manufacturer_name ;
std::string manufacturer_id ;
std::string device_id ;
std::string fw_version ;
std::string hw_version ;
} mc_info_type ;
int ipmiUtil_mc_info_load ( string hostname, const char * filename, mc_info_type & mc_info );
void ipmiUtil_mc_info_init ( mc_info_type & mc_info );
#endif

View File

@ -54,6 +54,7 @@ using namespace std;
#include "mtcInvApi.h" /* */
#include "mtcSmgrApi.h" /* */
#include "nlEvent.h" /* for ... open_netlink_socket */
#include "bmcUtil.h" /* for ... board mgmnt utility header */
/**************************************************************
* Implementation Structure
@ -983,12 +984,6 @@ int daemon_init ( string iface, string nodetype )
return ( FAIL_DAEMON_CONFIG ) ;
}
daemon_make_dir(IPMITOOL_OUTPUT_DIR) ;
#ifdef WANT_FIT_TESTING
daemon_make_dir(FIT__INFO_FILEPATH);
#endif
return (rc);
}
@ -1097,9 +1092,6 @@ int _self_provision ( void )
// node_ptr->alarms[MTC_ALARM_ID__LOCK] = FM_ALARM_SEVERITY_CLEAR
}
// mtcInv.set_subf_info ( my_identity.name, record_info.func,
// record_info.oper_subf,
// record_info.avail_subf );
if ( my_identity.mac != record_info.mac )
{
wlog ("%s mac address mismatch (%s - %s)\n",
@ -1162,12 +1154,6 @@ int _self_provision ( void )
return (FAIL_SOCKET_INIT) ;
}
daemon_make_dir(IPMITOOL_OUTPUT_DIR) ;
#ifdef WANT_FIT_TESTING
daemon_make_dir(FIT__INFO_FILEPATH);
#endif
return(rc);
}
@ -1226,6 +1212,10 @@ void daemon_service_run ( void )
/* Init HTTP Messaging */
mtcHttpUtil_init ();
/* Init board management stuff */
bmcUtil_init ();
/* log the currect software version */
ilog ("SW VERSION : %s\n", daemon_sw_version ().c_str());
/* Collect inventory in active state only */

View File

@ -69,10 +69,10 @@ int nodeLinkClass::fsm ( struct nodeLinkClass::node * node_ptr )
}
/* Monitor and Manage active threads */
thread_handler ( node_ptr->ipmitool_thread_ctrl, node_ptr->ipmitool_thread_info );
thread_handler ( node_ptr->bmc_thread_ctrl, node_ptr->bmc_thread_info );
/* manage the host connected state and board management alarms */
nodeLinkClass::bm_handler ( node_ptr );
nodeLinkClass::bmc_handler ( node_ptr );
/* manage host's degrade state */
nodeLinkClass::degrade_handler ( node_ptr );

File diff suppressed because it is too large Load Diff

View File

@ -35,10 +35,28 @@ using namespace std;
#include "hostUtil.h" /* for ... hostUtil_mktmpfile */
#include "nodeUtil.h"
#include "threadUtil.h"
#include "ipmiUtil.h" /* for ... IPMITOOL_CMD_FILE_SUFFIX ... */
#include "mtcThreads.h" /* for ... IPMITOOL_THREAD_CMD__RESET ... */
#include "bmcUtil.h" /* for ... mtce-common bmc utility header */
void * mtcThread_ipmitool ( void * arg )
/**************************************************************************
*
* Name : mtcThread_bmc
*
* Purpose : Maintenance thread used to submit a service request to the BMC
*
* Description: The thread ...
*
* 1. determine protocol to use.
* 2. create password temp file
* 3. create output data file name
* 4. create the tool specific command request
* 5. launch blocking request
* 6. parse response against protocol used and pass back to main process
*
************************************************************************/
void * mtcThread_bmc ( void * arg )
{
thread_info_type * info_ptr ;
thread_extra_info_type * extra_ptr ;
@ -46,7 +64,7 @@ void * mtcThread_ipmitool ( void * arg )
/* Pointer Error Detection and Handling */
if ( !arg )
{
slog ("*** ipmitool thread called with null arg pointer *** corruption\n");
slog ("thread called with null arg pointer\n");
return NULL ;
}
@ -61,6 +79,7 @@ void * mtcThread_ipmitool ( void * arg )
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL );
#ifdef WANT_FIT_TESTING
if ( daemon_want_fit ( FIT_CODE__DO_NOTHING_THREAD, info_ptr->hostname ))
{
info_ptr->progress++ ;
@ -68,165 +87,361 @@ void * mtcThread_ipmitool ( void * arg )
pthread_exit (&info_ptr->status );
return NULL ;
}
#endif
/* allow the parent to confirm thread id */
info_ptr->id = pthread_self() ;
if ( extra_ptr != NULL )
{
int rc = PASS ;
unsigned int rc = PASS ;
string command = "" ;
string response = "" ;
string suffix = "" ;
string datafile = "" ;
switch ( info_ptr->command )
if ( info_ptr->proto == BMC_PROTOCOL__REDFISHTOOL )
{
/* control commands */
case IPMITOOL_THREAD_CMD__POWER_RESET:
switch ( info_ptr->command )
{
command = IPMITOOL_POWER_RESET_CMD ;
response = IPMITOOL_POWER_RESET_RESP ;
break ;
}
case IPMITOOL_THREAD_CMD__POWER_ON:
{
command = IPMITOOL_POWER_ON_CMD ;
response = IPMITOOL_POWER_ON_RESP ;
break ;
}
case IPMITOOL_THREAD_CMD__POWER_OFF:
{
command = IPMITOOL_POWER_OFF_CMD ;
response = IPMITOOL_POWER_OFF_RESP ;
break ;
}
case IPMITOOL_THREAD_CMD__POWER_CYCLE:
{
command = IPMITOOL_POWER_CYCLE_CMD ;
response = IPMITOOL_POWER_CYCLE_RESP ;
break ;
}
case IPMITOOL_THREAD_CMD__BOOTDEV_PXE:
{
command = IPMITOOL_BOOTDEV_PXE_CMD ;
response = IPMITOOL_BOOTDEV_PXE_RESP ;
break ;
}
/* state commands */
case BMC_THREAD_CMD__BMC_QUERY:
{
command = REDFISHTOOL_ROOT_QUERY_CMD ;
suffix = BMC_QUERY_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__BMC_INFO:
{
command = REDFISHTOOL_BMC_INFO_CMD ;
suffix = BMC_INFO_FILE_SUFFIX ;
break ;
}
/* Status commands */
case IPMITOOL_THREAD_CMD__POWER_STATUS:
{
command = IPMITOOL_POWER_STATUS_CMD ;
break ;
}
case IPMITOOL_THREAD_CMD__RESTART_CAUSE:
{
command = IPMITOOL_RESTART_CAUSE_CMD ;
break ;
}
case IPMITOOL_THREAD_CMD__MC_INFO:
{
command = IPMITOOL_MC_INFO_CMD ;
break ;
}
/* control commands */
case BMC_THREAD_CMD__POWER_RESET:
{
command = REDFISHTOOL_POWER_RESET_CMD ;
suffix = BMC_POWER_CMD_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__POWER_ON:
{
command = REDFISHTOOL_POWER_ON_CMD ;
suffix = BMC_POWER_CMD_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__POWER_OFF:
{
command = REDFISHTOOL_POWER_OFF_CMD ;
suffix = BMC_POWER_CMD_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__BOOTDEV_PXE:
{
/* json response */
command = REDFISHTOOL_BOOTDEV_PXE_CMD ;
suffix = BMC_BOOTDEV_CMD_FILE_SUFFIX ;
break ;
}
default:
default:
{
rc = info_ptr->status = FAIL_BAD_CASE ;
info_ptr->data = "unsupported redfishtool command: " ;
info_ptr->data.append(bmcUtil_getCmd_str(info_ptr->command).c_str());
break ;
}
}/* end redfishtool switch */
} /* end if */
else
{
switch ( info_ptr->command )
{
rc = info_ptr->status = FAIL_BAD_CASE ;
info_ptr->data = "unsupported command: " ;
info_ptr->data.append(itos(info_ptr->command));
break ;
/* control commands */
case BMC_THREAD_CMD__POWER_RESET:
{
command = IPMITOOL_POWER_RESET_CMD ;
response = IPMITOOL_POWER_RESET_RESP ;
suffix = BMC_POWER_CMD_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__POWER_ON:
{
command = IPMITOOL_POWER_ON_CMD ;
response = IPMITOOL_POWER_ON_RESP ;
suffix = BMC_POWER_CMD_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__POWER_OFF:
{
command = IPMITOOL_POWER_OFF_CMD ;
response = IPMITOOL_POWER_OFF_RESP ;
suffix = BMC_POWER_CMD_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__POWER_CYCLE:
{
command = IPMITOOL_POWER_CYCLE_CMD ;
response = IPMITOOL_POWER_CYCLE_RESP ;
suffix = BMC_POWER_CMD_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__BOOTDEV_PXE:
{
command = IPMITOOL_BOOTDEV_PXE_CMD ;
response = IPMITOOL_BOOTDEV_PXE_RESP ;
suffix = BMC_BOOTDEV_CMD_FILE_SUFFIX ;
break ;
}
/* Status commands */
case BMC_THREAD_CMD__POWER_STATUS:
{
command = IPMITOOL_POWER_STATUS_CMD ;
suffix = BMC_POWER_STATUS_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__RESTART_CAUSE:
{
command = IPMITOOL_RESTART_CAUSE_CMD ;
suffix = BMC_RESTART_CAUSE_FILE_SUFFIX ;
break ;
}
case BMC_THREAD_CMD__BMC_INFO:
{
command = IPMITOOL_BMC_INFO_CMD ;
suffix = BMC_INFO_FILE_SUFFIX ;
break ;
}
default:
{
rc = info_ptr->status = FAIL_BAD_CASE ;
info_ptr->data = "unsupported ipmitool command: " ;
info_ptr->data.append(bmcUtil_getCmd_str(info_ptr->command).c_str());
break ;
}
} /* end ipmitool switch */
} /* end else */
if ( rc != PASS )
{
if ( info_ptr->status_string.empty() )
{
info_ptr->status_string = "failure ; see logs";
}
if ( info_ptr->status == PASS )
{
info_ptr->status = rc ;
}
goto bmc_thread_done ;
}
if ( rc == PASS )
else if ( info_ptr->proto == BMC_PROTOCOL__REDFISHTOOL )
{
bool bypass_ipmitool_request = false ;
dlog_t ("%s '%s' command\n", info_ptr->log_prefix, command.c_str());
/* create the password file */
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,
extra_ptr->bm_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 ;
goto ipmitool_thread_done ;
}
if ( info_ptr->pw_file_fd > 0)
close (info_ptr->pw_file_fd);
info_ptr->pw_file_fd = 0 ;
/*************** create the password file ***************/
/* password file contains username and password in format
*
* {"username":"<username>","password":"<password>"}
*
*/
string config_file_content = "{\"username\":\"" ;
config_file_content.append(extra_ptr->bm_un);
config_file_content.append("\",\"password\":\"");
config_file_content.append(extra_ptr->bm_pw);
config_file_content.append("\"}");
bmcUtil_create_pw_file ( info_ptr,
config_file_content,
BMC_PROTOCOL__REDFISHTOOL);
if ( info_ptr->password_file.empty() )
{
info_ptr->status_string = "failed to get a temporary password filename" ;
info_ptr->status = FAIL_FILE_CREATE ;
goto ipmitool_thread_done ;
goto bmc_thread_done ;
}
dlog_t ("%s password file: %s\n", info_ptr->log_prefix, info_ptr->password_file.c_str());
/* *********** create the output filename ****************/
datafile = bmcUtil_create_data_fn ( info_ptr->hostname,
suffix,
BMC_PROTOCOL__REDFISHTOOL );
/* create the output filename */
string ipmitool_datafile = IPMITOOL_OUTPUT_DIR ;
ipmitool_datafile.append(info_ptr->hostname);
dlog_t ("%s datafile:%s\n",
info_ptr->hostname.c_str(),
datafile.c_str());
if ( info_ptr->command == IPMITOOL_THREAD_CMD__MC_INFO )
{
ipmitool_datafile.append(IPMITOOL_MC_INFO_FILE_SUFFIX);
}
else if ( info_ptr->command == IPMITOOL_THREAD_CMD__RESTART_CAUSE )
{
ipmitool_datafile.append(IPMITOOL_RESTART_CAUSE_FILE_SUFFIX);
}
else if ( info_ptr->command == IPMITOOL_THREAD_CMD__POWER_STATUS )
{
ipmitool_datafile.append(IPMITOOL_POWER_STATUS_FILE_SUFFIX);
}
else
{
ipmitool_datafile.append(IPMITOOL_CMD_FILE_SUFFIX);
}
dlog_t ("%s datafile:%s\n", info_ptr->hostname.c_str(), ipmitool_datafile.c_str());
/************** Create the ipmitool request **************/
string ipmitool_request =
ipmiUtil_create_request ( command,
extra_ptr->bm_ip,
extra_ptr->bm_un,
info_ptr->password_file,
ipmitool_datafile );
/************** Create the redfishtool request **************/
string request =
redfishUtil_create_request (command,
extra_ptr->bm_ip,
info_ptr->password_file,
datafile);
blog1_t ("%s %s", info_ptr->hostname.c_str(), request.c_str());
#ifdef WANT_FIT_TESTING
bool bypass_request = false ;
if ( daemon_is_file_present ( MTC_CMD_FIT__DIR ) == true )
{
if (( command == IPMITOOL_MC_INFO_CMD ) &&
if (( command == REDFISHTOOL_ROOT_QUERY_CMD ) &&
( daemon_is_file_present ( MTC_CMD_FIT__ROOT_QUERY )))
{
bypass_request = true ;
rc = PASS ;
}
if (( command == REDFISHTOOL_BMC_INFO_CMD ) &&
( daemon_is_file_present ( MTC_CMD_FIT__MC_INFO )))
{
bypass_ipmitool_request = true ;
bypass_request = true ;
rc = PASS ;
}
}
if ( bypass_request )
;
else
#endif
{
daemon_remove_file ( datafile.data() ) ;
nodeUtil_latency_log ( info_ptr->hostname, NODEUTIL_LATENCY_MON_START, 0 );
rc = system ( request.data()) ;
if ( rc != PASS )
{
if ( info_ptr->command != BMC_THREAD_CMD__BMC_QUERY )
{
elog_t ("%s redfishtool system call failed (%s) (%d:%d:%m)\n",
info_ptr->hostname.c_str(),
request.c_str(),
rc, errno );
}
info_ptr->status = FAIL_SYSTEM_CALL ;
if ( daemon_is_file_present ( datafile.data() ))
{
/* load in the error. stdio is redirected to the datafile */
info_ptr->status_string = daemon_read_file(datafile.data());
}
}
nodeUtil_latency_log ( info_ptr->hostname, "redfishtool system call", 1000 );
}
#ifdef WANT_FIT_TESTING
if ( daemon_want_fit ( FIT_CODE__THREAD_TIMEOUT, info_ptr->hostname ) )
{
for ( ; ; )
{
sleep (1) ;
pthread_signal_handler ( info_ptr );
}
}
if ( daemon_want_fit ( FIT_CODE__THREAD_SEGFAULT, info_ptr->hostname ) )
{
daemon_do_segfault();
}
#endif
/* clean-up */
if ( info_ptr->pw_file_fd > 0 )
close(info_ptr->pw_file_fd);
info_ptr->pw_file_fd = 0 ;
unlink(info_ptr->password_file.data());
daemon_remove_file ( info_ptr->password_file.data() ) ;
info_ptr->password_file.clear();
if ( rc != PASS )
{
info_ptr->status_string = "failed redfishtool command : " ;
info_ptr->status_string.append(bmcUtil_getCmd_str(info_ptr->command));
info_ptr->status = FAIL_SYSTEM_CALL ;
#ifdef WANT_PW_FILE_LOG
if ( request.length () )
{
string _temp = request ;
size_t pos1 = _temp.find ("-f", 0) ;
size_t pos2 = _temp.find (" > ", 0) ;
if (( pos1 != std::string::npos ) && ( pos2 != std::string::npos ))
{
/* don't log the password filename */
wlog_t ("%s ... %s%s\n",
info_ptr->hostname.c_str(),
_temp.substr(0,pos1).c_str(),
_temp.substr(pos2).c_str());
}
else
{
wlog_t ("%s ... %s\n",
info_ptr->hostname.c_str(),
request.c_str());
}
}
#endif
}
}
else if ( info_ptr->proto == BMC_PROTOCOL__IPMITOOL )
{
dlog_t ("%s '%s' command\n", info_ptr->log_prefix, command.c_str());
/*************** create the password file ***************/
bmcUtil_create_pw_file ( info_ptr,
extra_ptr->bm_pw,
BMC_PROTOCOL__IPMITOOL);
if ( info_ptr->password_file.empty() )
{
info_ptr->status_string = "failed to get a temporary password filename" ;
info_ptr->status = FAIL_FILE_CREATE ;
goto bmc_thread_done ;
}
dlog_t ("%s password file: %s\n", info_ptr->log_prefix, info_ptr->password_file.c_str());
/* *********** create the output filename ****************/
datafile = bmcUtil_create_data_fn ( info_ptr->hostname,
suffix,
BMC_PROTOCOL__IPMITOOL );
dlog_t ("%s datafile:%s\n",
info_ptr->hostname.c_str(),
datafile.c_str());
/************** Create the ipmitool request **************/
string request = ipmiUtil_create_request ( command,
extra_ptr->bm_ip,
extra_ptr->bm_un,
info_ptr->password_file,
datafile );
dlog_t ("%s %s", info_ptr->hostname.c_str(), request.c_str());
/* assume pass */
info_ptr->status_string = "pass" ;
info_ptr->status = rc = PASS ;
#ifdef WANT_FIT_TESTING
bool bypass_request = false ;
if ( daemon_is_file_present ( MTC_CMD_FIT__DIR ) == true )
{
if (( command == IPMITOOL_BMC_INFO_CMD ) &&
( daemon_is_file_present ( MTC_CMD_FIT__MC_INFO )))
{
bypass_request = true ;
rc = PASS ;
}
else if (( command == IPMITOOL_POWER_STATUS_CMD ) &&
( daemon_is_file_present ( MTC_CMD_FIT__POWER_STATUS )))
{
bypass_ipmitool_request = true ;
bypass_request = true ;
rc = PASS ;
}
else if (( command == IPMITOOL_RESTART_CAUSE_CMD ) &&
( daemon_is_file_present ( MTC_CMD_FIT__RESTART_CAUSE )))
{
bypass_ipmitool_request = true ;
bypass_request = true ;
rc = PASS ;
}
else if ((( command == IPMITOOL_POWER_RESET_CMD ) ||
@ -237,31 +452,31 @@ void * mtcThread_ipmitool ( void * arg )
( daemon_is_file_present ( MTC_CMD_FIT__POWER_CMD )))
{
slog("%s FIT Bypass power or bootdev command", info_ptr->hostname.c_str());
bypass_ipmitool_request = true ;
bypass_request = true ;
rc = PASS ;
}
else if ( daemon_want_fit ( FIT_CODE__AVOID_N_FAIL_IPMITOOL_REQUEST, info_ptr->hostname ))
{
slog ("%s FIT FIT_CODE__AVOID_N_FAIL_IPMITOOL_REQUEST\n", info_ptr->hostname.c_str());
bypass_ipmitool_request = true ;
bypass_request = true ;
rc = FAIL_FIT ;
}
else if ( daemon_want_fit ( FIT_CODE__STRESS_THREAD, info_ptr->hostname ))
{
slog ("%s FIT FIT_CODE__STRESS_THREAD\n", info_ptr->hostname.c_str());
bypass_ipmitool_request = true ;
bypass_request = true ;
rc = PASS ;
}
}
dlog_t ("%s %s", info_ptr->hostname.c_str(), ipmitool_request.c_str()); /* ERIC */
if ( ! bypass_ipmitool_request )
if ( bypass_request )
;
else
#endif
{
daemon_remove_file ( ipmitool_datafile.data() ) ;
daemon_remove_file ( datafile.data() ) ;
nodeUtil_latency_log ( info_ptr->hostname, NODEUTIL_LATENCY_MON_START, 0 );
rc = system ( ipmitool_request.data()) ;
rc = system ( request.data()) ;
if ( rc != PASS )
{
wlog_t ("%s ipmitool system call failed (%d:%d:%m)\n", info_ptr->hostname.c_str(), rc, errno );
@ -294,13 +509,15 @@ void * mtcThread_ipmitool ( void * arg )
if ( rc != PASS )
{
info_ptr->status_string = "failed ipmitool command : " ;
info_ptr->status_string.append(getIpmiCmd_str(info_ptr->command));
info_ptr->status_string.append(bmcUtil_getCmd_str((bmc_cmd_enum)info_ptr->command));
info_ptr->status = FAIL_SYSTEM_CALL ;
if ( ipmitool_request.length () )
#ifdef WANT_PW_FILE_LOG
if ( request.length () )
{
string _temp = ipmitool_request ;
string _temp = request ;
size_t pos1 = _temp.find ("-f", 0) ;
size_t pos2 = _temp.find (" > ", 0) ;
@ -316,59 +533,60 @@ void * mtcThread_ipmitool ( void * arg )
{
wlog_t ("%s ... %s\n",
info_ptr->hostname.c_str(),
ipmitool_request.c_str());
request.c_str());
}
}
#endif
}
}
if ( rc == PASS )
{
bool datafile_present = false ;
/* look for the output data file */
for ( int i = 0 ; i < 10 ; i++ )
{
pthread_signal_handler ( info_ptr );
if ( daemon_is_file_present ( datafile.data() ))
{
datafile_present = true ;
break ;
}
info_ptr->progress++ ;
sleep (1);
}
if ( datafile_present )
{
if ( info_ptr->command == BMC_THREAD_CMD__BMC_INFO )
{
/* tell the main process the name of the file containing the mc info data */
info_ptr->data = datafile ;
}
else
{
info_ptr->data = daemon_read_file (datafile.data()) ;
}
}
else
{
bool ipmitool_datafile_present = false ;
/* look for the output data file */
for ( int i = 0 ; i < 10 ; i++ )
{
pthread_signal_handler ( info_ptr );
if ( daemon_is_file_present ( ipmitool_datafile.data() ))
{
ipmitool_datafile_present = true ;
break ;
}
info_ptr->progress++ ;
sleep (1);
}
if ( ipmitool_datafile_present )
{
if ( info_ptr->command == IPMITOOL_THREAD_CMD__MC_INFO )
{
/* tell the main process the name of the file containing the mc info data */
info_ptr->data = ipmitool_datafile ;
info_ptr->status_string = "pass" ;
info_ptr->status = PASS ;
}
else
{
info_ptr->data = daemon_read_file (ipmitool_datafile.data()) ;
info_ptr->status_string = "pass" ;
info_ptr->status = PASS ;
}
}
else
{
info_ptr->status_string = "command did not produce output file ; timeout" ;
info_ptr->status = FAIL_FILE_ACCESS ;
}
info_ptr->status_string = "command did not produce output file ; timeout" ;
info_ptr->status = FAIL_FILE_ACCESS ;
}
}
else
{
info_ptr->status_string = "system call failed" ;
info_ptr->status = FAIL_SYSTEM_CALL ;
}
}
else
{
info_ptr->status_string = "null 'extra info' pointer" ;
info_ptr->status = FAIL_NULL_POINTER ;
goto ipmitool_thread_done ;
}
ipmitool_thread_done:
bmc_thread_done:
if ( info_ptr->pw_file_fd > 0)
close (info_ptr->pw_file_fd);

View File

@ -23,7 +23,7 @@ typedef struct
} thread_extra_info_type ;
void * mtcThread_ipmitool ( void * );
void * mtcThread_ipmitool_test ( void * arg );
void * mtcThread_bmc ( void * );
void * mtcThread_bmc_test ( void * arg );
#endif // __INCLUDE_MTCTHREAD_HH__