diff options
Diffstat (limited to 'lib/plugins/stonith/drac3.c')
-rw-r--r-- | lib/plugins/stonith/drac3.c | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/lib/plugins/stonith/drac3.c b/lib/plugins/stonith/drac3.c new file mode 100644 index 0000000..95be775 --- /dev/null +++ b/lib/plugins/stonith/drac3.c @@ -0,0 +1,359 @@ +/* + * Stonith module for Dell DRACIII (Dell Remote Access Card) + * + * Copyright (C) 2003 Alfa21 Outsourcing + * Copyright (C) 2003 Roberto Moreda <moreda@alfa21.com> + * Tiny bits Copyright 2005 International Business Machines + * Significantly Mangled by Sun Jiang Dong <sunjd@cn.ibm.com>, IBM, 2005 + * + * (Using snippets of other stonith modules code) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#define DEVICE "Dell DRACIII Card" +#include "stonith_plugin_common.h" + +#include <curl/curl.h> +#include "drac3_command.h" + +#define PIL_PLUGIN drac3 +#define PIL_PLUGIN_S "drac3" +#define PIL_PLUGINLICENSE LICENSE_LGPL +#define PIL_PLUGINLICENSEURL URL_LGPL +#include <pils/plugin.h> +#include "stonith_signal.h" + +static StonithPlugin * drac3_new(const char *); +static void drac3_destroy(StonithPlugin *); +static const char * const * drac3_get_confignames(StonithPlugin *); +static int drac3_set_config(StonithPlugin *, StonithNVpair *); +static const char * drac3_getinfo(StonithPlugin * s, int InfoType); +static int drac3_status(StonithPlugin * ); +static int drac3_reset_req(StonithPlugin * s, int request, const char * host); +static char ** drac3_hostlist(StonithPlugin *); + +static struct stonith_ops drac3Ops ={ + drac3_new, /* Create new STONITH object */ + drac3_destroy, /* Destroy STONITH object */ + drac3_getinfo, /* Return STONITH info string */ + drac3_get_confignames, /* Return configuration parameters */ + drac3_set_config, /* Set configuration */ + drac3_status, /* Return STONITH device status */ + drac3_reset_req, /* Request a reset */ + drac3_hostlist, /* Return list of supported hosts */ +}; + +PIL_PLUGIN_BOILERPLATE2("1.0", Debug) +static const PILPluginImports* PluginImports; +static PILPlugin* OurPlugin; +static PILInterface* OurInterface; +static StonithImports* OurImports; +static void* interfprivate; + +PIL_rc +PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports); + +PIL_rc +PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports) +{ + /* Force the compiler to do a little type checking */ + (void)(PILPluginInitFun)PIL_PLUGIN_INIT; + + PluginImports = imports; + OurPlugin = us; + + /* Register ourself as a plugin */ + imports->register_plugin(us, &OurPIExports); + + /* Register our interface implementation */ + return imports->register_interface(us, PIL_PLUGINTYPE_S + , PIL_PLUGIN_S + , &drac3Ops + , NULL /*close */ + , &OurInterface + , (void*)&OurImports + , &interfprivate); +} + +#define BUFLEN 1024 +#define ST_HOST "host" + +struct pluginDevice { + StonithPlugin sp; + const char *pluginid; + const char *idinfo; + CURL *curl; + char *host; + char *user; + char *pass; +}; + +static const char *pluginid = "Dell-DRACIII-Stonith"; +static const char *NOTpluginID = "Dell DRACIII device has been destroyed"; + +#include "stonith_config_xml.h" + +#define XML_HOST_SHORTDESC \ + XML_PARM_SHORTDESC_BEGIN("en") \ + ST_HOST \ + XML_PARM_SHORTDESC_END + +#define XML_HOST_LONGDESC \ + XML_PARM_LONGDESC_BEGIN("en") \ + "The hostname of the STONITH device" \ + XML_PARM_LONGDESC_END + +#define XML_HOST_PARM \ + XML_PARAMETER_BEGIN(ST_HOST, "string", "1", "1") \ + XML_HOST_SHORTDESC \ + XML_HOST_LONGDESC \ + XML_PARAMETER_END + +static const char *drac3XML = + XML_PARAMETERS_BEGIN + XML_HOST_PARM + XML_LOGIN_PARM + XML_PASSWD_PARM + XML_PARAMETERS_END; + +/* ------------------------------------------------------------------ */ +/* STONITH PLUGIN API */ +/* ------------------------------------------------------------------ */ +static StonithPlugin * +drac3_new(const char *subplugin) +{ + struct pluginDevice *drac3d = ST_MALLOCT(struct pluginDevice); + + if (drac3d == NULL) { + LOG(PIL_CRIT, "out of memory"); + return(NULL); + } + memset(drac3d, 0, sizeof(*drac3d)); + drac3d->pluginid = pluginid; + drac3d->curl = curl_easy_init(); + drac3InitCurl(drac3d->curl); + drac3d->host = NULL; + drac3d->user = NULL; + drac3d->pass = NULL; + drac3d->idinfo = DEVICE; + drac3d->sp.s_ops = &drac3Ops; + return (&(drac3d->sp)); +} + +/* ------------------------------------------------------------------ */ +static void +drac3_destroy(StonithPlugin * s) +{ + struct pluginDevice *drac3d; + + VOIDERRIFWRONGDEV(s); + + drac3d = (struct pluginDevice *) s; + + drac3d->pluginid = NOTpluginID; + + /* release curl connection */ + if (drac3d->curl != NULL) { + drac3Logout(drac3d->curl, drac3d->host); + curl_easy_cleanup(drac3d->curl); + drac3d->curl = NULL; + } + + if (drac3d->host != NULL) { + FREE(drac3d->host); + drac3d->host = NULL; + } + if (drac3d->user != NULL) { + FREE(drac3d->user); + drac3d->user = NULL; + } + if (drac3d->pass != NULL) { + FREE(drac3d->pass); + drac3d->pass = NULL; + } + + /* release stonith-object itself */ + FREE(drac3d); +} + +/* ------------------------------------------------------------------ */ +static const char * const * +drac3_get_confignames(StonithPlugin * s) +{ + static const char * ret[] = {ST_HOST, ST_LOGIN, ST_PASSWD, NULL}; + return ret; +} + +/* ------------------------------------------------------------------ */ +static int +drac3_set_config(StonithPlugin * s, StonithNVpair * list) +{ + struct pluginDevice* sd = (struct pluginDevice *)s; + int rc; + StonithNamesToGet namestocopy [] = + { {ST_HOST, NULL} + , {ST_LOGIN, NULL} + , {ST_PASSWD, NULL} + , {NULL, NULL} + }; + + ERRIFWRONGDEV(s, S_OOPS); + if (sd->sp.isconfigured) { + return S_OOPS; + } + + if ((rc=OurImports->CopyAllValues(namestocopy, list)) != S_OK) { + return rc; + } + sd->host = namestocopy[0].s_value; + sd->user = namestocopy[1].s_value; + sd->pass = namestocopy[2].s_value; + + return(S_OK); +} + +/* ------------------------------------------------------------------ */ +const char * +drac3_getinfo(StonithPlugin * s, int reqtype) +{ + struct pluginDevice *drac3d; + const char *ret = NULL; + + ERRIFWRONGDEV(s,NULL); + + drac3d = (struct pluginDevice *) s; + + switch (reqtype) { + case ST_DEVICEID: + ret = drac3d->idinfo; + break; + case ST_DEVICENAME: + ret = drac3d->host; + break; + case ST_DEVICEDESCR: + ret = "Dell DRACIII (via HTTPS)\n" + "The Dell Remote Access Controller accepts XML " + "commands over HTTPS"; + break; + case ST_DEVICEURL: + ret = "http://www.dell.com/"; + break; + case ST_CONF_XML: /* XML metadata */ + ret = drac3XML; + break; + default: + ret = NULL; + break; + } + + return(ret); +} + +/* ------------------------------------------------------------------ */ +int +drac3_status(StonithPlugin *s) +{ + struct pluginDevice *drac3d; + + ERRIFNOTCONFIGED(s,S_OOPS); + + drac3d = (struct pluginDevice *) s; + + if (drac3VerifyLogin(drac3d->curl, drac3d->host)) { + if (drac3Login(drac3d->curl, drac3d->host, + drac3d->user, drac3d->pass)) { + LOG(PIL_CRIT, "%s: cannot log into %s at %s", + __FUNCTION__, + drac3d->idinfo, + drac3d->host); + return(S_ACCESS); + } + } + + if (drac3GetSysInfo(drac3d->curl, drac3d->host)) { + return(S_ACCESS); + }else{ + return(S_OK); + } +} + +/* ------------------------------------------------------------------ */ +int +drac3_reset_req(StonithPlugin * s, int request, const char *host) +{ + struct pluginDevice *drac3d; + int rc = S_OK; + + ERRIFNOTCONFIGED(s,S_OOPS); + + drac3d = (struct pluginDevice *) s; + + if (strcasecmp(host, drac3d->host)) { + LOG(PIL_CRIT, "%s doesn't control host [%s]" + , drac3d->idinfo, host); + return(S_BADHOST); + } + + if (drac3VerifyLogin(drac3d->curl, drac3d->host)) { + if (drac3Login(drac3d->curl, drac3d->host, + drac3d->user, drac3d->pass)) { + LOG(PIL_CRIT, "%s: cannot log into %s at %s", + __FUNCTION__, + drac3d->idinfo, + drac3d->host); + return(S_ACCESS); + } + } + + switch(request) { +#if defined(ST_POWERON) && defined(ST_POWEROFF) + case ST_POWERON: + case ST_POWEROFF: + /* TODO... */ +#endif + case ST_GENERIC_RESET: + if (drac3PowerCycle(drac3d->curl, drac3d->host)) + rc = S_ACCESS; + break; + default: + rc = S_INVAL; + break; + } + + return(rc); +} + +/* ------------------------------------------------------------------ */ +char ** +drac3_hostlist(StonithPlugin * s) +{ + struct pluginDevice *drac3d; + char **hl; + + ERRIFNOTCONFIGED(s,NULL); + + drac3d = (struct pluginDevice *) s; + + hl = OurImports->StringToHostList(drac3d->host); + if (hl == NULL) { + LOG(PIL_CRIT, "%s: out of memory", __FUNCTION__); + } else { + strdown(hl[0]); + } + + return(hl); +} |