// // Created by xajhu on 2021/7/8 0008. // #include #include #include #include #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; }