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 <aderumier@xxxxxxxxx> > To: ccaulfie@xxxxxxxxxx > > 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 > aderumier@xxxxxxxxx > > > > > > > > > > > -- > Linux-cluster mailing list > Linux-cluster@xxxxxxxxxx > 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 Linux-cluster@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/linux-cluster