Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

powerman: support status_ranged script #152

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions etc/devices/ipmipower.dev
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ specification "ipmipower" {
script logout {
send "quit\n"
}
script status_all {
send "stat\n"
script status_ranged {
send "stat %s\n"
foreachnode {
expect "([^\n:]+): ([^\n]+\n)"
setplugstate $1 $2 on="^on\n" off="^off\n"
Expand Down
16 changes: 7 additions & 9 deletions man/powerman.dev.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,17 @@ Executed prior to disconnect.
Get device in a state so login script will work
(though hopefully disconnecting will do that too).
.TP
.I "status_all, status[%s]"
Obtain plug state for all plugs or only the specified plug.
When all plugs of a device are involved in a plug status query,
the status_all script, if defined, will be called in preference to the
status script; otherwise the status script is called for each plug.
.I "status_all, status_ranged[%s], status[%s]"
Obtain plug state for all plugs, a range of plugs, or only the
specified plug.
.TP
.I "on_all, on_range[%s], on[%s]"
.I "on_all, on_ranged[%s], on[%s]"
Power on all plugs, a range of plugs, or the specified plug.
.TP
.I "off_all, off_range[%s], off[%s]"
.I "off_all, off_ranged[%s], off[%s]"
Power off all plugs, a range of plugs, or the specified plug.
.TP
.I "cycle_all, cycle_range[%s], cycle[%s]"
.I "cycle_all, cycle_ranged[%s], cycle[%s]"
Power cycle all plugs, a range of plugs, or the specified plug.
The intent of this command was to map to the RPC's cycle command;
however, device script are increasingly implementing this in terms of
Expand Down Expand Up @@ -122,7 +120,7 @@ Flash beacon on the specified plug.
.I "beacon_off[%s]"
Clear beacon on the specified plug.
.TP
.I "reset_all, reset_range[%s], reset[%s]"
.I "reset_all, reset_ranged[%s], reset[%s]"
Reset all plugs, a range of plugs, or only the specified plug.
Reset refers to signaling a motherboard reset butten header, not a plug cycle.
.LP
Expand Down
21 changes: 19 additions & 2 deletions src/powerman/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ typedef struct {
ListIterator stmtitr; /* next stmt in block */
Stmt *cur; /* current stmt */
PlugListIterator plugitr; /* used by foreach */
PlugList pluglist; /* pluglist if foreach is ranged */
bool processing; /* flag used by stmts, ifon/ifoff */
} ExecCtx;

Expand Down Expand Up @@ -229,6 +230,8 @@ static void _destroy_exec_ctx(ExecCtx *e)
e->cur = NULL;
if (e->plugs)
list_destroy(e->plugs);
if (e->pluglist)
pluglist_destroy(e->pluglist);
e->plugs = NULL;
xfree(e);
}
Expand Down Expand Up @@ -596,6 +599,10 @@ static int _get_ranged_script(Device * dev, int com)
if (dev->scripts[PM_RESET_RANGED])
new = PM_RESET_RANGED;
break;
case PM_STATUS_PLUGS:
if (dev->scripts[PM_STATUS_PLUGS_RANGED])
new = PM_STATUS_PLUGS_RANGED;
break;
case PM_BEACON_ON:
if (dev->scripts[PM_BEACON_ON_RANGED])
new = PM_BEACON_ON_RANGED;
Expand Down Expand Up @@ -937,8 +944,18 @@ static bool _process_foreach(Device *dev, Action *act, ExecCtx *e)
Plug *plug = NULL;

/* we store a plug iterator in the ExecCtx */
if (e->plugitr == NULL)
e->plugitr = pluglist_iterator_create(dev->plugs);
if (e->plugitr == NULL) {
if (act->com == PM_STATUS_PLUGS_RANGED) {
assert(e->plugs);
if (!e->pluglist) {
if (!(e->pluglist = pluglist_copy_from_list(e->plugs)))
goto cleanup;
}
e->plugitr = pluglist_iterator_create(e->pluglist);
}
else
e->plugitr = pluglist_iterator_create(dev->plugs);
}

/* Each time the inner block is executed, its argument will be
* a new plug name. Pick that up here.
Expand Down
56 changes: 28 additions & 28 deletions src/powerman/device_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,35 @@
#define NO_FD (-1)

/* Indices into script array */
#define PM_LOG_IN 0
#define PM_LOG_OUT 1
#define PM_STATUS_PLUGS 2
#define PM_STATUS_PLUGS_ALL 3
/*4*/
#define PM_LOG_IN 0
#define PM_LOG_OUT 1
#define PM_STATUS_PLUGS 2
#define PM_STATUS_PLUGS_RANGED 3
#define PM_STATUS_PLUGS_ALL 4
/*5*/
#define PM_PING 6
#define PM_POWER_ON 7
#define PM_POWER_ON_RANGED 8
#define PM_POWER_ON_ALL 9
#define PM_POWER_OFF 10
#define PM_POWER_OFF_RANGED 11
#define PM_POWER_OFF_ALL 12
#define PM_POWER_CYCLE 13
#define PM_POWER_CYCLE_RANGED 14
#define PM_POWER_CYCLE_ALL 15
#define PM_RESET 16
#define PM_RESET_RANGED 17
#define PM_RESET_ALL 18
#define PM_STATUS_TEMP 19
#define PM_STATUS_TEMP_ALL 20
#define PM_STATUS_BEACON 21
#define PM_STATUS_BEACON_ALL 22
#define PM_BEACON_ON 23
#define PM_BEACON_ON_RANGED 24
#define PM_BEACON_OFF 25
#define PM_BEACON_OFF_RANGED 26
#define PM_RESOLVE 27
#define NUM_SCRIPTS 28 /* count of scripts above */
#define PM_PING 6
#define PM_POWER_ON 7
#define PM_POWER_ON_RANGED 8
#define PM_POWER_ON_ALL 9
#define PM_POWER_OFF 10
#define PM_POWER_OFF_RANGED 11
#define PM_POWER_OFF_ALL 12
#define PM_POWER_CYCLE 13
#define PM_POWER_CYCLE_RANGED 14
#define PM_POWER_CYCLE_ALL 15
#define PM_RESET 16
#define PM_RESET_RANGED 17
#define PM_RESET_ALL 18
#define PM_STATUS_TEMP 19
#define PM_STATUS_TEMP_ALL 20
#define PM_STATUS_BEACON 21
#define PM_STATUS_BEACON_ALL 22
#define PM_BEACON_ON 23
#define PM_BEACON_ON_RANGED 24
#define PM_BEACON_OFF 25
#define PM_BEACON_OFF_RANGED 26
#define PM_RESOLVE 27
#define NUM_SCRIPTS 28 /* count of scripts above */

#define MAX_MATCH_POS 20

Expand Down
1 change: 1 addition & 0 deletions src/powerman/parse_lex.l
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ delay return TOK_DELAY;
login return TOK_LOGIN;
logout return TOK_LOGOUT;
status return TOK_STATUS;
status_ranged return TOK_STATUS_RANGED;
status_all return TOK_STATUS_ALL;
on return TOK_ON;
on_ranged return TOK_ON_RANGED;
Expand Down
4 changes: 3 additions & 1 deletion src/powerman/parse_tab.y
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ static Spec current_spec; /* Holds a Spec as it is built */
%}

/* script names */
%token TOK_LOGIN TOK_LOGOUT TOK_STATUS TOK_STATUS_ALL
%token TOK_LOGIN TOK_LOGOUT TOK_STATUS TOK_STATUS_RANGED TOK_STATUS_ALL
%token TOK_STATUS_TEMP TOK_STATUS_TEMP_ALL
%token TOK_STATUS_BEACON TOK_STATUS_BEACON_ALL
%token TOK_BEACON_ON TOK_BEACON_ON_RANGED TOK_BEACON_OFF TOK_BEACON_OFF_RANGED
Expand Down Expand Up @@ -232,6 +232,8 @@ spec_script : TOK_SCRIPT TOK_LOGIN stmt_block {
makeScript(PM_LOG_OUT, (List)$3);
} | TOK_SCRIPT TOK_STATUS stmt_block {
makeScript(PM_STATUS_PLUGS, (List)$3);
} | TOK_SCRIPT TOK_STATUS_RANGED stmt_block {
makeScript(PM_STATUS_PLUGS_RANGED, (List)$3);
} | TOK_SCRIPT TOK_STATUS_ALL stmt_block {
makeScript(PM_STATUS_PLUGS_ALL, (List)$3);
} | TOK_SCRIPT TOK_STATUS_TEMP stmt_block {
Expand Down
35 changes: 35 additions & 0 deletions src/powerman/pluglist.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ static Plug *_create_plug(char *name)
return plug;
}

static Plug *_copy_plug(Plug *p)
{
Plug *plug = (Plug *) xmalloc(sizeof(Plug));

assert(p != NULL);

plug->name = p->name ? xstrdup(p->name) : NULL;
plug->node = p->node ? xstrdup(p->node) : NULL;

return plug;
}

static void _destroy_plug(Plug *plug)
{
assert(plug != NULL);
Expand Down Expand Up @@ -82,6 +94,29 @@ PlugList pluglist_create(List plugnames)
return pl;
}

PlugList pluglist_copy_from_list(List plugs)
{
PlugList pl = (PlugList) xmalloc(sizeof(struct pluglist));

pl->pluglist = list_create((ListDelF)_destroy_plug);
pl->hardwired = false;

/* create plug from each plug in list */
if (plugs) {
ListIterator itr;
Plug *p;

itr = list_iterator_create(plugs);
while ((p = list_next(itr))) {
list_append(pl->pluglist, _copy_plug(p));
}
list_iterator_destroy(itr);
pl->hardwired = true;
}

return pl;
}

void pluglist_destroy(PlugList pl)
{
assert(pl != NULL);
Expand Down
3 changes: 3 additions & 0 deletions src/powerman/pluglist.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ typedef enum { EPL_SUCCESS, EPL_DUPNODE, EPL_UNKPLUG, EPL_DUPPLUG,
*/
PlugList pluglist_create(List plugnames);

/* Create a PlugList, copying plugs from an existing list of plugs */
PlugList pluglist_copy_from_list(List plugs);

/* Destroy a PlugList and its Plugs
*/
void pluglist_destroy(PlugList pl);
Expand Down
Loading