From bab42c2b278dc3006f22155c1bec0e62fdf4eee9 Mon Sep 17 00:00:00 2001 From: Marek 'marx' Grac <mgrac@redhat.com> Date: Fri, 23 Apr 2010 14:35:13 +0200 Subject: [PATCH] fence_ipmilan: Correct exit codes for status operation According to standard operation status should return 0 (if ON) and 2 (if OFF). In all other cases if operation was succesfull then agent return 0. Resolves: rhbz#583034 (partially) --- fence/agents/ipmilan/ipmilan.c | 107 ++++++++++++++++++++++++++++++++++------ 1 files changed, 92 insertions(+), 15 deletions(-) diff --git a/fence/agents/ipmilan/ipmilan.c b/fence/agents/ipmilan/ipmilan.c index d8d76ff..d16dfc9 100644 --- a/fence/agents/ipmilan/ipmilan.c +++ b/fence/agents/ipmilan/ipmilan.c @@ -57,6 +57,19 @@ do { \ #define DEFAULT_METHOD "onoff" +/* We should follow FenceAgentsAPI standard*/ +#define ERR_OFF_SUCCESSFUL 0 +#define ERR_OFF_FAIL 1 + +#define ERR_ON_SUCCESSFUL 0 +#define ERR_ON_FAIL 1 + +#define ERR_STATUS_ON 0 +#define ERR_STATUS_FAIL 1 +#define ERR_STATUS_OFF 2 + +#define ERR_OK 0 + #define log(lvl, fmt, args...) fprintf(stderr, fmt, ##args) #include <libgen.h> @@ -165,6 +178,24 @@ static struct Etoken power_status[] = { {NULL, 0, 0} }; +/* Structure describing one xml metadata value*/ +struct xml_parameter_s { + char *name; + char *description; +}; + +/* Array of xml metadatas*/ +struct xml_parameter_s xml_parameters[]={ + {"auth","IPMI Lan Auth type (md5, password, or none)"}, + {"ipaddr","IPMI Lan IP to talk to"}, + {"passwd","Password (if required) to control power on IPMI device"}, + {"passwd_script","Script to retrieve password (if required)"}, + {"lanplus","Use Lanplus"}, + {"login","Username/Login (if required) to control power on IPMI device"}, + {"action","Operation to perform. Valid operations: on, off, reboot, status, list, monitor or metadata"}, + {"timeout","Timeout (sec) for IPMI operation"}, + {"cipher","Ciphersuite to use (same as ipmitool -C parameter)"}, + {"verbose","Verbose mode"}}; /* Search for ipmitool @@ -1015,7 +1046,7 @@ printf(" -S <path> Script to retrieve password (if required)\n"); printf(" -l <login> Username/Login (if required) to control power\n" " on IPMI device\n"); printf(" -o <op> Operation to perform.\n"); -printf(" Valid operations: on, off, reboot, status\n"); +printf(" Valid operations: on, off, reboot, status, list or monitor\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); @@ -1040,6 +1071,26 @@ printf(" verbose Same as -v\n\n"); } +/** Print XML metadata of fence agent*/ +void print_xml_metadata(char *pname) { + int i; + + printf("%s\n","<?xml version=\"1.0\" ?>"); + printf("%s%s%s\n","<resource-agent name=\"",pname,"\" >"); + 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\t<shortdesc lang=\"C\">"); + printf("%s",xml_parameters[i].description); + printf("</shortdesc>\n"); + printf("\t</parameter>\n"); + } + printf("%s\n","</parameters>"); + printf("%s\n","</resource-agent>"); +} + int main(int argc, char **argv) { @@ -1057,7 +1108,9 @@ main(int argc, char **argv) char *pname = basename(argv[0]); struct ipmi *i; int timeout=DEFAULT_TIMEOUT; - int cipher=-1; + int cipher=-1; + int print_final_status=1; + int translated_ret = -1; memset(ip, 0, sizeof(ip)); memset(authtype, 0, sizeof(authtype)); @@ -1178,9 +1231,11 @@ main(int argc, char **argv) snprintf(method, sizeof(method), "onoff"); if (strcasecmp(op, "off") && strcasecmp(op, "on") && - strcasecmp(op, "status") && strcasecmp(op, "reboot")) { + strcasecmp(op, "status") && strcasecmp(op, "reboot") && + strcasecmp(op, "monitor") && strcasecmp(op, "list") && + strcasecmp(op, "metadata")) { fail_exit("operation must be 'on', 'off', 'status', " - "or 'reboot'"); + "'reboot', 'list', 'monitor' or 'metadata'"); } if (strlen(authtype) && @@ -1226,47 +1281,69 @@ main(int argc, char **argv) } else { /* Original onoff method */ ret = ipmi_off(i); - if (ret != 0) + translated_ret = (ret==0?ERR_OFF_SUCCESSFUL:ERR_OFF_FAIL); + if (ret != 0) { goto out; + } ret = ipmi_on(i); } } else if (!strcasecmp(op, "on")) { printf("Powering on machine @ IPMI:%s...", ip); fflush(stdout); ret = ipmi_on(i); - + translated_ret = (ret==0?ERR_ON_SUCCESSFUL:ERR_ON_FAIL); } else if (!strcasecmp(op, "off")) { printf("Powering off machine @ IPMI:%s...", ip); fflush(stdout); ret = ipmi_off(i); - } else if (!strcasecmp(op, "status")) { + translated_ret = (ret==0?ERR_ON_SUCCESSFUL:ERR_ON_FAIL); + } else if (!strcasecmp(op, "status") || !strcasecmp(op, "monitor")) { printf("Getting status of IPMI:%s...",ip); fflush(stdout); ret = ipmi_op(i, ST_STATUS, power_status); switch(ret) { case STATE_ON: - printf("Chassis power = On\n"); + if (!strcasecmp(op, "status")) + printf("Chassis power = On\n"); + translated_ret = ERR_STATUS_ON; ret = 0; break; case STATE_OFF: - printf("Chassis power = Off\n"); + if (!strcasecmp(op, "status")) + printf("Chassis power = Off\n"); + translated_ret = ERR_STATUS_OFF; ret = 0; break; default: - printf("Chassis power = Unknown\n"); + if (!strcasecmp(op, "status")) + printf("Chassis power = Unknown\n"); + translated_ret = ERR_STATUS_FAIL; ret = 1; break; } + } else if (!strcasecmp(op, "list")) { + printf("%s\n","N/A"); + ret=0; + translated_ret = ERR_OK; + print_final_status=0; + } else if (!strcasecmp(op, "metadata")) { + print_xml_metadata(pname); + ret=0; + translated_ret = ERR_OK; + print_final_status=0; } out: ipmi_destroy(i); free(i); - if (ret == 0) - printf("Done\n"); - else - printf("Failed\n"); - return ret; + + if (print_final_status) { + if (ret == 0) + printf("Done\n"); + else + printf("Failed\n"); + } + return translated_ret; } #endif /* fence */ -- 1.6.0.6