public inbox for cluster-cvs@sourceware.org
help / color / mirror / Atom feed
From: Jan Friesse <honzaf@fedoraproject.org>
To: cluster-cvs-relay@redhat.com
Subject: cluster: STABLE2 - fence: Support for power cycle in fence ipmi
Date: Tue, 01 Sep 2009 10:41:00 -0000	[thread overview]
Message-ID: <20090901104011.E41D812037C@lists.fedorahosted.org> (raw)

Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=b4d4b6137c13f5fb4e267cffbb97e0e885fef617
Commit:        b4d4b6137c13f5fb4e267cffbb97e0e885fef617
Parent:        275adfb353d1cc975772dcd4d6687de16a1ab223
Author:        Jan Friesse <jfriesse@redhat.com>
AuthorDate:    Mon Jul 20 13:47:52 2009 +0200
Committer:     Jan Friesse <jfriesse@redhat.com>
CommitterDate: Tue Sep 1 12:38:35 2009 +0200

fence: Support for power cycle in fence ipmi

Default behaviour (off/get status/on) doesn't work on
some IPMI implementations, because chasiss power off will
turn off IPMI management card. Next power on cannot be
done automatically. But it looks, like chassis power cycle
is supported and do what we need -> reset machine.

Patch add support for -M (method) option, which can have
values:
- onoff - default old behaviour
- cycle - use new power cycle

rhbz#482913
---
 fence/agents/ipmilan/ipmilan.c |   85 ++++++++++++++++++++++++++++++++++++----
 fence/man/fence_ipmilan.8      |   10 +++++
 2 files changed, 87 insertions(+), 8 deletions(-)

diff --git a/fence/agents/ipmilan/ipmilan.c b/fence/agents/ipmilan/ipmilan.c
index 6e43a8b..0deabe4 100644
--- a/fence/agents/ipmilan/ipmilan.c
+++ b/fence/agents/ipmilan/ipmilan.c
@@ -25,9 +25,12 @@
 #define ST_POWERON 1
 #define ST_POWEROFF 2
 #define ST_GENERIC_RESET 3
+#define ST_CYCLE 4
 
 #define DEFAULT_TIMEOUT 10
 
+#define DEFAULT_METHOD "onoff"
+
 #define log(lvl, fmt, args...) fprintf(stderr, fmt, ##args)
 #include <libgen.h>
 #include <copyright.cf>
@@ -82,7 +85,7 @@ const char *ipmitool_paths[] = {
 
 
 #define ECIPHER 2048
-
+#define ESTATE (8192*2)
 static struct Etoken power_on_complete[] = {
 	{"Password:", EPERM, 0},
 	{"Unable to establish LAN", EAGAIN, 0},	/* Retry */
@@ -103,6 +106,17 @@ static struct Etoken power_off_complete[] = {
 	{NULL, 0, 0}
 };
 
+/** Powercycle operation */
+static struct Etoken power_cycle_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},
+	{": Cycle", 0, 0},
+	{NULL, 0, 0}
+};
 
 #define STATE_OFF 4096
 #define STATE_ON  8192
@@ -245,6 +259,10 @@ build_cmd(char *command, size_t cmdlen, struct ipmi *ipmi, int op)
 		snprintf(arg, sizeof(arg),
 			 "%s chassis power status", cmd);
 		break;
+	case ST_CYCLE:
+		snprintf(arg, sizeof(arg),
+			 "%s chassis power cycle", cmd);
+		break;
 	}
 
 	strncpy(command, arg, cmdlen);
@@ -353,6 +371,12 @@ ipmi_op(struct ipmi *ipmi, int op, struct Etoken *toklist)
 		return ret;
 	}
 
+	if (ret == ESTATE) {
+		log(LOG_CRIT, "ipmilan: ipmitool failed to complete "
+		    "command in current state\n");
+		return ret;
+	}
+
 	if (ret == ETIMEDOUT) {
 		/*!!! Still couldn't get through?! */
 		log(LOG_WARNING,
@@ -446,6 +470,16 @@ ipmi_on(struct ipmi *ipmi)
 	return ret;
 }
 
+static int
+ipmi_cycle(struct ipmi *ipmi)
+{
+	int ret;
+
+	ret = ipmi_op(ipmi, ST_CYCLE, power_cycle_complete);
+
+	return ret;
+}
+
 
 /**
   Squash all our private data
@@ -614,13 +648,14 @@ get_options_stdin(char *ip, size_t iplen,
 		  char *user, size_t userlen,
 		  char *op, size_t oplen,
 		  int *lanplus, int *verbose,int *timeout,
-	          int *cipher)
+	          int *cipher, char *method, int methodlen)
 {
 	char in[256];
 	int line = 0;
 	char *name, *val;
 
 	op[0] = 0;
+	method[0] = 0;
 
 	while (fgets(in, sizeof(in), stdin)) {
 		++line;
@@ -684,6 +719,8 @@ get_options_stdin(char *ip, size_t iplen,
 			if ((sscanf(val,"%d",cipher)!=1) || *cipher<0) {
 			    *cipher=-1;
 			}
+		} else if (!strcasecmp(name,"method")) {
+			strncpy (method, val, methodlen);
 		} else if (!strcasecmp(name, "option") ||
 			   !strcasecmp(name, "operation") ||
 			   !strcasecmp(name, "action")) {
@@ -725,6 +762,7 @@ printf("   -o <op>        Operation to perform.\n");
 printf("                  Valid operations: on, off, reboot, status\n");
 printf("   -t <timeout>   Timeout (sec) for IPMI operation (default %d)\n",DEFAULT_TIMEOUT);
 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("   -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");
@@ -740,6 +778,7 @@ printf("   operation=<op>        Same as -o\n");
 printf("   action=<op>           Same as -o\n");
 printf("   timeout=<timeout>     Same as -t\n");
 printf("   cipher=<cipher>       Same as -C\n");
+printf("   method=<method>       Same as -M\n");
 printf("   verbose               Same as -v\n\n");
 	exit(1);
 }
@@ -755,6 +794,7 @@ main(int argc, char **argv)
 	char passwd[64];
 	char user[64];
 	char op[64];
+	char method[64];
 	char pwd_script[PATH_MAX] = { 0, };
 	int lanplus=0;
 	int verbose=0;
@@ -773,7 +813,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:C:")) != EOF) {
+		while ((opt = getopt(argc, argv, "A:a:i:l:p:S:Po:vV?hHt:C:M:")) != EOF) {
 			switch(opt) {
 			case 'A':
 				/* Auth type */
@@ -815,6 +855,10 @@ main(int argc, char **argv)
 				    fail_exit("Ciphersuite option expects positive number parameter");
 				}
 				break;
+			case 'M':
+				/* Reboot method */
+				strncpy(method, optarg, sizeof(method));
+				break;
 			case 'v':
 				verbose++;
 				break;
@@ -839,7 +883,7 @@ main(int argc, char **argv)
 					  pwd_script, sizeof(pwd_script),
 				      user, sizeof(user),
 				      op, sizeof(op), &lanplus, &verbose,&timeout,
-				      &cipher) != 0)
+				      &cipher, method, sizeof(method)) != 0)
 			return 1;
 	}
 
@@ -873,6 +917,9 @@ main(int argc, char **argv)
 	if (!strlen(op))
 		snprintf(op,sizeof(op), "reboot");
 
+	if (!strlen(method))
+		snprintf(method, sizeof(method), "onoff");
+
 	if (strcasecmp(op, "off") && strcasecmp(op, "on") &&
 	    strcasecmp(op, "status") && strcasecmp(op, "reboot")) {
 		fail_exit("operation must be 'on', 'off', 'status', "
@@ -887,6 +934,15 @@ main(int argc, char **argv)
 			  " 'none'.");
 	}
 
+	if (strcasecmp(method, "onoff") &&
+	    strcasecmp(method, "cycle")) {
+		fail_exit("method, if included, muse be 'onoff', 'cycle'.");
+	}
+
+	if (!strcasecmp(method, "cycle") &&
+	    (!strcasecmp(op, "on") || !strcasecmp(op, "off"))) {
+		fail_exit("cycle method supports only 'reboot' operation (not 'on' or 'off').");
+	}
 
 	/* Ok, set up the IPMI struct */
 	i = ipmi_init(NULL, ip, authtype, user, passwd, lanplus, verbose, timeout, cipher);
@@ -899,11 +955,24 @@ main(int argc, char **argv)
 	if (!strcasecmp(op, "reboot")) {
 		printf("Rebooting machine @ IPMI:%s...", ip);
 		fflush(stdout);
-		ret = ipmi_off(i);
-		if (ret != 0)
-			goto out;
-		ret = ipmi_on(i);
+		if (!strcasecmp(method, "cycle")) {
+			ret = ipmi_op(i, ST_STATUS, power_status);
 
+			if (ret == STATE_OFF) {
+				/* State is off -> use onoff method because cycle is not able to turn on*/
+				snprintf(method, sizeof(method), "onoff");
+			}
+		}
+
+		if (!strcasecmp(method, "cycle")) {
+			ret = ipmi_cycle(i);
+		} else {
+			/* Original onoff method */
+			ret = ipmi_off(i);
+			if (ret != 0)
+				goto out;
+			ret = ipmi_on(i);
+		}
 	} else if (!strcasecmp(op, "on")) {
 		printf("Powering on machine @ IPMI:%s...", ip);
 		fflush(stdout);
diff --git a/fence/man/fence_ipmilan.8 b/fence/man/fence_ipmilan.8
index 19efa99..98006f6 100644
--- a/fence/man/fence_ipmilan.8
+++ b/fence/man/fence_ipmilan.8
@@ -49,6 +49,11 @@ If you are using lanplus, this option avails you to define type of ciphersuite t
 use. Standard is 3 (defined if you just use lanplus). For more information please
 refer ipmitool man page (option -C).
 .TP
+\fB-M\fP \fImethod\fP
+Method to fence (onoff or cycle). Default is onoff. Use cycle in case your management
+card will power off with default method so there will be no chance to power machine
+on by IPMI.
+.TP
 \fB-t\fP \fItimeout\fP
 Timeout in seconds for IPMI operation. Default is 10, but in some cases it
 must be set to higher value (anything above 30 is not recommended and may
@@ -93,6 +98,11 @@ If you are using lanplus, this option avails you to define type of ciphersuite t
 use. Standard is 3 (defined if you just use lanplus). For more information please
 refer ipmitool man page (option -C).
 .TP
+\fImethod = < param >\fR
+Method to fence (onoff or cycle). Default is onoff. Use cycle in case your management
+card will power off with default method so there will be no chance to power machine
+on by IPMI.
+.TP
 \fIlanplus\fR
 If we are using the lanplus option for ipmitool
 


                 reply	other threads:[~2009-09-01 10:41 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090901104011.E41D812037C@lists.fedorahosted.org \
    --to=honzaf@fedoraproject.org \
    --cc=cluster-cvs-relay@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).