From db0b4ccaddb8418bc85defdadd03c0a1bca0ea7c Mon Sep 17 00:00:00 2001 From: Eric MacDonald Date: Wed, 5 Oct 2022 15:58:16 +0000 Subject: [PATCH] Debian: Redfishtool requests fail when IPV4 address has square brackets Redfishtool was introduced in CentOS for maintenance power control and sensor monitoring. Both IPV4 and IPV6 addressing is supported. The initial integration exposed an issue where square brackets were required around the BMC IP address for IPV6 addressing. At the time it was simpler to add the brackets for IPV4 as well. redfishtool -S Always -T 30 -r [${BM_IP}] root However, the python3 version of redfishtool, introduced in Debian, rejects requests with square braces around IPV4 addresses. redfishtool -v -S Always -T 20 -r [${BM_IP}] root # Main: Error: rc=5 This update introduces a utility to the mtce msgClass module used to distinguish between IPV4 and IPV6 addresses. The redfish request create utility is updated to use this new utility when creating the redfishtool request without adding the square brackets in Debian for BMC's provisioned with IPV4 addressing. Update testing revealed that the Debian based python3 version of redfishtool takes a few seconds longer compared to the python2 in CentOS. This exposes a timer race condition during sensor monitoring. The BMC pthread is currently given 60 seconds to complete its requests. However, unlike sensor monitoring using ipmi which uses one request, redfish requires two requests. Unfortunately, requests using the Debian python3 version of redfishtool sometimes take longer than 30 seconds. If the cumulation of both requests take longer than the current max timeout of 60 seconds then that is treated as a pthread timeout error condition causing the hardware monitor to enter an error state for that host which requires it to go through a full reconnection algorithm. Given this additional issue this update also increases the BMC thread timeout from 60 to 100 seconds to avoid needless reconnections when using the mildly slower Debian python3 redfishtool. Test Plan: PASS: Verify Build Debian and CentOS iso images PASS: Verify Patch CentOS change PASS: Verify Install Debian image For both Debian and CentOS PASS: Verify redfish sensor monitoring over IPV4 PASS: Verify ipmi sensor monitoring over IPV4 PASS: Verify redfish sensor monitoring over IPV6 PASS: Verify ipmi sensor monitoring over IPV6 PASS: Verify no redfish connection failure/recovery errors; 3 hr soak Regression: PASS: Verify sensor model relearn by command and reprovision PASS: Verify system host-modify bm_type change handling PASS: Verify redfish critical sensor assert/clear handling PASS: Verify ipmi critical sensor assert/clear handling PASS: Verify mtcAgent and hwmond logging Closes-Bug: 1991819 Signed-off-by: Eric MacDonald Change-Id: I3b69cc4f19c580687cd91b4f2033f6019be87e5e --- mtce-common/src/common/msgClass.cpp | 48 ++++++++++++++++++++++++++ mtce-common/src/common/msgClass.h | 3 ++ mtce-common/src/common/redfishUtil.cpp | 20 ++++++++--- mtce-common/src/common/threadUtil.h | 2 +- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/mtce-common/src/common/msgClass.cpp b/mtce-common/src/common/msgClass.cpp index b11201f8..ff967a40 100644 --- a/mtce-common/src/common/msgClass.cpp +++ b/mtce-common/src/common/msgClass.cpp @@ -1129,3 +1129,51 @@ int msgClassTx::initSocket() } return PASS; } + +/** + * Used to validate and distinguish between IPV4 and IPV6 addresses. + * + * @return PF_UNSPEC for unknown IP address format + * AF_INET for IPV4 addresses + * AF_INET6 for IPV6 addresses + */ +int get_address_ai_family ( const char * addr_ptr ) +{ + if ( addr_ptr == NULL ) + { + slog ("null string pointer"); + return ( PF_UNSPEC ); + } + + struct addrinfo *res = NULL; + struct addrinfo hint ; + MEMSET_ZERO ( hint); + + hint.ai_family = PF_UNSPEC; + hint.ai_flags = AI_NUMERICHOST; + + if ( getaddrinfo(addr_ptr, NULL, &hint, &res) ) + { + wlog ("Invalid address: %s", addr_ptr ); + return ( PF_UNSPEC ); + } + + int ai_family = res->ai_family ; + freeaddrinfo(res); + + if ( ai_family == AF_INET ) + { + dlog1 ("%s is an ipv4 address\n", addr_ptr ); + } + else if ( ai_family == AF_INET6 ) + { + dlog1 ("%s is an ipv6 address\n", addr_ptr ); + } + else + { + slog ("unknown address format: %s ; ai_family:%d\n", + addr_ptr, ai_family ); + ai_family = PF_UNSPEC ; + } + return (ai_family) ; +} diff --git a/mtce-common/src/common/msgClass.h b/mtce-common/src/common/msgClass.h index abcc88a7..e35fdc4c 100644 --- a/mtce-common/src/common/msgClass.h +++ b/mtce-common/src/common/msgClass.h @@ -213,4 +213,7 @@ private: int initSocket(); }; +/* Used to validate and distinguish between IPV4 and IPV6 addresses */ +int get_address_ai_family ( const char * addr_ptr ); + #endif /* __INCLUDE_MSGCLASS_H__ */ diff --git a/mtce-common/src/common/redfishUtil.cpp b/mtce-common/src/common/redfishUtil.cpp index 4ceb33e5..5bdfd758 100644 --- a/mtce-common/src/common/redfishUtil.cpp +++ b/mtce-common/src/common/redfishUtil.cpp @@ -16,6 +16,7 @@ using namespace std; #include "nodeBase.h" /* for ... mtce node common definitions */ +#include "msgClass.h" /* for ... get_address_ai_family */ #include "nodeUtil.h" /* for ... tolowercase */ #include "hostUtil.h" /* for ... mtce host common definitions */ #include "jsonUtil.h" /* for ... */ @@ -353,10 +354,21 @@ string redfishUtil_create_request ( string cmd, * defaulting to 20 sec timeout */ command_request.append(" -T 30"); - /* specify the bmc ip address */ - command_request.append(" -r ["); - command_request.append(ip); - command_request.append("]"); + /* The square brackets around the ip address in Debian + * cause the redfishtool request to fail */ + if ( daemon_is_os_debian() && get_address_ai_family(ip.data()) == AF_INET ) + { + /* add the bmc ip address option */ + command_request.append(" -r "); + command_request.append(ip); + } + else + { + /* specify the bmc ip address option with square brackets */ + command_request.append(" -r ["); + command_request.append(ip); + command_request.append("]"); + } #ifdef WANT_INLINE_CREDS if ( daemon_is_file_present ( MTC_CMD_FIT__INLINE_CREDS ) ) diff --git a/mtce-common/src/common/threadUtil.h b/mtce-common/src/common/threadUtil.h index 2cbabe41..b2558fd3 100644 --- a/mtce-common/src/common/threadUtil.h +++ b/mtce-common/src/common/threadUtil.h @@ -160,7 +160,7 @@ using namespace std; #define THREAD_INIT_SIG (0xbabef00d) #define MAX_PTHREADS (1) /* max number concurrent pthreads */ -#define DEFAULT_THREAD_TIMEOUT_SECS (60) /* default pthread exec timout */ +#define DEFAULT_THREAD_TIMEOUT_SECS (100) /* default pthread exec timout */ #define MAX_LOG_PREFIX_LEN (MAX_CHARS_ON_LINE) #define THREAD_POST_KILL_WAIT (10) /* wait time between KILL and IDLE */