194 lines
5.7 KiB
C
194 lines
5.7 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")
|
|
|
|
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];
|
|
|
|
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;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
_Noreturn void sensorRefreshCb(void *UNUSED(pArg)) {
|
|
do {
|
|
unsigned int period = cfg_get_sensor_refresh_period();
|
|
|
|
if (cfg_get_watch_sensor()) {
|
|
sensor_info_refresh();
|
|
}
|
|
|
|
if (period < REFRESH_MAX_PERIOD && period >= 1) {
|
|
uv_sleep(1000 * period);
|
|
} else {
|
|
uv_sleep(1000);
|
|
}
|
|
} while (TRUE);
|
|
}
|
|
|
|
int sensor_watch_init() {
|
|
|
|
static uv_thread_t uvThread;
|
|
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;
|
|
}
|
|
|
|
uv_thread_create(&uvThread, sensorRefreshCb, NULL);
|
|
|
|
return ERR_SUCCESS;
|
|
} |