vcpe/srcs/libs/hardware/ipmltools.c

186 lines
5.6 KiB
C

//
// Created by xajhu on 2021/7/8 0008.
//
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
#include <sds/sds.h>
#include "hardware.h"
#include "user_errno.h"
#include "uthash/uthash.h"
#include "misc.h"
#include "config.h"
#define MAX_SENSOR_STR (32)
//#define CMD_SENSOR_INFO ("ipmitool sensor | awk '{gsub(/\|/, \"\"); print $0}'")
#define CMD_SENSOR_INFO ("ipmitool sensor")
#define CMD_IPMITOOL_ENABLE ("whereis ipmitool | awk '{print $2}'")
typedef struct {
char name[MAX_SENSOR_STR]; ///< 传感器名称
char valUnit[MAX_SENSOR_STR]; ///< 传感器值单位
char value[MAX_SENSOR_STR]; ///< 传感器值, >=0: 正常值, <0: 错误码
char lnr[MAX_SENSOR_STR]; ///< Lower Non-Recoverable
char lc[MAX_SENSOR_STR]; ///< Lower Critical
char lnc[MAX_SENSOR_STR]; ///< Lower Non-Critical
char unc[MAX_SENSOR_STR]; ///< Upper Non-Critical
char uc[MAX_SENSOR_STR]; ///< Upper Critical
char unr[MAX_SENSOR_STR]; ///< Upper Non-Critical
char status[MAX_SENSOR_STR]; ///< 设备状态 0: failed, 1: Ok, and other
unsigned long timestamp; ///< 更新时间戳
UT_hash_handle hh;
} IPMI_SENSOR_INFO, *PIPMI_SENSOR_INFO;
static const char *g_ipmiDev[] = {"/dev/ipmi0", "/dev/ipmi/0", "/dev/ipmidev/0"};
static uv_rwlock_t g_uvLock;
static PIPMI_SENSOR_INFO g_pSensorInfo = NULL;
static int sensor_info_refresh() {
int i = 0;
int errCode = ERR_SUCCESS;
FILE *fp;
char buf[1024];
char *pRet = NULL;
if (shell_with_output(CMD_IPMITOOL_ENABLE, &pRet) != ERR_SUCCESS || pRet == NULL || strlen(pRet) == 0) {
if (pRet) {
free(pRet);
}
return -ERR_ITEM_UNEXISTS;
}
fp = popen(CMD_SENSOR_INFO, "r");
if (fp == NULL) {
return -ERR_OPEN_FILE;
}
while (fgets(buf, 1024, fp) != NULL && i < MAX_SENSOR_ITEMS) {
int nItems;
sds tmpStr = sdsnew(buf);
sds *pToken = sdssplitlen(tmpStr, (int)sdslen(tmpStr), "|", 1, &nItems);
if (nItems == 10) {
PIPMI_SENSOR_INFO pTmp = NULL;
sdstrim(pToken[0], " \n");
sdstrim(pToken[1], " \n");
sdstrim(pToken[2], " \n");
sdstrim(pToken[3], " \n");
sdstrim(pToken[4], " \n");
sdstrim(pToken[5], " \n");
sdstrim(pToken[6], " \n");
sdstrim(pToken[7], " \n");
sdstrim(pToken[8], " \n");
sdstrim(pToken[9], " \n");
HASH_FIND_STR(g_pSensorInfo, pToken[0], pTmp);
if (pTmp) {
uv_rwlock_wrlock(&g_uvLock);
strcpy(pTmp->value, pToken[1]);
strcpy(pTmp->valUnit, pToken[2]);
strcpy(pTmp->status, pToken[3]);
pTmp->timestamp = time(NULL);
uv_rwlock_wrunlock(&g_uvLock);
} else {
pTmp = (PIPMI_SENSOR_INFO)malloc(sizeof(IPMI_SENSOR_INFO));
if (pTmp) {
uv_rwlock_wrlock(&g_uvLock);
strcpy(pTmp->name, pToken[0]);
strcpy(pTmp->value, pToken[1]);
strcpy(pTmp->valUnit, pToken[2]);
strcpy(pTmp->status, pToken[3]);
strcpy(pTmp->lnr, pToken[4]);
strcpy(pTmp->lc, pToken[5]);
strcpy(pTmp->lnc, pToken[6]);
strcpy(pTmp->unc, pToken[7]);
strcpy(pTmp->uc, pToken[8]);
strcpy(pTmp->unr, pToken[9]);
HASH_ADD_STR(g_pSensorInfo, name, pTmp);
uv_rwlock_wrunlock(&g_uvLock);
} else {
errCode = -ERR_MALLOC_MEMORY;
}
}
i++;
#if 0
printf("name: [%s]\n", pTmp->name);
printf("value: [%s]\n", pTmp->value);
printf("valUnit: [%s]\n", pTmp->valUnit);
printf("status: [%s]\n", pTmp->status);
printf("lnr: [%s]\n", pTmp->lnr);
printf("lc: [%s]\n", pTmp->lc);
printf("lnc: [%s]\n", pTmp->lnc);
printf("unc: [%s]\n", pTmp->unc);
printf("uc: [%s]\n", pTmp->uc);
printf("unr: [%s]\n\n\n", pTmp->unr);
#endif
}
sdsfreesplitres(pToken, nItems);
sdsfree(tmpStr);
memset(buf, 0, sizeof(buf));
}
pclose(fp);
return errCode;
}
int get_sensor_info(PSENSOR_INFO pInfo) {
PIPMI_SENSOR_INFO pItem, pTmp;
PSENSOR_ITEM pSensor;
if (pInfo == NULL) {
return -ERR_INPUT_PARAMS;
}
if (cfg_get_watch_sensor()) {
sensor_info_refresh();
}
uv_rwlock_rdlock(&g_uvLock);
pInfo->nItems = HASH_COUNT(g_pSensorInfo);
pInfo->timestamp = time(NULL);
pSensor = pInfo->sensorInfo;
HASH_ITER(hh, g_pSensorInfo, pItem, pTmp) {
pSensor->sensorName = pItem->name;
pSensor->value = pItem->value;
pSensor->unit = pItem->valUnit;
pSensor->status = pItem->status;
pSensor++;
}
uv_rwlock_rdunlock(&g_uvLock);
return ERR_SUCCESS;
}
int sensor_watch_init() {
int i, devOk = FALSE;
int n = ARRAY_SIZE(g_ipmiDev);
uv_rwlock_init(&g_uvLock);
for (i = 0; i < n; i++) {
if (file_exists(g_ipmiDev[i])) {
devOk = TRUE;
break;
}
}
if (!devOk) {
return -ERR_SYS_IPMI_UNSUP;
}
if (sensor_info_refresh() != ERR_SUCCESS) {
return -ERR_SYS_SENSOR_GET_INFO;
}
return ERR_SUCCESS;
}