mirror of
https://github.com/ipmitool/ipmitool.git
synced 2025-05-11 19:17:22 +00:00
Support for watchdog timer shutoff, reset, and get info
This commit is contained in:
parent
b3563716bd
commit
3c94523f11
@ -233,6 +233,36 @@ Displays information about the BMC hardware, including device
|
|||||||
revision, firmware revision, IPMI version supported, manufacturer ID,
|
revision, firmware revision, IPMI version supported, manufacturer ID,
|
||||||
and information on additional device support.
|
and information on additional device support.
|
||||||
.TP
|
.TP
|
||||||
|
\fIwatchdog\fP <\fBcommand\fR>
|
||||||
|
.br
|
||||||
|
|
||||||
|
Perform various watchdog timer setting commands to view and
|
||||||
|
change the current state of the timer.
|
||||||
|
.RS
|
||||||
|
.TP
|
||||||
|
\fIget\fP
|
||||||
|
.br
|
||||||
|
|
||||||
|
Show current Watchdog Timer settings and countdown state.
|
||||||
|
.TP
|
||||||
|
\fIreset\fP
|
||||||
|
.br
|
||||||
|
|
||||||
|
Reset the Watchdog Timer to its most recent state and restart the
|
||||||
|
countdown timer.
|
||||||
|
.TP
|
||||||
|
\fIoff\fP
|
||||||
|
.br
|
||||||
|
|
||||||
|
Turn off a currently running Watchdog countdown timer.
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
\fIselftest\fP
|
||||||
|
.br
|
||||||
|
|
||||||
|
Check on the basic health of the BMC by executing the Get Self Test
|
||||||
|
results command and report the results.
|
||||||
|
.TP
|
||||||
\fIgetenables\fP
|
\fIgetenables\fP
|
||||||
.br
|
.br
|
||||||
|
|
||||||
|
@ -114,4 +114,23 @@ struct ipm_get_watchdog_rsp {
|
|||||||
unsigned char present_countdown_msb;
|
unsigned char present_countdown_msb;
|
||||||
} __attribute__ ((packed));
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
#define IPM_WATCHDOG_RESET_ERROR 0x80
|
||||||
|
|
||||||
|
#define IPM_WATCHDOG_BIOS_FRB2 0x01
|
||||||
|
#define IPM_WATCHDOG_BIOS_POST 0x02
|
||||||
|
#define IPM_WATCHDOG_OS_LOAD 0x03
|
||||||
|
#define IPM_WATCHDOG_SMS_OS 0x04
|
||||||
|
#define IPM_WATCHDOG_OEM 0x05
|
||||||
|
|
||||||
|
#define IPM_WATCHDOG_NO_ACTION 0x00
|
||||||
|
#define IPM_WATCHDOG_HARD_RESET 0x01
|
||||||
|
#define IPM_WATCHDOG_POWER_DOWN 0x02
|
||||||
|
#define IPM_WATCHDOG_POWER_CYCLE 0x03
|
||||||
|
|
||||||
|
#define IPM_WATCHDOG_CLEAR_OEM 0x20
|
||||||
|
#define IPM_WATCHDOG_CLEAR_SMS_OS 0x10
|
||||||
|
#define IPM_WATCHDOG_CLEAR_OS_LOAD 0x08
|
||||||
|
#define IPM_WATCHDOG_CLEAR_BIOS_POST 0x04
|
||||||
|
#define IPM_WATCHDOG_CLEAR_BIOS_FRB2 0x02
|
||||||
|
|
||||||
#endif /*IPMI_MC_H */
|
#endif /*IPMI_MC_H */
|
||||||
|
@ -155,8 +155,9 @@ printf_mc_usage(void)
|
|||||||
struct bitfield_data * bf;
|
struct bitfield_data * bf;
|
||||||
printf("MC Commands:\n");
|
printf("MC Commands:\n");
|
||||||
printf(" reset <warm|cold>\n");
|
printf(" reset <warm|cold>\n");
|
||||||
|
printf(" guid\n");
|
||||||
printf(" info\n");
|
printf(" info\n");
|
||||||
printf(" wdt\n");
|
printf(" watchdog <get|reset|off>\n");
|
||||||
printf(" selftest\n");
|
printf(" selftest\n");
|
||||||
printf(" getenables\n");
|
printf(" getenables\n");
|
||||||
printf(" setenables <option=on|off> ...\n");
|
printf(" setenables <option=on|off> ...\n");
|
||||||
@ -166,6 +167,17 @@ printf_mc_usage(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_watchdog_usage(void)
|
||||||
|
{
|
||||||
|
lprintf(LOG_NOTICE, "usage: watchdog <command>:");
|
||||||
|
lprintf(LOG_NOTICE, " get : Get Current Watchdog settings");
|
||||||
|
lprintf(LOG_NOTICE, " reset : Restart Watchdog timer based on most recent settings");
|
||||||
|
lprintf(LOG_NOTICE, " off : Shut off a running Watchdog timer");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ipmi_mc_get_enables - print out MC enables
|
/* ipmi_mc_get_enables - print out MC enables
|
||||||
*
|
*
|
||||||
* @intf: ipmi inteface
|
* @intf: ipmi inteface
|
||||||
@ -251,12 +263,12 @@ ipmi_mc_set_enables(struct ipmi_intf * intf, int argc, char ** argv)
|
|||||||
if (strncmp(argv[i]+nl+1, "off", 3) == 0) {
|
if (strncmp(argv[i]+nl+1, "off", 3) == 0) {
|
||||||
printf("Disabling %s\n", bf->desc);
|
printf("Disabling %s\n", bf->desc);
|
||||||
en &= ~bf->mask;
|
en &= ~bf->mask;
|
||||||
}
|
}
|
||||||
else if (strncmp(argv[i]+nl+1, "on", 2) == 0) {
|
else if (strncmp(argv[i]+nl+1, "on", 2) == 0) {
|
||||||
printf("Enabling %s\n", bf->desc);
|
printf("Enabling %s\n", bf->desc);
|
||||||
en |= bf->mask;
|
en |= bf->mask;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lprintf(LOG_ERR, "Unrecognized option: %s", argv[i]);
|
lprintf(LOG_ERR, "Unrecognized option: %s", argv[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -470,7 +482,7 @@ static int ipmi_mc_get_selftest(struct ipmi_intf * intf)
|
|||||||
|
|
||||||
if (rsp->ccode) {
|
if (rsp->ccode) {
|
||||||
lprintf(LOG_ERR, "Bad response: (%s)",
|
lprintf(LOG_ERR, "Bad response: (%s)",
|
||||||
val2str(rsp->ccode, completion_code_vals));
|
val2str(rsp->ccode, completion_code_vals));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,25 +557,25 @@ static int ipmi_mc_get_selftest(struct ipmi_intf * intf)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const char *wdt_use_string[8] = {
|
const char *wdt_use_string[8] = {
|
||||||
"reserved",
|
"Reserved",
|
||||||
"BIOS FRB2",
|
"BIOS FRB2",
|
||||||
"BIOS/POST",
|
"BIOS/POST",
|
||||||
"OS Load",
|
"OS Load",
|
||||||
"SMS/OS",
|
"SMS/OS",
|
||||||
"OEM",
|
"OEM",
|
||||||
"reserved",
|
"Reserved",
|
||||||
"reserved"
|
"Reserved"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *wdt_action_string[8] = {
|
const char *wdt_action_string[8] = {
|
||||||
"no action",
|
"No action",
|
||||||
"Hard Reset",
|
"Hard Reset",
|
||||||
"Power Down",
|
"Power Down",
|
||||||
"Power Cycle",
|
"Power Cycle",
|
||||||
"reserved",
|
"Reserved",
|
||||||
"reserved",
|
"Reserved",
|
||||||
"reserved",
|
"Reserved",
|
||||||
"reserved"
|
"Reserved"
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -579,32 +591,37 @@ ipmi_mc_get_watchdog(struct ipmi_intf * intf)
|
|||||||
req.msg.data_len = 0;
|
req.msg.data_len = 0;
|
||||||
|
|
||||||
rsp = intf->sendrecv(intf, &req);
|
rsp = intf->sendrecv(intf, &req);
|
||||||
if (!rsp) {
|
if (rsp == NULL) {
|
||||||
printf("no response\n");
|
lprintf(LOG_ERR, "Get Watchdog Timer command failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rsp->ccode) {
|
if (rsp->ccode) {
|
||||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
lprintf(LOG_ERR, "Get Watchdog Timer command failed: %s",
|
||||||
|
val2str(rsp->ccode, completion_code_vals));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
wdt_res = (struct ipm_get_watchdog_rsp *) rsp->data;
|
wdt_res = (struct ipm_get_watchdog_rsp *) rsp->data;
|
||||||
|
|
||||||
printf("Timer Use: 0x%02x - %s\n", wdt_res->timer_use, wdt_use_string[wdt_res->timer_use]);
|
printf("Watchdog Timer Use: %s (0x%02x)\n",
|
||||||
printf("Timer Actions: 0x%02x - %s\n", wdt_res->timer_actions, wdt_action_string[wdt_res->timer_actions]);
|
wdt_use_string[wdt_res->timer_use], wdt_res->timer_use);
|
||||||
printf("Pre-timeout interval: 0x%02x\n", wdt_res->pre_timeout);
|
printf("Watchdog Timer Is: %s\n",
|
||||||
printf("Timer Use Expiration: 0x%02x\n", wdt_res->timer_use_exp);
|
wdt_res->timer_use & 0x40 ? "Started/Running" : "Stopped");
|
||||||
printf("Initial Countdown: %i ms\n",
|
printf("Watchdog Timer Actions: %s (0x%02x)\n",
|
||||||
(wdt_res->initial_countdown_msb << 8) | wdt_res->initial_countdown_lsb);
|
wdt_action_string[wdt_res->timer_actions], wdt_res->timer_actions);
|
||||||
printf("Present Countdown: %i ms\n",
|
printf("Pre-timeout interval: %d seconds\n", wdt_res->pre_timeout);
|
||||||
(wdt_res->present_countdown_msb << 8) | wdt_res->present_countdown_lsb);
|
printf("Timer Expiration Flags: 0x%02x\n", wdt_res->timer_use_exp);
|
||||||
|
printf("Initial Countdown: %i sec\n",
|
||||||
|
((wdt_res->initial_countdown_msb << 8) | wdt_res->initial_countdown_lsb)/10 );
|
||||||
|
printf("Present Countdown: %i sec\n",
|
||||||
|
(((wdt_res->present_countdown_msb << 8) | wdt_res->present_countdown_lsb)) / 10);
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ipmi_mc_set_watchdog
|
/* ipmi_mc_shutoff_watchdog
|
||||||
*
|
*
|
||||||
* @intf: ipmi interface
|
* @intf: ipmi interface
|
||||||
*
|
*
|
||||||
@ -612,7 +629,7 @@ ipmi_mc_get_watchdog(struct ipmi_intf * intf)
|
|||||||
* returns -1 on error
|
* returns -1 on error
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ipmi_mc_set_watchdog(struct ipmi_intf * intf, int argc, char ** argv)
|
ipmi_mc_shutoff_watchdog(struct ipmi_intf * intf)
|
||||||
{
|
{
|
||||||
struct ipmi_rs * rsp;
|
struct ipmi_rs * rsp;
|
||||||
struct ipmi_rq req;
|
struct ipmi_rq req;
|
||||||
@ -624,31 +641,43 @@ ipmi_mc_set_watchdog(struct ipmi_intf * intf, int argc, char ** argv)
|
|||||||
req.msg.data = msg_data;
|
req.msg.data = msg_data;
|
||||||
req.msg.data_len = 6;
|
req.msg.data_len = 6;
|
||||||
|
|
||||||
printf("FIXME - not fully implemented\n");
|
/*
|
||||||
|
* The only set cmd we're allowing is to shut off the timer.
|
||||||
|
* Turning on the timer should be the job of the ipmi watchdog driver.
|
||||||
|
* See 'modinfo ipmi_watchdog' for more info. (NOTE: the reset
|
||||||
|
* command will restart the timer if it's already been initialized.)
|
||||||
|
*
|
||||||
|
* Out-of-band watchdog set commands can still be sent via the raw
|
||||||
|
* command interface but this is a very dangerous thing to do since
|
||||||
|
* a periodic "poke"/reset over a network is unreliable. This is
|
||||||
|
* not a recommended way to use the IPMI watchdog commands.
|
||||||
|
*/
|
||||||
|
|
||||||
msg_data[0] = 0x03; /* os load*/
|
msg_data[0] = IPM_WATCHDOG_SMS_OS;
|
||||||
msg_data[1] = 0x02; /* action power down */
|
msg_data[1] = IPM_WATCHDOG_NO_ACTION;
|
||||||
msg_data[2] = 10; /* pretimeout */
|
msg_data[2] = 0x00; // pretimeout interval
|
||||||
msg_data[3] = 0;
|
msg_data[3] = IPM_WATCHDOG_CLEAR_SMS_OS;
|
||||||
msg_data[4] = 10; /* timeout lsb in 100ms/count */
|
msg_data[4] = 0xb8; // countdown lsb (100 ms/count)
|
||||||
msg_data[5] = 0; /* timeout lsb */
|
msg_data[5] = 0x0b; // countdown msb - 5 mins
|
||||||
|
|
||||||
rsp = intf->sendrecv(intf, &req);
|
rsp = intf->sendrecv(intf, &req);
|
||||||
if (!rsp) {
|
if (rsp == NULL) {
|
||||||
printf("no response\n");
|
lprintf(LOG_ERR, "Watchdog Timer Shutoff command failed!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rsp->ccode) {
|
if (rsp->ccode) {
|
||||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
lprintf(LOG_ERR, "Watchdog Timer Shutoff command failed! %s",
|
||||||
|
val2str(rsp->ccode, completion_code_vals));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lprintf(LOG_ERR, "Watchdog Timer Shutoff successful -- timer stopped");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ipmi_mc_set_watchdog
|
/* ipmi_mc_rst_watchdog
|
||||||
*
|
*
|
||||||
* @intf: ipmi interface
|
* @intf: ipmi interface
|
||||||
*
|
*
|
||||||
@ -667,16 +696,20 @@ ipmi_mc_rst_watchdog(struct ipmi_intf * intf)
|
|||||||
req.msg.data_len = 0;
|
req.msg.data_len = 0;
|
||||||
|
|
||||||
rsp = intf->sendrecv(intf, &req);
|
rsp = intf->sendrecv(intf, &req);
|
||||||
if (!rsp) {
|
if (rsp == NULL) {
|
||||||
printf("no response\n");
|
lprintf(LOG_ERR, "Reset Watchdog Timer command failed!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rsp->ccode) {
|
if (rsp->ccode) {
|
||||||
printf("returned CC code 0x%02x\n", rsp->ccode);
|
lprintf(LOG_ERR, "Reset Watchdog Timer command failed: %s",
|
||||||
|
(rsp->ccode == IPM_WATCHDOG_RESET_ERROR) ?
|
||||||
|
"Attempt to reset unitialized watchdog" :
|
||||||
|
val2str(rsp->ccode, completion_code_vals));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lprintf(LOG_ERR, "IPMI Watchdog Timer Reset - countdown restarted!");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,19 +759,22 @@ ipmi_mc_main(struct ipmi_intf * intf, int argc, char ** argv)
|
|||||||
else if (!strncmp(argv[0], "selftest", 8)) {
|
else if (!strncmp(argv[0], "selftest", 8)) {
|
||||||
rc = ipmi_mc_get_selftest(intf);
|
rc = ipmi_mc_get_selftest(intf);
|
||||||
}
|
}
|
||||||
else if (!strncmp(argv[0], "wdt", 3)) {
|
else if (!strncmp(argv[0], "watchdog", 3)) {
|
||||||
if (argc < 2) {
|
if (argc < 2 || strncmp(argv[1], "help", 4) == 0) {
|
||||||
|
print_watchdog_usage();
|
||||||
|
}
|
||||||
|
else if (strncmp(argv[1], "get", 3) == 0) {
|
||||||
rc = ipmi_mc_get_watchdog(intf);
|
rc = ipmi_mc_get_watchdog(intf);
|
||||||
}else if(strncmp(argv[1], "get", 3) == 0){
|
}
|
||||||
rc = ipmi_mc_get_watchdog(intf);
|
else if(strncmp(argv[1], "off", 3) == 0) {
|
||||||
}else if(strncmp(argv[1], "set", 3) == 0){
|
rc = ipmi_mc_shutoff_watchdog(intf);
|
||||||
if(argc > 5)
|
}
|
||||||
rc = ipmi_mc_set_watchdog(intf, argc-1, &(argv[1]));
|
else if(strncmp(argv[1], "reset", 5) == 0) {
|
||||||
else
|
|
||||||
printf("wdt set <use><action><pretimeout><countdown> FIXME - not fully implemented\n");
|
|
||||||
}else if(strncmp(argv[1], "rst", 3) == 0){
|
|
||||||
rc = ipmi_mc_rst_watchdog(intf);
|
rc = ipmi_mc_rst_watchdog(intf);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
print_watchdog_usage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lprintf(LOG_ERR, "Invalid mc/bmc command: %s", argv[0]);
|
lprintf(LOG_ERR, "Invalid mc/bmc command: %s", argv[0]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user