Skip to content

Commit f792544

Browse files
committed
Report all DIMMs LastShutdownStatus when ADR failure is detected
Signed-off-by: Tomasz Gromadzki <tomasz.gromadzki@hpe.com>
1 parent 6805ed4 commit f792544

1 file changed

Lines changed: 98 additions & 0 deletions

File tree

src/common/set.c

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2776,6 +2776,103 @@ util_unmap_all_hdrs(struct pool_set *set)
27762776
}
27772777
}
27782778

2779+
/*
2780+
* util_ipmctl_log_dimm_shutdown_status -- query ipmctl for every DIMM's last
2781+
* shutdown time and shutdown status (both latched and unlatched) and report
2782+
* the output of each command via CORE_LOG_ERROR.
2783+
*
2784+
* Steps:
2785+
* 1. Run "ipmctl show -display DimmID -dimm" and collect all DimmID values
2786+
* from lines of the form ---DimmID=0x0001---.
2787+
* 2. For every discovered DimmID run three ipmctl queries and emit one
2788+
* CORE_LOG_ERROR entry per query containing the raw command output.
2789+
*/
2790+
static void
2791+
util_ipmctl_log_dimm_shutdown_status(void)
2792+
{
2793+
/*
2794+
* Collect DimmID strings from "ipmctl show -display DimmID -dimm".
2795+
* A DimmID is always 6 characters (e.g. 0x0001) + NUL = 7 bytes.
2796+
*/
2797+
#define IPMCTL_MAX_DIMMS 64
2798+
#define IPMCTL_DIMMID_LEN 7 /* "0x0001" + NUL */
2799+
#define IPMCTL_CMD_LEN 128
2800+
#define IPMCTL_OUTPUT_LEN 1024
2801+
2802+
char dimm_ids[IPMCTL_MAX_DIMMS][IPMCTL_DIMMID_LEN];
2803+
int ndimms = 0;
2804+
2805+
FILE *fp = popen("ipmctl show -display DimmID -dimm", "r");
2806+
if (fp == NULL) {
2807+
CORE_LOG_ERROR_W_ERRNO(
2808+
"popen failed: ipmctl show -display DimmID -dimm");
2809+
return;
2810+
}
2811+
2812+
char line[256];
2813+
while (fgets(line, sizeof(line), fp) != NULL) {
2814+
char id[IPMCTL_DIMMID_LEN];
2815+
/* match lines of the form ---DimmID=0x0001--- */
2816+
if (sscanf(line, "---DimmID=%6[^-]---", id) == 1) {
2817+
if (ndimms < IPMCTL_MAX_DIMMS) {
2818+
memcpy(dimm_ids[ndimms], id, IPMCTL_DIMMID_LEN);
2819+
ndimms++;
2820+
} else {
2821+
CORE_LOG_ERROR(
2822+
"ipmctl DIMM count exceeds limit (%d); "
2823+
"remaining DIMMs skipped",
2824+
IPMCTL_MAX_DIMMS);
2825+
break;
2826+
}
2827+
}
2828+
}
2829+
pclose(fp);
2830+
2831+
/* Three queries to run per DIMM, in order */
2832+
static const char * const queries[] = {
2833+
"LastShutdownTime",
2834+
"UnlatchedLastShutdownStatus",
2835+
"LatchedLastShutdownStatus",
2836+
};
2837+
2838+
for (int i = 0; i < ndimms; i++) {
2839+
for (size_t q = 0; q < ARRAY_SIZE(queries); q++) {
2840+
char cmd[IPMCTL_CMD_LEN];
2841+
snprintf(cmd, sizeof(cmd),
2842+
"ipmctl show -display %s -dimm %s",
2843+
queries[q], dimm_ids[i]);
2844+
2845+
FILE *qfp = popen(cmd, "r");
2846+
if (qfp == NULL) {
2847+
CORE_LOG_ERROR_W_ERRNO(
2848+
"popen failed: %s", cmd);
2849+
continue;
2850+
}
2851+
2852+
char output[IPMCTL_OUTPUT_LEN];
2853+
if (fgets(output, sizeof(output), qfp) == NULL)
2854+
output[0] = '\0';
2855+
2856+
/* strip trailing newline */
2857+
size_t off = strlen(output);
2858+
while (off > 0 &&
2859+
(output[off - 1] == '\n' ||
2860+
output[off - 1] == '\r')) {
2861+
output[--off] = '\0';
2862+
}
2863+
2864+
pclose(qfp);
2865+
2866+
CORE_LOG_ERROR("DimmID=%s: %s", dimm_ids[i], output);
2867+
}
2868+
}
2869+
2870+
#undef IPMCTL_MAX_DIMMS
2871+
#undef IPMCTL_DIMMID_LEN
2872+
#undef IPMCTL_CMD_LEN
2873+
#undef IPMCTL_OUTPUT_LEN
2874+
}
2875+
27792876
/*
27802877
* util_replica_check -- check headers, check UUID's, check replicas linkage
27812878
*/
@@ -2833,6 +2930,7 @@ util_replica_check(struct pool_set *set, const struct pool_attr *attr)
28332930
if (shutdown_state_check(&sds, &HDR(rep, 0)->sds,
28342931
rep)) {
28352932
CORE_LOG_ERROR("ADR failure detected");
2933+
util_ipmctl_log_dimm_shutdown_status();
28362934
errno = EINVAL;
28372935
return -1;
28382936
}

0 commit comments

Comments
 (0)