Skip to content

Commit

Permalink
Merge pull request #72 from chu11/redfishpower_timeout
Browse files Browse the repository at this point in the history
redfishpower: allow timeout to be set by device script
  • Loading branch information
mergify[bot] authored Jan 25, 2024
2 parents cf3de6e + b561dd4 commit 0e76a2c
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 18 deletions.
10 changes: 5 additions & 5 deletions etc/devices/redfishpower-cray-r272z30.dev
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@
#
# - This device specification was tested on a Cray with Gigabyte R272-Z30.
#
# - If using a slightly different model or BMC firmware version, its
# possible the URI paths will be different. A good starting point
# is to run the following command to discover the correct paths:
#
# curl -s -u USER:PASS -k -X GET https://pnode1/redfish/v1/Systems
# - CAUTION: If you intend to use this file as the basis for a different
# Redfish system, read the section "UPDATING REDFISHPOWER DEVICE FILES"
# in redfishpower(8).
#
specification "redfishpower-cray-r272z30" {
timeout 60
Expand All @@ -33,6 +31,8 @@ specification "redfishpower-cray-r272z30" {
expect "redfishpower> "
send "setcyclepath redfish/v1/Systems/Self/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceRestart\"}\n"
expect "redfishpower> "
send "settimeout 60\n"
expect "redfishpower> "
}
script logout {
send "quit\n"
Expand Down
12 changes: 7 additions & 5 deletions etc/devices/redfishpower-cray-windom.dev
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@
# attached to a blade's service processor. Some experimentation may
# be needed to determine which node is attached to which suffix.
#
# - If using a slightly different model or BMC firmware version, its
# possible the URI paths will be different. A good starting point
# is to run the following command to discover the correct paths:
#
# curl -s -u USER:PASS -k -X GET https://pnode1/redfish/v1/Systems
# - CAUTION: If you intend to use this file as the basis for a different
# Redfish system, read the section "UPDATING REDFISHPOWER DEVICE FILES"
# in redfishpower(8).
#
specification "redfishpower-cray-windom-node0" {
timeout 60
Expand All @@ -39,6 +37,8 @@ specification "redfishpower-cray-windom-node0" {
expect "redfishpower> "
send "setoffpath redfish/v1/Systems/Node0/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceOff\"}\n"
expect "redfishpower> "
send "settimeout 60\n"
expect "redfishpower> "
}
script logout {
send "quit\n"
Expand Down Expand Up @@ -82,6 +82,8 @@ specification "redfishpower-cray-windom-node1" {
expect "redfishpower> "
send "setoffpath redfish/v1/Systems/Node1/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceOff\"}\n"
expect "redfishpower> "
send "settimeout 60\n"
expect "redfishpower> "
}
script logout {
send "quit\n"
Expand Down
10 changes: 5 additions & 5 deletions etc/devices/redfishpower-supermicro.dev
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@
#
# - This device specification was tested on a Supermicro H12DSG-O-CPU.
#
# - If using a slightly different model or BMC firmware version, its
# possible the URI paths will be different. A good starting point
# is to run the following command to discover the correct paths:
#
# curl -s -u USER:PASS -k -X GET https://pnode1/redfish/v1/Systems/1
# - CAUTION: If you intend to use this file as the basis for a different
# Redfish system, read the section "UPDATING REDFISHPOWER DEVICE FILES"
# in redfishpower(8).
#
specification "redfishpower-supermicro" {
timeout 60
Expand All @@ -33,6 +31,8 @@ specification "redfishpower-supermicro" {
expect "redfishpower> "
send "setcyclepath redfish/v1/Systems/1/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceRestart\"}\n"
expect "redfishpower> "
send "settimeout 60\n"
expect "redfishpower> "
}
script logout {
send "quit\n"
Expand Down
62 changes: 62 additions & 0 deletions man/redfishpower.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ Set path and optional post data to turn off node.
.I "setcyclepath <path> [data]"
Set path and optional post data to turn cycle node.
.TP
.I "settimeout <seconds>"
Set command timeout in seconds.
.TP
.I "stat [nodes]"
Get power status of all nodes or specified subset of nodes.
.TP
Expand All @@ -87,6 +90,65 @@ Turn off all nodes or specified subset of nodes. Will return "ok" after confirm
.I "cycle [nodes]"
Turn off all nodes or specified subset of nodes.

.SH "UPDATING REDFISHPOWER DEVICE FILES"
.LP
Users may often need to modify
.B redfishpower
device files for other systems, as URI paths may be slightly different.
.LP
To find the URI paths on your system, a good starting point is to
use
.B curl(1)
to discover the correct paths at the following standard location.
Note that the output can be easier to read if piped to
.B jq(1),
but that is optional.
.PP
.B # curl -s -u USER:PASS -k -X GET https://<node>/redfish/v1/Systems | jq
.LP
Information in the response will point you on how to dig further.
Several paths the authors have seen include:
.PP
.B # curl -s -u USER:PASS -k -X GET https://<node>/redfish/v1/Systems/1
.PP
.B # curl -s -u USER:PASS -k -X GET https://<node>/redfish/v1/Systems/Node0
.PP
.B # curl -s -u USER:PASS -k -X GET https://<node>/redfish/v1/Systems/Self
.LP
To discover if \fIcycle\fR is supported, a path similar to the following might
be found:
.PP
.B # curl -s -u USER:PASS -k -X GET https://<node>/redfish/v1/Systems/Node0/ResetActionInfo
.LP
If \fIcycle\fR (i.e. \fIForceRestart\fR) is not available, the
\fIcycle_ranged\fR script could be replaced with.
.PP
.nf
script cycle_ranged {
send "off %s\\n"
expect "redfishpower> "
send "on %s\\n"
expect "redfishpower> "
}
.fi
.LP
Internally within
.B redfishpower,
an \fIon\fR or \fIoff\fR command will not return until the
\fIon\fR/\fIoff\fR is confirmed to complete. i.e. \fIstat\fR returns
the expected status.
.LP
This can sometimes take awhile and on some systems may push the
timeout limit specified in the device file (typically 60 seconds). If
necessary, it should be increased at the top of the specification file
(via \fItimeout\fR) and the login section of device file (via
\fIsettimeout\fR).
.LP
Note that if \fIcycle_ranged\fR is scripted as an \fIoff\fR followed by an
\fIon\fR, the
.B powerman
timeout should account for the combined time of both.

.SH "FILES"
@X_SBINDIR@/redfishpower
.br
Expand Down
30 changes: 28 additions & 2 deletions src/redfishpower/redfishpower.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
#include <jansson.h>
#include <unistd.h>
#include <sys/select.h>
#include <limits.h>
#include <sys/time.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>

#include "xtypes.h"
Expand All @@ -46,7 +48,7 @@ static char *cyclepostdata = NULL;

/* in seconds */
#define MESSAGE_TIMEOUT 10
#define CMD_TIMEOUT 60
#define CMD_TIMEOUT_DEFAULT 60

/* Per documentation, wait incremental time then proceed if timeout < 0 */
#define INCREMENTAL_WAIT 500
Expand Down Expand Up @@ -109,6 +111,8 @@ static struct option longopts[] = {
{0,0,0,0},
};

static time_t cmd_timeout = CMD_TIMEOUT_DEFAULT;

void help(void)
{
printf("Valid commands are:\n");
Expand All @@ -118,6 +122,7 @@ void help(void)
printf(" setonpath url [data]\n");
printf(" setoffpath url [data]\n");
printf(" setcyclepath url [data]\n");
printf(" settimeout seconds\n");
printf(" stat [nodes]\n");
printf(" on [nodes]\n");
printf(" off [nodes]\n");
Expand Down Expand Up @@ -218,7 +223,10 @@ static struct powermsg *powermsg_create(CURLM *mh,
else
gettimeofday(&pm->start, NULL);

pm->timeout.tv_sec = pm->start.tv_sec + CMD_TIMEOUT;
if (cmd_timeout > (LONG_MAX - pm->start.tv_sec))
err_exit(FALSE, "cmd_timeout overflow");

pm->timeout.tv_sec = pm->start.tv_sec + cmd_timeout;
pm->timeout.tv_usec = pm->start.tv_usec;

if (delay_usec) {
Expand Down Expand Up @@ -589,6 +597,22 @@ static void setpowerpath(char **av, char **path, char **postdata)
(*postdata) = xstrdup(av[1]);
}

static void settimeout(char **av)
{
if (av[0]) {
char *endptr;
long tmp;

errno = 0;
tmp = strtol (av[0], &endptr, 10);
if (errno
|| endptr[0] != '\0'
|| tmp <= 0)
printf("invalid timeout specified\n");
cmd_timeout = tmp;
}
}

static void process_cmd(List activecmds, CURLM *mh, char **av, int *exitflag)
{
if (av[0] != NULL) {
Expand All @@ -608,6 +632,8 @@ static void process_cmd(List activecmds, CURLM *mh, char **av, int *exitflag)
setpowerpath(av + 1, &offpath, &offpostdata);
else if (strcmp(av[0], "setcyclepath") == 0)
setpowerpath(av + 1, &cyclepath, &cyclepostdata);
else if (strcmp(av[0], "settimeout") == 0)
settimeout(av + 1);
else if (strcmp(av[0], "stat") == 0)
stat_cmd(activecmds, mh, av + 1);
else if (strcmp(av[0], "on") == 0)
Expand Down
3 changes: 2 additions & 1 deletion test/redfishpower.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ _prompt_loop(void)
|| !strcmp(buf, "setstatpath")
|| !strcmp(buf, "setonpath")
|| !strcmp(buf, "setoffpath")
|| !strcmp(buf, "setcyclepath")) {
|| !strcmp(buf, "setcyclepath")
|| !strcmp(buf, "settimeout")) {
/* do nothing with config, just accept */
;
} else if (!strcmp(buf, "stat")) {
Expand Down

0 comments on commit 0e76a2c

Please sign in to comment.