Hi Christine, all,
This is definitely true.
I do not have so nice patches against git master, but I'd like to
present my patches against 3.1.7 which I use for a quite long time (I
send them as I promised year ago or so on pacemaker list).
I attach them in order they are applied in my srpm, and I hope that
their names and contents are self-describing. If not please do not
hesitate to write me.
I would describe some patches here:
01-fence-agents-3.1.7-ipmilan-uniq.patch fixes parameter uniqueness
report (needed for newer pacemaker)
02-fence-agents-3.1.2-ipmilan-cycle.patch fixes return value for cycle
method (nobody uses it yet?)
06-fence-agents-3.1.7-ipmilan-reset-method.patch just adds IPMI reset
method, because some IPMI controllers have bugs in cycle or on-off
implementations and admin may want to use reset which always work with
them.
08-fence-agents-3.1.7-ipmilan-force-ops.patch and
09-fence-agents-3.1.7-ipmilan-status-recheck.patch add more workarounds
against buggy IPMI controllers which may report status incorrectly right
after operation is completed (Supermicro on-board ones are examples of
them).
I definitely do not like amount of function arguments I have after that
all, but it is better to leave it to package maintainer to decide what
to do with them
Pleas do not kick me for sending non-git patches, it is over my skills
to do that.
Best,
Vladislav
03.02.2012 17:22, Christine Caulfield wrote:
>
>
> -------- Original Message --------
> Subject: fence-agent : ipmilan : power_wait : missing in ipmi_off.
> Date: Fri, 03 Feb 2012 15:20:47 +0100 (CET)
> From: Alexandre DERUMIER <[email protected]>
> To: [email protected]
>
> Hi,
>
> I'm working to implement a redhat cluster and I think I found a bug in
> ipmilan.c
>
> On this commit:
>
> fence-agents: Add power_wait to fence_ipmilan
>
> http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=7d53eb8ab06a8713d2b52500da741b6170fbfc91
>
>
> in ipmi_off , the sleep(2) is still hardcorded
>
> I think It must replace with sleep(ipmi->i_power_wait), like ipmi_on ?
>
>
> index 52be371..46814a8 100644
> --- a/fence/agents/ipmilan/ipmilan.c
> +++ b/fence/agents/ipmilan/ipmilan.c
> @@ -473,7 +473,7 @@ ipmi_off(struct ipmi *ipmi)
> if (ret != 0)
> return ret;
>
> - sleep(2);
> + sleep(ipmi->i_power_wait);
> --retries;
> ret = ipmi_op(ipmi, ST_STATUS, power_status);
>
>
>
> What do you thinks about it ?
>
>
>
> Best Regards,
>
> Alexandre Derumier
> System Engineer
> [email protected]
>
>
>
>
>
>
>
>
>
>
> --
> Linux-cluster mailing list
> [email protected]
> https://www.redhat.com/mailman/listinfo/linux-cluster
--- fence-agents-3.1.7.orig/fence/agents/ipmilan/ipmilan.c 2011-02-03 21:46:45.000000000 +0100
+++ fence-agents-3.1.7/fence/agents/ipmilan/ipmilan.c 2011-03-26 07:34:47.455695999 +0100
@@ -156,6 +156,7 @@ struct xml_parameter_s {
const char *name;
const char *getopt;
const int required;
+ const int unique;
const char *content_type;
const char *default_value;
const char *description;
@@ -163,20 +164,20 @@ struct xml_parameter_s {
/* Array of xml metadatas*/
struct xml_parameter_s xml_parameters[]={
- {"auth","-A",0,"string",NULL,"IPMI Lan Auth type (md5, password, or none)"},
- {"ipaddr","-a",1,"string",NULL,"IPMI Lan IP to talk to"},
- {"passwd","-p",0,"string",NULL,"Password (if required) to control power on IPMI device"},
- {"passwd_script","-S",0,"string",NULL,"Script to retrieve password (if required)"},
- {"lanplus","-P",0,"boolean",NULL,"Use Lanplus"},
- {"login","-l",0,"string",NULL,"Username/Login (if required) to control power on IPMI device"},
- {"action","-o",0,"string","reboot","Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata"},
- {"timeout","-t",0,"string",NULL,"Timeout (sec) for IPMI operation"},
- {"cipher","-C",0,"string",NULL,"Ciphersuite to use (same as ipmitool -C parameter)"},
- {"method","-M",0,"string",DEFAULT_METHOD,"Method to fence (onoff or cycle)"},
- {"power_wait","-T",0,"string","2","Wait X seconds after on/off operation"},
- {"delay","-f",0,"string",NULL,"Wait X seconds before fencing is started"},
- {"privlvl","-L",0,"string",NULL,"Privilege level on IPMI device"},
- {"verbose","-v",0,"boolean",NULL,"Verbose mode"}};
+ {"auth","-A",0,0,"string",NULL,"IPMI Lan Auth type (md5, password, or none)"},
+ {"ipaddr","-a",1,1,"string",NULL,"IPMI Lan IP to talk to"},
+ {"passwd","-p",0,0,"string",NULL,"Password (if required) to control power on IPMI device"},
+ {"passwd_script","-S",0,0,"string",NULL,"Script to retrieve password (if required)"},
+ {"lanplus","-P",0,0,"boolean",NULL,"Use Lanplus"},
+ {"login","-l",0,0,"string",NULL,"Username/Login (if required) to control power on IPMI device"},
+ {"action","-o",0,0,"string","reboot","Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata"},
+ {"timeout","-t",0,0,"string",NULL,"Timeout (sec) for IPMI operation"},
+ {"cipher","-C",0,0,"string",NULL,"Ciphersuite to use (same as ipmitool -C parameter)"},
+ {"method","-M",0,0,"string",DEFAULT_METHOD,"Method to fence (onoff or cycle)"},
+ {"power_wait","-T",0,0,"string","2","Wait X seconds after on/off operation"},
+ {"delay","-f",0,0,"string",NULL,"Wait X seconds before fencing is started"},
+ {"privlvl","-L",0,0,"string",NULL,"Privilege level on IPMI device"},
+ {"verbose","-v",0,0,"boolean",NULL,"Verbose mode"}};
/*
Search for ipmitool
@@ -911,7 +912,7 @@ static void print_xml_metadata(char *pna
printf("%s\n","<parameters>");
for (i=0;i<(sizeof(xml_parameters)/sizeof(struct xml_parameter_s));i++) {
- printf("\t<parameter name=\"%s\" unique=\"1\">\n",xml_parameters[i].name);
+ printf("\t<parameter name=\"%s\" unique=\"%d\">\n",xml_parameters[i].name,xml_parameters[i].unique);
printf("\t\t<getopt mixed=\"%s\" />\n",xml_parameters[i].getopt);
if (xml_parameters[i].default_value == NULL) {
--- fence-agents-3.1.2.orig/fence/agents/ipmilan/ipmilan.c 2011-03-26 07:43:59.000000000 +0100
+++ fence-agents-3.1.2/fence/agents/ipmilan/ipmilan.c 2011-03-26 08:03:03.358695907 +0100
@@ -1125,6 +1125,7 @@ main(int argc, char **argv)
if (!strcasecmp(method, "cycle")) {
ret = ipmi_cycle(i);
+ translated_ret = (ret==0?ERR_OFF_SUCCESSFUL:ERR_OFF_FAIL);
} else {
/* Original onoff method */
ret = ipmi_off(i);
diff -urNp fence-agents-3.1.2.orig/fence/agents/ipmilan/ipmilan.c fence-agents-3.1.2/fence/agents/ipmilan/ipmilan.c
--- fence-agents-3.1.2.orig/fence/agents/ipmilan/ipmilan.c 2011-03-26 08:07:13.000000000 +0100
+++ fence-agents-3.1.2/fence/agents/ipmilan/ipmilan.c 2011-03-26 15:02:05.135947265 +0100
@@ -456,7 +456,7 @@ ipmi_off(struct ipmi *ipmi)
if (ret != 0)
return ret;
- sleep(2);
+ sleep(ipmi->i_power_wait);
--retries;
ret = ipmi_op(ipmi, ST_STATUS, power_status);
diff -urNp fence-agents-3.1.2.orig/fence/agents/ipmilan/ipmilan.c fence-agents-3.1.2/fence/agents/ipmilan/ipmilan.c
--- fence-agents-3.1.2.orig/fence/agents/ipmilan/ipmilan.c 2011-03-26 15:02:05.000000000 +0100
+++ fence-agents-3.1.2/fence/agents/ipmilan/ipmilan.c 2011-03-26 15:03:36.791070636 +0100
@@ -847,7 +847,7 @@ printf(" ipaddr=<#> Same as
printf(" passwd=<pass> Same as -p\n");
printf(" passwd_script=<path> Same as -S\n");
printf(" lanplus Same as -P\n");
-printf(" login=<login> Same as -u\n");
+printf(" login=<login> Same as -l\n");
printf(" option=<op> Same as -o\n");
printf(" operation=<op> Same as -o\n");
printf(" action=<op> Same as -o\n");
diff -urNp fence-agents-3.1.2.orig/fence/agents/ipmilan/ipmilan.c fence-agents-3.1.2/fence/agents/ipmilan/ipmilan.c
--- fence-agents-3.1.2.orig/fence/agents/ipmilan/ipmilan.c 2011-03-28 09:19:03.000000000 +0200
+++ fence-agents-3.1.2/fence/agents/ipmilan/ipmilan.c 2011-03-28 09:19:35.012696209 +0200
@@ -1088,7 +1088,7 @@ main(int argc, char **argv)
if (strcasecmp(method, "onoff") &&
strcasecmp(method, "cycle")) {
- fail_exit("method, if included, muse be 'onoff', 'cycle'.");
+ fail_exit("method, if included, must be 'onoff', 'cycle'.");
}
if (!strcasecmp(method, "cycle") &&
--- fence-agents-3.1.7.orig/fence/agents/ipmilan/ipmilan.c 2011-03-26 15:03:36.000000000 +0100
+++ fence-agents-3.1.7/fence/agents/ipmilan/ipmilan.c 2011-03-26 15:14:11.340695714 +0100
@@ -29,7 +29,8 @@
#define ST_POWEROFF 2
#define ST_GENERIC_RESET 3
#define ST_CYCLE 4
-#define ST_DIAG 5
+#define ST_RESET 5
+#define ST_DIAG 6
#define DEFAULT_TIMEOUT 20
#define DEFAULT_POWER_WAIT 2
@@ -138,6 +139,17 @@ static struct Etoken power_cycle_complet
{NULL, 0, 0}
};
+static struct Etoken power_reset_complete[] = {
+ {"Password:", EPERM, 0},
+ {"Unable to establish LAN", EAGAIN, 0}, /* Retry */
+ {"IPMI mutex", EFAULT, 0}, /* Death */
+ {"Unsupported cipher suite ID", ECIPHER,0},
+ {"read_rakp2_message: no support for", ECIPHER,0},
+ {"Command not supported in present state", ESTATE, 0},
+ {": Reset", 0, 0},
+ {NULL, 0, 0}
+};
+
#define STATE_OFF 4096
#define STATE_ON 8192
static struct Etoken power_status[] = {
@@ -173,7 +185,7 @@ struct xml_parameter_s xml_parameters[]=
{"action","-o",0,0,"string","reboot","Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata"},
{"timeout","-t",0,0,"string",NULL,"Timeout (sec) for IPMI operation"},
{"cipher","-C",0,0,"string",NULL,"Ciphersuite to use (same as ipmitool -C parameter)"},
- {"method","-M",0,0,"string",DEFAULT_METHOD,"Method to fence (onoff or cycle)"},
+ {"method","-M",0,0,"string",DEFAULT_METHOD,"Method to fence (onoff, cycle or reset)"},
{"power_wait","-T",0,0,"string","2","Wait X seconds after on/off operation"},
{"delay","-f",0,0,"string",NULL,"Wait X seconds before fencing is started"},
{"privlvl","-L",0,0,"string",NULL,"Privilege level on IPMI device"},
@@ -319,6 +331,10 @@ build_cmd(char *command, size_t cmdlen,
snprintf(arg, sizeof(arg),
"%s chassis power cycle", cmd);
break;
+ case ST_RESET:
+ snprintf(arg, sizeof(arg),
+ "%s chassis power reset", cmd);
+ break;
case ST_DIAG:
snprintf(arg, sizeof(arg),
"%s chassis power diag", cmd);
@@ -548,6 +564,16 @@ ipmi_cycle(struct ipmi *ipmi)
}
static int
+ipmi_reset(struct ipmi *ipmi)
+{
+ int ret;
+
+ ret = ipmi_op(ipmi, ST_RESET, power_reset_complete);
+
+ return ret;
+}
+
+static int
ipmi_diag(struct ipmi *ipmi)
{
int ret;
@@ -870,7 +896,7 @@ printf(" -t <timeout> Timeout (sec)
printf(" -T <timeout> Wait X seconds after on/off operation\n");
printf(" -f <timeout> Wait X seconds before fencing is started\n");
printf(" -C <cipher> Ciphersuite to use (same as ipmitool -C parameter)\n");
-printf(" -M <method> Method to fence (onoff or cycle (default %s)\n", DEFAULT_METHOD);
+printf(" -M <method> Method to fence (onoff, cycle or reset) (default %s)\n", DEFAULT_METHOD);
printf(" -V Print version and exit\n");
printf(" -v Verbose mode\n\n");
printf("If no options are specified, the following options will be read\n");
@@ -1130,8 +1156,9 @@ main(int argc, char **argv)
}
if (strcasecmp(method, "onoff") &&
- strcasecmp(method, "cycle")) {
- fail_exit("method, if included, must be 'onoff', 'cycle'.");
+ strcasecmp(method, "cycle") &&
+ strcasecmp(method, "reset")) {
+ fail_exit("method, if included, must be 'onoff', 'cycle', 'reset'.");
}
if (!strcasecmp(method, "cycle") &&
@@ -1139,6 +1166,11 @@ main(int argc, char **argv)
fail_exit("cycle method supports only 'reboot' operation (not 'on' or 'off').");
}
+ if (!strcasecmp(method, "reset") &&
+ (!strcasecmp(op, "on") || !strcasecmp(op, "off"))) {
+ fail_exit("reset method supports only 'reboot' operation (not 'on' or 'off').");
+ }
+
/* Delay fencing if requested */
if (delay) {
if (!strcasecmp(op, "reboot") || !strcasecmp(op, "off")) {
@@ -1157,7 +1189,7 @@ main(int argc, char **argv)
if (!strcasecmp(op, "reboot")) {
printf("Rebooting machine @ IPMI:%s...", ip);
fflush(stdout);
- if (!strcasecmp(method, "cycle")) {
+ if (!strcasecmp(method, "cycle") || !strcasecmp(method, "reset")) {
ret = ipmi_op(i, ST_STATUS, power_status);
if (ret == STATE_OFF) {
@@ -1169,6 +1201,9 @@ main(int argc, char **argv)
if (!strcasecmp(method, "cycle")) {
ret = ipmi_cycle(i);
translated_ret = (ret==0?ERR_OFF_SUCCESSFUL:ERR_OFF_FAIL);
+ } else if (!strcasecmp(method, "reset")) {
+ ret = ipmi_reset(i);
+ translated_ret = (ret==0?ERR_OFF_SUCCESSFUL:ERR_OFF_FAIL);
} else {
/* Original onoff method */
ret = ipmi_off(i);
diff -urNp fence-agents-3.1.2.orig/fence/agents/ipmilan/ipmilan.c fence-agents-3.1.2/fence/agents/ipmilan/ipmilan.c
--- fence-agents-3.1.2.orig/fence/agents/ipmilan/ipmilan.c 2011-03-26 15:15:58.000000000 +0100
+++ fence-agents-3.1.2/fence/agents/ipmilan/ipmilan.c 2011-03-26 15:19:30.869070840 +0100
@@ -1129,9 +1129,12 @@ main(int argc, char **argv)
}
/* Delay fencing if requested */
- if (delay) {
+ if (delay[0] != '\0') {
if (!strcasecmp(op, "reboot") || !strcasecmp(op, "off")) {
- sleep(atoi(delay));
+ int delay_time = atoi(delay);
+ if (delay_time) {
+ sleep(delay_time);
+ }
}
}
--- fence-agents-3.1.7.orig/fence/agents/ipmilan/ipmilan.c 2011-03-28 11:15:41.052950785 +0200
+++ fence-agents-3.1.7/fence/agents/ipmilan/ipmilan.c 2011-03-28 11:16:16.338820731 +0200
@@ -87,6 +87,7 @@ struct ipmi {
int i_timeout;
int i_power_wait;
int i_cipher;
+ int i_force_ops;
};
@@ -189,7 +190,8 @@ struct xml_parameter_s xml_parameters[]=
{"power_wait","-T",0,0,"string","2","Wait X seconds after on/off operation"},
{"delay","-f",0,0,"string",NULL,"Wait X seconds before fencing is started"},
{"privlvl","-L",0,0,"string",NULL,"Privilege level on IPMI device"},
- {"verbose","-v",0,0,"boolean",NULL,"Verbose mode"}};
+ {"verbose","-v",0,0,"boolean",NULL,"Verbose mode"},
+ {"force","-F",0,0,"boolean",NULL,"Force power operations even if status reports matching power state."}};
/*
Search for ipmitool
@@ -480,7 +482,10 @@ ipmi_off(struct ipmi *ipmi)
case STATE_ON:
break;
case STATE_OFF:
- return 0;
+ if (!ipmi->i_force_ops) {
+ return 0;
+ }
+ break;
default:
return ret;
}
@@ -520,7 +525,10 @@ ipmi_on(struct ipmi *ipmi)
ret = ipmi_op(ipmi, ST_STATUS, power_status);
switch(ret) {
case STATE_ON:
- return 0;
+ if (!ipmi->i_force_ops) {
+ return 0;
+ }
+ break;
case STATE_OFF:
break;
default:
@@ -620,7 +628,7 @@ static struct ipmi *
ipmi_init(struct ipmi *i, char *host, char *authtype,
char *user, char *password, int lanplus, int verbose,int timeout,
int power_wait,
- int cipher, char *privlvl)
+ int cipher, char *privlvl, int force_ops)
{
const char *p;
@@ -698,6 +706,7 @@ ipmi_init(struct ipmi *i, char *host, ch
i->i_timeout = timeout;
i->i_power_wait = power_wait;
i->i_cipher = cipher;
+ i->i_force_ops = force_ops;
return i;
}
@@ -763,7 +772,7 @@ get_options_stdin(char *ip, size_t iplen
int *power_wait,
int *cipher, char *method, int methodlen,
char *delay, size_t delaylen,
- char *privlvl, size_t privlen)
+ char *privlvl, size_t privlen, int *force_ops)
{
char in[256];
int line = 0;
@@ -857,6 +866,8 @@ get_options_stdin(char *ip, size_t iplen
strncpy(delay, val, delaylen);
else
delay[0] = 0;
+ } else if (!strcasecmp(name, "force")) {
+ (*force_ops) = 1;
}
}
@@ -898,7 +909,9 @@ printf(" -f <timeout> Wait X seconds
printf(" -C <cipher> Ciphersuite to use (same as ipmitool -C parameter)\n");
printf(" -M <method> Method to fence (onoff, cycle or reset) (default %s)\n", DEFAULT_METHOD);
printf(" -V Print version and exit\n");
-printf(" -v Verbose mode\n\n");
+printf(" -v Verbose mode\n");
+printf(" -F Force power operations (on, off) even if current status\n"
+ " matches required state\n\n");
printf("If no options are specified, the following options will be read\n");
printf("from standard input (one per line):\n\n");
printf(" auth=<auth> Same as -A\n");
@@ -916,7 +929,8 @@ printf(" power_wait=<time> Same as
printf(" cipher=<cipher> Same as -C\n");
printf(" method=<method> Same as -M\n");
printf(" privlvl=<privlvl> Same as -L\n");
-printf(" verbose Same as -v\n\n");
+printf(" verbose Same as -v\n");
+printf(" force Same as -F\n\n");
exit(1);
}
@@ -984,6 +998,7 @@ main(int argc, char **argv)
char pwd_script[PATH_MAX] = { 0, };
int lanplus=0;
int verbose=0;
+ int force_ops=0;
char *pname = basename(argv[0]);
struct ipmi *i;
int timeout=DEFAULT_TIMEOUT;
@@ -1005,7 +1020,7 @@ main(int argc, char **argv)
/*
Parse command line options if any were specified
*/
- while ((opt = getopt(argc, argv, "A:a:i:l:p:S:Po:vV?hHt:T:C:M:f:L:")) != EOF) {
+ while ((opt = getopt(argc, argv, "A:a:i:l:p:S:Po:vV?hHt:T:C:M:f:L:F")) != EOF) {
switch(opt) {
case 'A':
/* Auth type */
@@ -1077,6 +1092,9 @@ main(int argc, char **argv)
printf("%s\n",
REDHAT_COPYRIGHT);
return 0;
+ case 'F':
+ force_ops=1;
+ break;
default:
usage_exit(pname);
}
@@ -1094,7 +1112,7 @@ main(int argc, char **argv)
&down_sleep,
&cipher, method, sizeof(method),
delay, sizeof(delay),
- privlvl, sizeof(privlvl)) != 0)
+ privlvl, sizeof(privlvl), &force_ops) != 0)
return 1;
}
@@ -1182,7 +1200,7 @@ main(int argc, char **argv)
}
/* Ok, set up the IPMI struct */
- i = ipmi_init(NULL, ip, authtype, user, passwd, lanplus, verbose, timeout, down_sleep, cipher, privlvl);
+ i = ipmi_init(NULL, ip, authtype, user, passwd, lanplus, verbose, timeout, down_sleep, cipher, privlvl, force_ops);
if (!i)
fail_exit("Failed to initialize\n");
--- fence-agents-3.1.7.orig/fence/agents/ipmilan/ipmilan.c 2011-03-28 12:22:26.504946459 +0200
+++ fence-agents-3.1.7/fence/agents/ipmilan/ipmilan.c 2011-03-28 12:16:26.819695689 +0200
@@ -34,6 +34,7 @@
#define DEFAULT_TIMEOUT 20
#define DEFAULT_POWER_WAIT 2
+#define DEFAULT_RECHECK_WAIT 1
#define DEFAULT_METHOD "onoff"
@@ -88,6 +89,8 @@ struct ipmi {
int i_power_wait;
int i_cipher;
int i_force_ops;
+ int i_status_rechecks;
+ int i_recheck_wait;
};
@@ -191,7 +194,9 @@ struct xml_parameter_s xml_parameters[]=
{"delay","-f",0,0,"string",NULL,"Wait X seconds before fencing is started"},
{"privlvl","-L",0,0,"string",NULL,"Privilege level on IPMI device"},
{"verbose","-v",0,0,"boolean",NULL,"Verbose mode"},
- {"force","-F",0,0,"boolean",NULL,"Force power operations even if status reports matching power state."}};
+ {"force","-F",0,0,"boolean",NULL,"Force power operations even if status reports matching power state."},
+ {"rechecks","-R",0,0,"string",NULL,"Number of status re-checks after on and off operations."},
+ {"recheck_wait","-W",0,0,"string",NULL,"Wait X seconds between status re-checks."}};
/*
Search for ipmitool
@@ -476,38 +481,62 @@ static int
ipmi_off(struct ipmi *ipmi)
{
int ret, retries = 7;
+ int status_retries = 3;
+ int successes = 0;
- ret = ipmi_op(ipmi, ST_STATUS, power_status);
- switch(ret) {
- case STATE_ON:
- break;
- case STATE_OFF:
- if (!ipmi->i_force_ops) {
- return 0;
+ if (ipmi->i_status_rechecks > status_retries) {
+ status_retries = ipmi->i_status_rechecks;
+ }
+ while (status_retries>0) {
+ ret = ipmi_op(ipmi, ST_STATUS, power_status);
+ status_retries--;
+ switch(ret) {
+ case STATE_ON:
+ break;
+ case STATE_OFF:
+ if (!ipmi->i_force_ops) {
+ if (successes >= ipmi->i_status_rechecks) {
+ return 0;
+ } else {
+ successes++;
+ }
+ }
+ break;
+ default:
+ return ret;
}
- break;
- default:
- return ret;
+ sleep(ipmi->i_recheck_wait);
}
+ successes = 0;
while (retries>=0) {
- ret = ipmi_op(ipmi, ST_POWEROFF, power_off_complete);
- if (ret != 0)
- return ret;
+ if (successes == 0) {
+ ret = ipmi_op(ipmi, ST_POWEROFF, power_off_complete);
+ if (ret != 0)
+ return ret;
+ sleep(ipmi->i_power_wait);
+ --retries;
+ } else {
+ sleep(ipmi->i_recheck_wait);
+ }
- sleep(ipmi->i_power_wait);
- --retries;
ret = ipmi_op(ipmi, ST_STATUS, power_status);
switch(ret) {
case STATE_OFF:
- return 0;
+ if (successes >= ipmi->i_status_rechecks) {
+ return 0;
+ } else {
+ successes++;
+ continue;
+ }
case EFAULT:
/* We're done. */
retries = 0;
break;
case STATE_ON:
default:
+ successes = 0;
continue;
}
}
@@ -521,38 +550,62 @@ static int
ipmi_on(struct ipmi *ipmi)
{
int ret, retries = 7;
+ int status_retries = 3;
+ int successes = 0;
- ret = ipmi_op(ipmi, ST_STATUS, power_status);
- switch(ret) {
- case STATE_ON:
- if (!ipmi->i_force_ops) {
- return 0;
+ if (ipmi->i_status_rechecks > status_retries) {
+ status_retries = ipmi->i_status_rechecks;
+ }
+ while (status_retries>0) {
+ ret = ipmi_op(ipmi, ST_STATUS, power_status);
+ status_retries--;
+ switch(ret) {
+ case STATE_ON:
+ if (!ipmi->i_force_ops) {
+ if (successes >= ipmi->i_status_rechecks) {
+ return 0;
+ } else {
+ successes++;
+ }
+ }
+ break;
+ case STATE_OFF:
+ break;
+ default:
+ return ret;
}
- break;
- case STATE_OFF:
- break;
- default:
- return ret;
+ sleep(ipmi->i_recheck_wait);
}
+ successes = 0;
while (retries>=0) {
- ret = ipmi_op(ipmi, ST_POWERON, power_on_complete);
- if (ret != 0)
- return ret;
+ if (successes == 0) {
+ ret = ipmi_op(ipmi, ST_POWERON, power_on_complete);
+ if (ret != 0)
+ return ret;
+ sleep(ipmi->i_power_wait);
+ --retries;
+ } else {
+ sleep(ipmi->i_recheck_wait);
+ }
- sleep(ipmi->i_power_wait);
- --retries;
ret = ipmi_op(ipmi, ST_STATUS, power_status);
switch(ret) {
case STATE_ON:
- return 0;
+ if (successes >= ipmi->i_status_rechecks) {
+ return 0;
+ } else {
+ successes++;
+ continue;
+ }
case EFAULT:
/* We're done. */
retries = 0;
break;
case STATE_OFF:
default:
+ successes = 0;
continue;
}
}
@@ -628,7 +681,7 @@ static struct ipmi *
ipmi_init(struct ipmi *i, char *host, char *authtype,
char *user, char *password, int lanplus, int verbose,int timeout,
int power_wait,
- int cipher, char *privlvl, int force_ops)
+ int cipher, char *privlvl, int force_ops, int status_rechecks, int recheck_wait)
{
const char *p;
@@ -707,7 +760,8 @@ ipmi_init(struct ipmi *i, char *host, ch
i->i_power_wait = power_wait;
i->i_cipher = cipher;
i->i_force_ops = force_ops;
-
+ i->i_status_rechecks = status_rechecks;
+ i->i_recheck_wait = recheck_wait;
return i;
}
@@ -772,7 +826,9 @@ get_options_stdin(char *ip, size_t iplen
int *power_wait,
int *cipher, char *method, int methodlen,
char *delay, size_t delaylen,
- char *privlvl, size_t privlen, int *force_ops)
+ char *privlvl, size_t privlen,
+ int *force_ops,
+ int *status_rechecks, int *recheck_wait)
{
char in[256];
int line = 0;
@@ -868,6 +924,10 @@ get_options_stdin(char *ip, size_t iplen
delay[0] = 0;
} else if (!strcasecmp(name, "force")) {
(*force_ops) = 1;
+ } else if (!strcasecmp(name, "rechecks")) {
+ sscanf(val,"%d",status_rechecks);
+ } else if (!strcasecmp(name, "recheck_wait")) {
+ sscanf(val,"%d",recheck_wait);
}
}
@@ -911,7 +971,10 @@ printf(" -M <method> Method to fenc
printf(" -V Print version and exit\n");
printf(" -v Verbose mode\n");
printf(" -F Force power operations (on, off) even if current status\n"
- " matches required state\n\n");
+ " matches required state\n");
+printf(" -R <number> Re-check power status X times before changing power status\n"
+ " and until X successes after changing it\n");
+printf(" -W <timeout> Wait X seconds betweet power status checks operations\n\n");
printf("If no options are specified, the following options will be read\n");
printf("from standard input (one per line):\n\n");
printf(" auth=<auth> Same as -A\n");
@@ -930,7 +993,9 @@ printf(" cipher=<cipher> Same as
printf(" method=<method> Same as -M\n");
printf(" privlvl=<privlvl> Same as -L\n");
printf(" verbose Same as -v\n");
-printf(" force Same as -F\n\n");
+printf(" force Same as -F\n");
+printf(" recheck=<number> Same as -R\n");
+printf(" recheck_wait=<time> Same as -W\n\n");
exit(1);
}
@@ -999,6 +1064,8 @@ main(int argc, char **argv)
int lanplus=0;
int verbose=0;
int force_ops=0;
+ int status_rechecks=0;
+ int recheck_wait=DEFAULT_RECHECK_WAIT;
char *pname = basename(argv[0]);
struct ipmi *i;
int timeout=DEFAULT_TIMEOUT;
@@ -1020,7 +1087,7 @@ main(int argc, char **argv)
/*
Parse command line options if any were specified
*/
- while ((opt = getopt(argc, argv, "A:a:i:l:p:S:Po:vV?hHt:T:C:M:f:L:F")) != EOF) {
+ while ((opt = getopt(argc, argv, "A:a:i:l:p:S:Po:vV?hHt:T:C:M:f:L:FR:W:")) != EOF) {
switch(opt) {
case 'A':
/* Auth type */
@@ -1095,6 +1162,16 @@ main(int argc, char **argv)
case 'F':
force_ops=1;
break;
+ case 'R':
+ if ((sscanf(optarg,"%d",&status_rechecks)!=1) || status_rechecks<1) {
+ fail_exit("Status re-checks option expects positive number parameter");
+ }
+ break;
+ case 'W':
+ if ((sscanf(optarg,"%d",&recheck_wait)!=1) || recheck_wait<1) {
+ fail_exit("Re-check wait time option expects positive number parameter");
+ }
+ break;
default:
usage_exit(pname);
}
@@ -1112,7 +1189,8 @@ main(int argc, char **argv)
&down_sleep,
&cipher, method, sizeof(method),
delay, sizeof(delay),
- privlvl, sizeof(privlvl), &force_ops) != 0)
+ privlvl, sizeof(privlvl), &force_ops,
+ &status_rechecks, &recheck_wait) != 0)
return 1;
}
@@ -1200,7 +1278,8 @@ main(int argc, char **argv)
}
/* Ok, set up the IPMI struct */
- i = ipmi_init(NULL, ip, authtype, user, passwd, lanplus, verbose, timeout, down_sleep, cipher, privlvl, force_ops);
+ i = ipmi_init(NULL, ip, authtype, user, passwd, lanplus, verbose, timeout, down_sleep, cipher,
+ privlvl, force_ops, status_rechecks, recheck_wait);
if (!i)
fail_exit("Failed to initialize\n");
--
Linux-cluster mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/linux-cluster