Skip to content
Snippets Groups Projects
Commit b814d3e0 authored by Adam Wujek's avatar Adam Wujek :speech_balloon:
Browse files

userspace/snmpd: add boot count objects to wrsBootStatusGroup


objects added:
--wrsBootCnt (read from /proc/wrs-bootcount)
--wrsRebootCnt (read from /proc/wrs-bootcount)
--wrsRestartReason (read from CPU's register)
--wrsFaultIP (not implemented in kernel)
--wrsFaultLR (not implemented in kernel)

Signed-off-by: default avatarAdam Wujek <adam.wujek@cern.ch>
parent d8725cb3
No related merge requests found
......@@ -206,21 +206,66 @@ wrsDateTAIString OBJECT-TYPE
--wrsBootStatusGroup (.7.1.2)
wrsBootStatusGroup OBJECT IDENTIFIER ::= { wrsOperationStatus 2 }
--wrsBootCnt OBJECT-TYPE
-- SYNTAX Counter32
-- MAX-ACCESS read-only
-- STATUS current
-- DESCRIPTION
-- "Number of switch's boots"
-- ::= { wrsBootStatusGroup 1 }
--wrsRestartReason OBJECT-TYPE
-- SYNTAX Integer32
-- MAX-ACCESS read-only
-- STATUS current
-- DESCRIPTION
-- "Reason of last switch restart"
-- ::= { wrsBootStatusGroup 3 }
wrsBootCnt OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Number of switch's boots since power-on"
::= { wrsBootStatusGroup 1 }
wrsRebootCnt OBJECT-TYPE
SYNTAX Counter32
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The number of soft reboots. This is incremented by the
reboot system call. A healthy system should feature one
soft-reboot less than total boots."
::= { wrsBootStatusGroup 2 }
wrsRestartReason OBJECT-TYPE
SYNTAX INTEGER {
na(0),
error(1),
generalReset(2),
wakeUpReset(3),
watchdogReset(4),
softwareReset(5),
userReset(6)
}
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"Reason of last switch restart.
error(1) - unable to read restart reason or reset counters
generalReset(2) - Both VDDCORE and VDDBU rising (power-on)
wakeUpReset(3) - VDDCORE rising
watchdogReset(4) - Watchdog fault occurred
softwareReset(5) - Processor reset required by the software (system reboot)
userReset(6) - NRST pin detected low (reset button)"
::= { wrsBootStatusGroup 3 }
wrsFaultIP OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(4))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The fault address of the last panic. This is the instruction
pointer normally printed by the stack backtrace. The register
is zeroed at first boot and only modified within panic."
::= { wrsBootStatusGroup 4 }
wrsFaultLR OBJECT-TYPE
SYNTAX OCTET STRING (SIZE(4))
MAX-ACCESS read-only
STATUS current
DESCRIPTION
"The link register register at last panic.
This is usually the caller of the function that failed,
but it may be a local register if the failing function
saved lr to the stack and used it as a scratch register."
::= { wrsBootStatusGroup 5 }
wrsConfigSource OBJECT-TYPE
SYNTAX INTEGER {
......
#include "wrsSnmp.h"
#include "snmp_mmap.h"
#include "wrsBootStatusGroup.h"
#define BOOTCOUNT_FILE "/proc/wrs-bootcount"
#define DOTCONFIGDIR "/tmp"
#define DOTCONFIG_PROTO "dot-config_proto"
#define DOTCONFIG_HOST "dot-config_host"
......@@ -10,6 +13,10 @@
* without new line. Macro expands to something like: "%10[^\n]" */
#define LINE_READ_LEN_HELPER(x) "%"#x"[^\n]"
#define LINE_READ_LEN(x) LINE_READ_LEN_HELPER(x)
#define ARM_RCSR_ADDR 0xFFFFFD04 /* address of CPU's Reset Controller Status
* Register */
#define ARM_RCSR_RESET_TYPE_MASK 0x00000700 /* reset type mast in CPU's Reset
* Controller Status Register */
static struct pickinfo wrsBootStatus_pickinfo[] = {
FIELD(wrsBootStatus_s, ASN_COUNTER, wrsBootCnt),
......@@ -24,10 +31,82 @@ static struct pickinfo wrsBootStatus_pickinfo[] = {
struct wrsBootStatus_s wrsBootStatus_s;
struct wrs_bc_item {
char *key;
uint32_t value;
};
/* items to be read from BOOTCOUNT_FILE */
static struct wrs_bc_item boot_info[] = {
[0] = {.key = "boot_count:"},
[1] = {"reboot_count:"},
[2] = {"fault_ip:"},
[3] = {"fault_lr:"},
};
static void get_boot_info(void){
static int run_once = 0;
FILE *f;
char s[80], key[40];
uint32_t value;
int i;
uint32_t *rcsr_map;
if (run_once) {
/* boot info change only at restart */
return;
}
run_once = 1;
/* get restart reason */
rcsr_map = create_map(ARM_RCSR_ADDR, sizeof(uint32_t));
if (!rcsr_map) {
snmp_log(LOG_ERR, "SNMP: wrsBootStatusGroup unable to map "
"CPU's Reset Controller Status Register\n");
/* pass error to SNMP, assign 1 */
wrsBootStatus_s.wrsRestartReason = WRS_RESTART_REASON_ERROR;
} else {
/* reset reason values are from 0 to 4, SNMP enum is from
* 2 to 6, so "+ 2", 1 is reserved for error */
wrsBootStatus_s.wrsRestartReason = 2 +
((*rcsr_map & ARM_RCSR_RESET_TYPE_MASK) >> 8);
}
f = fopen(BOOTCOUNT_FILE, "r");
if (!f) {
snmp_log(LOG_ERR, "SNMP: wrsBootStatusGroup filed to open "
BOOTCOUNT_FILE"\n");
/* notify snmp about error in restart reason */
wrsBootStatus_s.wrsRestartReason = WRS_RESTART_REASON_ERROR;
return;
}
while (fgets(s, sizeof(s), f)) {
if (sscanf(s, "%s %i", key, &value) != 2)
continue; /* error... */
for (i = 0; i < ARRAY_SIZE(boot_info); i++) {
if (strncmp(key, boot_info[i].key, 40))
continue;
boot_info[i].value = value;
}
}
fclose(f);
wrsBootStatus_s.wrsBootCnt = boot_info[0].value;
wrsBootStatus_s.wrsRebootCnt = boot_info[1].value;
snprintf(wrsBootStatus_s.wrsFaultIP,
sizeof(wrsBootStatus_s.wrsFaultIP), "0x%.8x",
boot_info[2].value);
snprintf(wrsBootStatus_s.wrsFaultLR,
sizeof(wrsBootStatus_s.wrsFaultLR), "0x%.8x",
boot_info[3].value);
}
static void get_dotconfig_source(void)
{
char buff[10];
FILE *f;
/* Check dotconfig source.
* dotconfig source can change in runtime, i.e. from remote to local by
* web-interface */
......@@ -97,6 +176,8 @@ time_t wrsBootStatus_data_fill(void)
}
time_update = time_cur;
get_boot_info();
/* get dotconfig source information */
get_dotconfig_source();
......
......@@ -4,6 +4,8 @@
#define WRSBOOTSTATUS_CACHE_TIMEOUT 5
#define WRSBOOTSTATUS_OID WRS_OID, 7, 1, 2
#define WRS_RESTART_REASON_ERROR 1 /* error */
#define WRS_CONFIG_SOURCE_HOST_LEN 64
#define WRS_CONFIG_SOURCE_FILENAME_LEN 128
#define WRS_CONFIG_SOURCE_PROTO_ERROR 1 /* error */
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment