static int external_status(StonithPlugin *s) { struct pluginDevice * sd; const char * op = "status"; int rc; if (Debug) { LOG(PIL_DEBUG, "%s: called.", __FUNCTION__); } ERRIFWRONGDEV(s,S_OOPS); sd = (struct pluginDevice*) s; if (sd->subplugin == NULL) { LOG(PIL_CRIT, "%s: invoked without subplugin", __FUNCTION__); return(S_OOPS); } rc = external_run_cmd(sd, op, NULL); if (rc != 0) { LOG(PIL_CRIT, "%s: '%s %s' failed with rc %d", __FUNCTION__, sd->subplugin, op, rc); } else { if (Debug) { LOG(PIL_DEBUG, "%s: running '%s %s' returned %d", __FUNCTION__, sd->subplugin, op, rc); } } return rc; }
/* * Pretend to reset the given host on this Stonith device. * (we don't even error check the "request" type) */ static int riloe_reset_req(StonithPlugin * s, int request, const char * host) { char cmd[4096]; if (Debug) { LOG(PIL_DEBUG, "%s:called.", __FUNCTION__); } ERRIFWRONGDEV(s,S_OOPS); if (Debug) { LOG(PIL_DEBUG, "%s:called.", __FUNCTION__); } snprintf(cmd, sizeof(cmd), "%s %s reset", RILOE_COMMAND, host); if (Debug) { LOG(PIL_DEBUG, "command %s will be executed", cmd); } if (system(cmd) == 0) { return S_OK; } else { LOG(PIL_CRIT, "command %s failed", cmd); return(S_RESETFAIL); } }
/* * Return STONITH info string */ static const char * meatware_getinfo(StonithPlugin * s, int reqtype) { struct pluginDevice* nd; const char * ret; ERRIFWRONGDEV(s,NULL); /* * We look in the ST_TEXTDOMAIN catalog for our messages */ nd = (struct pluginDevice *)s; switch (reqtype) { case ST_DEVICEID: ret = nd->idinfo; break; case ST_DEVICENAME: ret = "Your Name Here"; break; case ST_DEVICEDESCR: ret = "Human (meatware) intervention STONITH device.\n" "This STONITH agent prompts a human to reset a machine.\n" "The human tells it when the reset was completed."; break; case ST_CONF_XML: /* XML metadata */ ret = meatwareXML; break; default: ret = NULL; break; } return ret; }
/* * Parse the information in the given string, * and stash it away... */ static int riloe_set_config(StonithPlugin* s, StonithNVpair *list) { StonithNamesToGet namestocopy [] = { {ST_HOSTLIST, NULL} , {NULL, NULL} }; struct pluginDevice* nd; int rc; if (Debug) { LOG(PIL_DEBUG, "%s:called.", __FUNCTION__); } ERRIFWRONGDEV(s,S_OOPS); nd = (struct pluginDevice*) s; if ((rc = OurImports->CopyAllValues(namestocopy, list)) != S_OK) { return rc; } rc = RILOE_parse_config_info(nd , namestocopy[0].s_value); FREE(namestocopy[0].s_value); return rc; }
/* * Parse the config information in the given string, and stash it away... */ static int baytech_set_config(StonithPlugin* s, StonithNVpair* list) { struct pluginDevice* bt = (struct pluginDevice *)s; int rc; StonithNamesToGet namestocopy [] = { {ST_IPADDR, NULL} , {ST_LOGIN, NULL} , {ST_PASSWD, NULL} , {NULL, NULL} }; ERRIFWRONGDEV(s, S_OOPS); if (bt->sp.isconfigured) { return S_OOPS; } if ((rc =OurImports->CopyAllValues(namestocopy, list)) != S_OK) { return rc; } bt->device = namestocopy[0].s_value; bt->user = namestocopy[1].s_value; bt->passwd = namestocopy[2].s_value; return(S_OK); }
static int ssh_status(StonithPlugin *s) { ERRIFWRONGDEV(s, S_OOPS); return system(NULL) ? S_OK : S_OOPS; }
static int bladehpi_status(StonithPlugin *s) { struct pluginDevice * dev; SaErrorT ohrc; SaHpiDomainInfoT ohdi; int rc = S_OK; if (Debug) { LOG(PIL_DEBUG, "%s: called", __FUNCTION__); } ERRIFWRONGDEV(s, S_OOPS); dev = (struct pluginDevice *)s; rc = open_hpi_session(dev); if( rc != S_OK ) return rc; /* Refresh the hostlist only if RPTs updated */ ohrc = saHpiDomainInfoGet(dev->ohsession, &ohdi); if (ohrc != SA_OK) { LOG(PIL_CRIT, "Unable to get domain info in %s (%d)" , __FUNCTION__, ohrc); rc = S_BADCONFIG; goto done; } if (dev->ohrptcnt != ohdi.RptUpdateCount) { free_bladehpi_hostlist(dev); if (get_bladehpi_hostlist(dev) != S_OK) { LOG(PIL_CRIT, "Unable to obtain list of hosts in %s" , __FUNCTION__); rc = S_BADCONFIG; goto done; } } /* At this point, hostlist is up to date */ if (dev->ohsensid && dev->ohsensnum) { /* * For accurate status, need to make a call that goes out to * BladeCenter MM because the calls made so far by this * function (and perhaps get_bladehpi_hostlist) only retrieve * information from memory cached by OpenHPI */ ohrc = saHpiSensorReadingGet(dev->ohsession , dev->ohsensid, dev->ohsensnum, NULL, NULL); if (ohrc == SA_ERR_HPI_BUSY || ohrc == SA_ERR_HPI_NO_RESPONSE) { LOG(PIL_CRIT, "Unable to connect to BladeCenter in %s" , __FUNCTION__); rc = S_OOPS; goto done; } } done: close_hpi_session(dev); return (rc == S_OK) ? (dev->ohdevid ? S_OK : S_OOPS) : rc; }
static const char * bladehpi_getinfo(StonithPlugin *s, int reqtype) { struct pluginDevice * dev; const char * ret; if (Debug) { LOG(PIL_DEBUG, "%s: called, reqtype=%d" , __FUNCTION__, reqtype); } ERRIFWRONGDEV(s, NULL); dev = (struct pluginDevice *)s; switch (reqtype) { case ST_DEVICEID: ret = dev->idinfo; break; case ST_DEVICENAME: ret = dev->device; break; case ST_DEVICEDESCR: ret = "IBM BladeCenter via OpenHPI\n" "Use for IBM xSeries systems managed by BladeCenter\n" " Required parameter name " ST_ENTITYROOT " is " "a string (no white-space) of\n" "the format \""SYSTEM_CHASSIS_FMT"\" " "which is entity_root of BladeCenter\n" "from OpenHPI config file, where %d is a positive " "integer\n" " Optional parameter name " ST_SOFTRESET " is " "true|1 if STONITH device should\n" "use soft reset (power cycle) to reset nodes or " "false|0 if device should\n" "use hard reset (power off, wait, power on); " "default is false"; break; case ST_DEVICEURL: ret = OPENHPIURL; break; case ST_CONF_XML: /* XML metadata */ ret = bladehpiXML; break; default: ret = NULL; break; } return ret; }
static int riloe_status(StonithPlugin *s) { if (Debug) { LOG(PIL_DEBUG, "%s:called.", __FUNCTION__); } ERRIFWRONGDEV(s,S_OOPS); return S_OK; }
static const char* ibmhmc_getinfo(StonithPlugin* s, int reqtype) { struct pluginDevice* dev; const char* ret; ERRIFWRONGDEV(s,NULL); dev = (struct pluginDevice *)s; switch (reqtype) { case ST_DEVICEID: ret = dev->idinfo; break; case ST_DEVICENAME: ret = dev->hmc; break; case ST_DEVICEDESCR: ret = "IBM Hardware Management Console (HMC)\n" "Use for IBM i5, p5, pSeries and OpenPower systems " "managed by HMC\n" " Optional parameter name " ST_MANSYSPAT " is " "white-space delimited list of\n" "patterns used to match managed system names; if last " "character is '*',\n" "all names that begin with the pattern are matched\n" " Optional parameter name " ST_PASSWD " is password " "for " HMCROOT " if passwordless\n" "ssh access to HMC has NOT been setup (to do so, it " "is necessary to create\n" "a public/private key pair with empty passphrase - " "see \"Configure the\n" "OpenSSH client\" in the redbook for more details)"; break; case ST_DEVICEURL: ret = HMCURL; break; case ST_CONF_XML: /* XML metadata */ ret = ibmhmcXML; break; default: ret = NULL; break; } return ret; }
static int ibmhmc_status(StonithPlugin *s) { struct pluginDevice* dev = NULL; if(Debug){ LOG(PIL_DEBUG, "%s: called\n", __FUNCTION__); } ERRIFWRONGDEV(s,S_OOPS); dev = (struct pluginDevice*) s; return check_hmc_status(dev); }
static const char * apcmaster_getinfo(StonithPlugin * s, int reqtype) { struct pluginDevice* ms; const char * ret; ERRIFWRONGDEV(s,NULL); /* * We look in the ST_TEXTDOMAIN catalog for our messages */ ms = (struct pluginDevice *)s; switch (reqtype) { case ST_DEVICEID: ret = ms->idinfo; break; case ST_DEVICENAME: /* Which particular device? */ ret = ms->device; break; case ST_DEVICEDESCR: ret = "APC MasterSwitch (via telnet)\n" "NOTE: The APC MasterSwitch accepts only one (telnet)\n" "connection/session a time. When one session is active,\n" "subsequent attempts to connect to the MasterSwitch" " will fail."; break; case ST_DEVICEURL: ret = "http://www.apc.com/"; break; case ST_CONF_XML: /* XML metadata */ ret = apcmasterXML; break; default: ret = NULL; break; } return ret; }
static const char * ssh_get_info(StonithPlugin * s, int reqtype) { struct pluginDevice* sd = (struct pluginDevice *)s; const char * ret; ERRIFWRONGDEV(s, NULL); switch (reqtype) { case ST_DEVICEID: ret = sd->idinfo; break; case ST_DEVICENAME: ret = "ssh STONITH device"; break; case ST_DEVICEDESCR: /* Description of device type */ ret = "SSH-based Linux host reset\n" "Fine for testing, but not suitable for production!"; break; case ST_DEVICEURL: ret = "http://openssh.org"; break; case ST_CONF_XML: /* XML metadata */ ret = sshXML; break; default: ret = NULL; break; } return ret; }
static const char * baytech_get_info(StonithPlugin * s, int reqtype) { struct pluginDevice* bt; const char * ret; ERRIFWRONGDEV(s,NULL); bt = (struct pluginDevice *)s; switch (reqtype) { case ST_DEVICEID: /* What type of device? */ ret = bt->idinfo; break; case ST_DEVICENAME: /* Which particular device? */ ret = bt->device; break; case ST_DEVICEDESCR: /* Description of dev type */ ret = "Bay Technical Associates (Baytech) RPC " "series power switches (via telnet).\n" "The RPC-5, RPC-3 and RPC-3A switches are well tested" "."; break; case ST_DEVICEURL: /* Manufacturer's web site */ ret = "http://www.baytech.net/"; break; case ST_CONF_XML: /* XML metadata */ ret = baytechXML; break; default: ret = NULL; break; } return ret; }
/* * Parse the information in the given string * and stash it away... */ static int meatware_set_config(StonithPlugin* s, StonithNVpair *list) { struct pluginDevice* nd; int rc; StonithNamesToGet namestocopy [] = { {ST_HOSTLIST, NULL} , {NULL, NULL} }; ERRIFWRONGDEV(s,S_OOPS); nd = (struct pluginDevice*) s; if ((rc = OurImports->CopyAllValues(namestocopy, list)) != S_OK) { return rc; } rc = Meat_parse_config_info(nd, namestocopy[0].s_value); FREE(namestocopy[0].s_value); return rc; }
/* * Parse the information in the given string * and stash it away... */ static int external_set_config(StonithPlugin* s, StonithNVpair *list) { struct pluginDevice * sd; char ** p; if (Debug) { LOG(PIL_DEBUG, "%s: called.", __FUNCTION__); } ERRIFWRONGDEV(s,S_OOPS); /* make sure that command has not already been set */ if (s->isconfigured) { return(S_OOPS); } sd = (struct pluginDevice*) s; if (sd->subplugin == NULL) { LOG(PIL_CRIT, "%s: invoked without subplugin", __FUNCTION__); return(S_OOPS); } if (sd->confignames == NULL) { /* specified by name=value pairs, check required parms */ if (external_get_confignames(s) == NULL) { return(S_OOPS); } for (p = sd->confignames; *p; p++) { if (OurImports->GetValue(list, *p) == NULL) { LOG(PIL_INFO, "Cannot get parameter %s from " "StonithNVpair", *p); } } } return external_parse_config_info(sd, list); }
static const char * wti_mpc_getinfo(StonithPlugin * s, int reqtype) { struct pluginDevice *ad; const char *ret = NULL; DEBUGCALL; ERRIFWRONGDEV(s, NULL); ad = (struct pluginDevice *) s; switch (reqtype) { case ST_DEVICEID: ret = ad->idinfo; break; case ST_DEVICENAME: ret = ad->hostname; break; case ST_DEVICEDESCR: ret = "WTI MPC (via SNMP)\n" "The WTI MPC can accept multiple simultaneous SNMP clients"; break; case ST_DEVICEURL: ret = "http://www.wti.com/"; break; case ST_CONF_XML: /* XML metadata */ ret = apcmastersnmpXML; break; } return ret; }
/* * Parse the config information in the given string, and stash it away... */ static int ssh_set_config(StonithPlugin* s, StonithNVpair* list) { struct pluginDevice* sd = (struct pluginDevice *)s; const char * hlist; ERRIFWRONGDEV(s,S_OOPS); if ((hlist = OurImports->GetValue(list, ST_HOSTLIST)) == NULL) { return S_OOPS; } sd->hostlist = OurImports->StringToHostList(hlist); if (sd->hostlist == NULL) { LOG(PIL_CRIT, "out of memory"); sd->hostcount = 0; }else{ for (sd->hostcount = 0; sd->hostlist[sd->hostcount] ; sd->hostcount++) { g_strdown(sd->hostlist[sd->hostcount]); } } return sd->hostcount ? S_OK : S_OOPS; }
static const char * riloe_getinfo(StonithPlugin * s, int reqtype) { struct pluginDevice* nd; const char * ret; if (Debug) { LOG(PIL_DEBUG, "%s:called.", __FUNCTION__); } ERRIFWRONGDEV(s,NULL); /* * We look in the ST_TEXTDOMAIN catalog for our messages */ nd = (struct pluginDevice *)s; switch (reqtype) { case ST_DEVICEID: ret = nd->idinfo; break; case ST_DEVICEDESCR: ret = "Compaq RILOE STONITH device\n" "Very early version!"; break; case ST_DEVICEURL: ret = "http://www.hp.com/"; break; case ST_CONF_XML: /* XML metadata */ ret = riloeXML; break; default: ret = NULL; break; } return ret; }
static int meatware_status(StonithPlugin *s) { ERRIFWRONGDEV(s,S_OOPS); return S_OK; }
static int wti_mpc_set_config(StonithPlugin * s, StonithNVpair * list) { struct pluginDevice* sd = (struct pluginDevice *)s; int rc; char * i; int mo; char objname[MAX_STRING]; StonithNamesToGet namestocopy [] = { {ST_IPADDR, NULL} , {ST_PORT, NULL} , {ST_COMMUNITY, NULL} , {ST_MIBVERSION, NULL} , {NULL, NULL} }; DEBUGCALL; ERRIFWRONGDEV(s,S_INVAL); if (sd->sp.isconfigured) { return S_OOPS; } if ((rc=OurImports->CopyAllValues(namestocopy, list)) != S_OK) { return rc; } sd->hostname = namestocopy[0].s_value; sd->port = atoi(namestocopy[1].s_value); PluginImports->mfree(namestocopy[1].s_value); sd->community = namestocopy[2].s_value; sd->mib_version = atoi(namestocopy[3].s_value); PluginImports->mfree(namestocopy[3].s_value); /* try to resolve the hostname/ip-address */ if (gethostbyname(sd->hostname) != NULL) { /* init snmp library */ init_snmp("wti_mpc"); /* now try to get a snmp session */ if ((sd->sptr = MPC_open(sd->hostname, sd->port, sd->community)) != NULL) { /* ok, get the number of groups from the mpc */ sd->num_outlets=0; /* We scan goup names table starting from 1 to MAX_OUTLETS */ /* and increase num_outlet counter on every group entry with name */ /* first entry without name is the mark of the end of the group table */ for (mo=1; mo<MAX_OUTLETS; mo++) { switch (sd->mib_version) { case 3: snprintf(objname,MAX_STRING,OID_GROUP_NAMES_V3,mo); break; case 1: default: snprintf(objname,MAX_STRING,OID_GROUP_NAMES_V1,mo); break; } if (Debug) { LOG(PIL_DEBUG, "%s: used for groupTable retrieval: %s." , __FUNCTION__, objname); } if ((i = MPC_read(sd->sptr, objname, ASN_OCTET_STR)) == NULL) { LOG(PIL_CRIT , "%s: cannot read number of outlets." , __FUNCTION__); return (S_ACCESS); } if (strlen(i)) { /* store the number of outlets */ sd->num_outlets++; } else { break; } } if (Debug) { LOG(PIL_DEBUG, "%s: number of outlets: %i." , __FUNCTION__, sd->num_outlets ); } /* Everything went well */ return (S_OK); } else { LOG(PIL_CRIT, "%s: cannot create snmp session." , __FUNCTION__); } } else { LOG(PIL_CRIT, "%s: cannot resolve hostname '%s', h_errno %d." , __FUNCTION__, sd->hostname, h_errno); } /* not a valid config */ return (S_BADCONFIG); }
static int bladehpi_reset_req(StonithPlugin *s, int request, const char *host) { GList * node = NULL; struct pluginDevice * dev = NULL; struct blade_info * bi = NULL; SaHpiPowerStateT ohcurstate, ohnewstate; SaErrorT ohrc; if (Debug) { LOG(PIL_DEBUG, "%s: called, request=%d, host=%s" , __FUNCTION__, request, host); } ERRIFWRONGDEV(s, S_OOPS); if (host == NULL) { LOG(PIL_CRIT, "Invalid host argument to %s", __FUNCTION__); return S_OOPS; } dev = (struct pluginDevice *)s; for (node = g_list_first(dev->hostlist) ; node != NULL ; node = g_list_next(node)) { bi = ((struct blade_info *)node->data); if (Debug) { LOG(PIL_DEBUG, "Found host %s in hostlist", bi->name); } if (!strcasecmp(bi->name, host)) { break; } } if (!node || !bi) { LOG(PIL_CRIT , "Host %s is not configured in this STONITH module, " "please check your configuration information", host); return S_OOPS; } /* Make sure host has proper capabilities for get */ if (!(bi->resourceCaps & SAHPI_CAPABILITY_POWER)) { LOG(PIL_CRIT , "Host %s does not have power capability", host); return S_OOPS; } ohrc = saHpiResourcePowerStateGet(dev->ohsession, bi->resourceId , &ohcurstate); if (ohrc != SA_OK) { LOG(PIL_CRIT, "Unable to get host %s power state (%d)" , host, ohrc); return S_OOPS; } switch (request) { case ST_POWERON: if (ohcurstate == SAHPI_POWER_ON) { LOG(PIL_INFO, "Host %s already on", host); return S_OK; } ohnewstate = SAHPI_POWER_ON; break; case ST_POWEROFF: if (ohcurstate == SAHPI_POWER_OFF) { LOG(PIL_INFO, "Host %s already off", host); return S_OK; } ohnewstate = SAHPI_POWER_OFF; break; case ST_GENERIC_RESET: if (ohcurstate == SAHPI_POWER_OFF) { ohnewstate = SAHPI_POWER_ON; } else { ohnewstate = SAHPI_POWER_CYCLE; } break; default: LOG(PIL_CRIT, "Invalid request argument to %s" , __FUNCTION__); return S_INVAL; } if (!dev->softreset && (ohnewstate == SAHPI_POWER_CYCLE)) { int maxwait; ohrc = saHpiResourcePowerStateSet(dev->ohsession , bi->resourceId, SAHPI_POWER_OFF); if (ohrc != SA_OK) { LOG(PIL_CRIT, "Unable to set host %s power state to" " OFF (%d)", host, ohrc); return S_OOPS; } /* * Must wait for power off here or subsequent power on request * may take place while power is still on and thus ignored */ maxwait = MAX_POWEROFF_WAIT; do { maxwait--; sleep(1); ohrc = saHpiResourcePowerStateGet(dev->ohsession , bi->resourceId, &ohcurstate); } while ((ohrc == SA_OK) && (ohcurstate != SAHPI_POWER_OFF) && (maxwait > 0)); if (Debug) { LOG(PIL_DEBUG, "Waited %d seconds for power off" , MAX_POWEROFF_WAIT - maxwait); } ohrc = saHpiResourcePowerStateSet(dev->ohsession , bi->resourceId, SAHPI_POWER_ON); if (ohrc != SA_OK) { LOG(PIL_CRIT, "Unable to set host %s power state to" " ON (%d)", host, ohrc); return S_OOPS; } } else { /* Make sure host has proper capabilities to reset */ if ((ohnewstate == SAHPI_POWER_CYCLE) && (!(bi->resourceCaps & SAHPI_CAPABILITY_RESET))) { LOG(PIL_CRIT , "Host %s does not have reset capability" , host); return S_OOPS; } if ((ohrc = saHpiResourcePowerStateSet(dev->ohsession , bi->resourceId, ohnewstate)) != SA_OK) { LOG(PIL_CRIT, "Unable to set host %s power state (%d)" , host, ohrc); return S_OOPS; } } #ifdef IBMBC_WAIT_FOR_OFF if (ohnewstate == SAHPI_POWER_OFF) { int maxwait = MAX_POWEROFF_WAIT; do { maxwait--; sleep(1); ohrc = saHpiResourcePowerStateGet(dev->ohsession , bi->resourceId, &ohcurstate); } while ((ohrc == SA_OK) && (ohcurstate != SAHPI_POWER_OFF) && (maxwait > 0)); if (Debug) { LOG(PIL_DEBUG, "Waited %d seconds for power off" , MAX_POWEROFF_WAIT - maxwait); } } #endif LOG(PIL_INFO, "Host %s %s %d.", host, __FUNCTION__, request); return S_OK; }
static int bladehpi_set_config(StonithPlugin *s, StonithNVpair *list) { struct pluginDevice * dev = NULL; StonithNamesToGet namestocopy [] = { {ST_ENTITYROOT, NULL} , {NULL, NULL} }; int rc, i; SaErrorT ohrc; if (Debug) { LOG(PIL_DEBUG, "%s: called", __FUNCTION__); } ERRIFWRONGDEV(s, S_OOPS); dev = (struct pluginDevice *)s; if (Debug) { LOG(PIL_DEBUG, "%s conditionally compiled with:" #ifdef IBMBC_WAIT_FOR_OFF " IBMBC_WAIT_FOR_OFF" #endif , dev->pluginid); } if ((rc = OurImports->CopyAllValues(namestocopy, list)) != S_OK) { return rc; } if (Debug) { LOG(PIL_DEBUG, "%s = %s", ST_ENTITYROOT , namestocopy[0].s_value); } if (get_num_tokens(namestocopy[0].s_value) == 1) { /* name=value pairs on command line, look for soft_reset */ const char *softreset = OurImports->GetValue(list, ST_SOFTRESET); if (softreset != NULL) { if (!strcasecmp(softreset, "true") || !strcmp(softreset, "1")) { dev->softreset = 1; } else if (!strcasecmp(softreset, "false") || !strcmp(softreset, "0")) { dev->softreset = 0; } else { LOG(PIL_CRIT, "Invalid %s %s, must be " "true, 1, false or 0" , ST_SOFTRESET, softreset); FREE(namestocopy[0].s_value); return S_OOPS; } } } else { /* -p or -F option with args "entity_root [soft_reset]..." */ char *pch = namestocopy[0].s_value; /* skip over entity_root and null-terminate */ pch += strcspn(pch, WHITESPACE); *pch = EOS; /* skip over white-space up to next token */ pch++; pch += strspn(pch, WHITESPACE); if (!strcasecmp(pch, "true") || !strcmp(pch, "1")) { dev->softreset = 1; } else if (!strcasecmp(pch, "false") || !strcmp(pch, "0")) { dev->softreset = 0; } else { LOG(PIL_CRIT, "Invalid %s %s, must be " "true, 1, false or 0" , ST_SOFTRESET, pch); FREE(namestocopy[0].s_value); return S_OOPS; } } dev->device = STRDUP(namestocopy[0].s_value); FREE(namestocopy[0].s_value); if (dev->device == NULL) { LOG(PIL_CRIT, "Out of memory for strdup in %s", __FUNCTION__); return S_OOPS; } if (strcspn(dev->device, WHITESPACE) != strlen(dev->device) || sscanf(dev->device, SYSTEM_CHASSIS_FMT, &i) != 1 || i < 0) { LOG(PIL_CRIT, "Invalid %s %s, must be of format %s" , ST_ENTITYROOT, dev->device, SYSTEM_CHASSIS_FMT); return S_BADCONFIG; } dev->ohver = saHpiVersionGet(); if (dev->ohver > SAHPI_INTERFACE_VERSION) { LOG(PIL_CRIT, "Installed OpenHPI interface (%x) greater than " "one used by plugin (%x), incompatibilites may exist" , dev->ohver, SAHPI_INTERFACE_VERSION); return S_BADCONFIG; } ohrc = saHpiSessionOpen(SAHPI_UNSPECIFIED_DOMAIN_ID , &dev->ohsession, NULL); if (ohrc != SA_OK) { LOG(PIL_CRIT, "Unable to open HPI session (%d)", ohrc); return S_BADCONFIG; } ohrc = saHpiDiscover(dev->ohsession); if (ohrc != SA_OK) { LOG(PIL_CRIT, "Unable to discover resources (%d)", ohrc); return S_BADCONFIG; } if (get_bladehpi_hostlist(dev) != S_OK) { LOG(PIL_CRIT, "Unable to obtain list of hosts in %s" , __FUNCTION__); return S_BADCONFIG; } return S_OK; }
static int ibmhmc_reset_req(StonithPlugin * s, int request, const char * host) { GList* node = NULL; struct pluginDevice* dev = NULL; char off_cmd[MAX_CMD_LEN]; char on_cmd[MAX_CMD_LEN]; char reset_cmd[MAX_CMD_LEN]; gchar** names = NULL; int i; int is_lpar = FALSE; int status; char* pch; char* output = NULL; char state_cmd[MAX_CMD_LEN]; int state = STATE_UNKNOWN; status = 0; if(Debug){ LOG(PIL_DEBUG, "%s: called, host=%s\n", __FUNCTION__, host); } ERRIFWRONGDEV(s,S_OOPS); if (NULL == host) { LOG(PIL_CRIT, "invalid argument to %s", __FUNCTION__); return(S_OOPS); } dev = (struct pluginDevice*) s; for (node = g_list_first(dev->hostlist) ; NULL != node ; node = g_list_next(node)) { if(Debug){ LOG(PIL_DEBUG, "%s: node->data=%s\n" , __FUNCTION__, (char*)node->data); } if ((pch = strchr((char*)node->data, '/')) != NULL && 0 == strcasecmp(++pch, host)) { break; } } if (!node) { LOG(PIL_CRIT , "Host %s is not configured in this STONITH module. " "Please check your configuration information.", host); return (S_OOPS); } names = g_strsplit((char*)node->data, "/", 2); /* names[0] will be the name of managed system */ /* names[1] will be the name of the lpar partition */ if(Debug){ LOG(PIL_DEBUG, "%s: names[0]=%s, names[1]=%s\n" , __FUNCTION__, names[0], names[1]); } if (dev->hmcver < 4) { if (0 == strcasecmp(names[1], FULLSYSTEMPARTITION)) { is_lpar = FALSE; snprintf(off_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s chsysstate" " -r sys -m %s -o off -n %s -c full" , dev->hmc, dev->hmc, names[0]); snprintf(on_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s chsysstate" " -r sys -m %s -o on -n %s -c full -b norm" , dev->hmc, names[0], names[0]); snprintf(reset_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s chsysstate" " -r sys -m %s -o reset -n %s -c full -b norm" , dev->hmc, names[0], names[0]); *state_cmd = 0; }else{ is_lpar = TRUE; snprintf(off_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s reset_partition" " -m %s -p %s -t hard" , dev->hmc, names[0], names[1]); snprintf(on_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s chsysstate" " -r lpar -m %s -o on -n %s" , dev->hmc, names[0], names[1]); *reset_cmd = 0; snprintf(state_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s lssyscfg" " -r lpar -m %s -F state -n %s" , dev->hmc, names[0], names[1]); } }else{ is_lpar = TRUE; snprintf(off_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s chsysstate" " -m %s -r lpar -o shutdown -n \"%s\" --immed" , dev->hmc, names[0], names[1]); snprintf(on_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s lssyscfg" " -m %s -r lpar -F \"default_profile\"" " --filter \"lpar_names=%s\"" , dev->hmc, names[0], names[1]); output = do_shell_cmd(on_cmd, &status, dev->password); if (output == NULL) { LOG(PIL_CRIT, "command %s failed", on_cmd); return (S_OOPS); } if ((pch = strchr(output, '\n')) != NULL) { *pch = 0; } snprintf(on_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s chsysstate" " -m %s -r lpar -o on -n %s -f %s" , dev->hmc, names[0], names[1], output); FREE(output); output = NULL; snprintf(reset_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s chsysstate" " -m %s -r lpar -o shutdown -n %s --immed --restart" , dev->hmc, names[0], names[1]); snprintf(state_cmd, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s lssyscfg" " -m %s -r lpar -F state --filter \"lpar_names=%s\"" , dev->hmc, names[0], names[1]); } g_strfreev(names); if(Debug){ LOG(PIL_DEBUG, "%s: off_cmd=%s, on_cmd=%s," "reset_cmd=%s, state_cmd=%s\n" , __FUNCTION__, off_cmd, on_cmd, reset_cmd, state_cmd); } output = do_shell_cmd(state_cmd, &status, dev->password); if (output == NULL) { LOG(PIL_CRIT, "command %s failed", on_cmd); return S_OOPS; } if ((pch = strchr(output, '\n')) != NULL) { *pch = 0; } if (strcmp(output, "Running") == 0 || strcmp(output, "Starting") == 0 || strcmp(output, "Open Firmware") == 0) { state = STATE_ON; }else if (strcmp(output, "Shutting Down") == 0 || strcmp(output, "Not Activated") == 0 || strcmp(output, "Ready") == 0) { state = STATE_OFF; }else if (strcmp(output, "Not Available") == 0 || strcmp(output, "Error") == 0) { state = STATE_INVALID; } FREE(output); output = NULL; if (state == STATE_INVALID) { LOG(PIL_CRIT, "host %s in invalid state", host); return S_OOPS; } switch (request) { case ST_POWERON: if (state == STATE_ON) { LOG(PIL_INFO, "host %s already on", host); return S_OK; } output = do_shell_cmd(on_cmd, &status, dev->password); if (0 != status) { LOG(PIL_CRIT, "command %s failed", on_cmd); return S_OOPS; } break; case ST_POWEROFF: if (state == STATE_OFF) { LOG(PIL_INFO, "host %s already off", host); return S_OK; } output = do_shell_cmd(off_cmd, &status, dev->password); if (0 != status) { LOG(PIL_CRIT, "command %s failed", off_cmd); return S_OOPS; } break; case ST_GENERIC_RESET: if (dev->hmcver < 4) { if (is_lpar) { if (state == STATE_ON) { output = do_shell_cmd(off_cmd , &status, dev->password); if (0 != status) { LOG(PIL_CRIT, "command %s " "failed", off_cmd); return S_OOPS; } } for (i = 0; i < MAX_POWERON_RETRY; i++) { char *output2; output2 = do_shell_cmd(on_cmd , &status, dev->password); if (output2 != NULL) { FREE(output2); } if (0 != status) { sleep(1); }else{ break; } } if (MAX_POWERON_RETRY == i) { LOG(PIL_CRIT, "command %s failed" , on_cmd); return S_OOPS; } }else{ output = do_shell_cmd(reset_cmd , &status, dev->password); if (0 != status) { LOG(PIL_CRIT, "command %s failed" , reset_cmd); return S_OOPS; } break; } }else{ if (state == STATE_ON) { output = do_shell_cmd(reset_cmd , &status, dev->password); }else{ output = do_shell_cmd(on_cmd , &status, dev->password); } if (0 != status) { LOG(PIL_CRIT, "command %s failed", reset_cmd); return S_OOPS; } } break; default: return S_INVAL; } if (output != NULL) { FREE(output); } LOG(PIL_INFO, "Host %s %s %d.", host, __FUNCTION__, request); return S_OK; }
static int ibmhmc_set_config(StonithPlugin * s, StonithNVpair* list) { struct pluginDevice* dev = NULL; StonithNamesToGet namestocopy [] = { {ST_IPADDR, NULL} , {NULL, NULL} }; int rc; char get_hmcver[MAX_CMD_LEN]; char firstchar; int firstnum; char* output = NULL; int status; const char *mansyspats; int len; ERRIFWRONGDEV(s,S_OOPS); if(Debug){ LOG(PIL_DEBUG, "%s: called\n", __FUNCTION__); } dev = (struct pluginDevice*) s; if ((rc = OurImports->CopyAllValues(namestocopy, list)) != S_OK) { return rc; } if(Debug){ LOG(PIL_DEBUG, "%s: ipaddr=%s\n", __FUNCTION__ , namestocopy[0].s_value); } if (get_num_tokens(namestocopy[0].s_value) == 1) { /* name=value pairs on command line, look for managedsyspat */ mansyspats = OurImports->GetValue(list, ST_MANSYSPAT); if (mansyspats != NULL) { if (get_hmc_mansyspats(dev, mansyspats) != S_OK) { FREE(namestocopy[0].s_value); return S_OOPS; } } /* look for password */ dev->password = STRDUP(OurImports->GetValue(list, ST_PASSWD)); dev->hmc = namestocopy[0].s_value; }else{ /* -p or -F option with args "ipaddr [managedsyspat]..." */ char *pch = namestocopy[0].s_value; /* skip over ipaddr and null-terminate */ pch += strcspn(pch, WHITESPACE); *pch = EOS; /* skip over white-space up to next token */ pch++; pch += strspn(pch, WHITESPACE); if (get_hmc_mansyspats(dev, pch) != S_OK) { FREE(namestocopy[0].s_value); return S_OOPS; } dev->hmc = STRDUP(namestocopy[0].s_value); FREE(namestocopy[0].s_value); } /* check whether the HMC has ssh command enabled */ if (check_hmc_status(dev) != S_OK) { LOG(PIL_CRIT, "HMC %s does not have remote " "command execution using the ssh facility enabled", dev->hmc); return S_BADCONFIG; } /* get the HMC's version info */ snprintf(get_hmcver, MAX_CMD_LEN , SSH_CMD " -l " HMCROOT " %s lshmc -v | grep RM", dev->hmc); if (Debug) { LOG(PIL_DEBUG, "%s: get_hmcver=%s", __FUNCTION__, get_hmcver); } output = do_shell_cmd(get_hmcver, &status, dev->password); if (Debug) { LOG(PIL_DEBUG, "%s: output=%s\n", __FUNCTION__ , output ? output : "(nil)"); } if (output == NULL) { return S_BADCONFIG; } /* parse the HMC's version info (i.e. "*RM V4R2.1" or "*RM R3V2.6") */ if ((sscanf(output, "*RM %c%1d", &firstchar, &firstnum) == 2) && ((firstchar == 'V') || (firstchar == 'R'))) { dev->hmcver = firstnum; if(Debug){ LOG(PIL_DEBUG, "%s: HMC %s version is %d" , __FUNCTION__, dev->hmc, dev->hmcver); } }else{ LOG(PIL_CRIT, "%s: unable to determine HMC %s version" , __FUNCTION__, dev->hmc); FREE(output); return S_BADCONFIG; } len = strlen(output+4) + sizeof(DEVICE) + 1; if (dev->idinfo != NULL) { FREE(dev->idinfo); dev->idinfo = NULL; } dev->idinfo = MALLOC(len * sizeof(char)); if (dev->idinfo == NULL) { LOG(PIL_CRIT, "out of memory"); FREE(output); return S_OOPS; } snprintf(dev->idinfo, len, "%s %s", DEVICE, output+4); FREE(output); if (S_OK != get_hmc_hostlist(dev)){ LOG(PIL_CRIT, "unable to obtain list of managed systems in %s" , __FUNCTION__); return S_BADCONFIG; } return S_OK; }
/* * Indicate that host must be power cycled manually. */ static int meatware_reset_req(StonithPlugin * s, int request, const char * host) { int fd, rc; const char * meatpipe_pr = HA_VARRUNDIR "/meatware"; /* if you intend to change this, modify meatclient.c as well */ char line[256], meatpipe[256]; char resp_addr[50], resp_mw[50], resp_result[50]; ERRIFWRONGDEV(s,S_OOPS); snprintf(meatpipe, 256, "%s.%s", meatpipe_pr, host); umask(0); unlink(meatpipe); rc = mkfifo(meatpipe, (S_IRUSR | S_IWUSR)); if (rc < 0) { LOG(PIL_CRIT, "cannot create FIFO for Meatware_reset_host"); return S_OOPS; } LOG(PIL_CRIT, "OPERATOR INTERVENTION REQUIRED to reset %s.", host); LOG(PIL_CRIT, "Run \"meatclient -c %s\" AFTER power-cycling the " "machine.", host); fd = open(meatpipe, O_RDONLY); if (fd < 0) { LOG(PIL_CRIT, "cannot open FIFO for Meatware_reset_host"); return S_OOPS; } alarm(600); memset(line, 0, 256); rc = read(fd, line, 256); alarm(0); if (rc < 0) { LOG(PIL_CRIT, "read error on FIFO for Meatware_reset_host"); return S_OOPS; } memset(resp_mw, 0, 50); memset(resp_result, 0, 50); memset(resp_addr, 0, 50); if (sscanf(line, "%s %s %s", resp_mw, resp_result, resp_addr) < 3) { LOG(PIL_CRIT, "Format error - failed to Meatware-reset node %s", host); return S_RESETFAIL; } strdown(resp_addr); if (strncmp(resp_mw, "meatware", 8) || strncmp(resp_result, "reply", 5) || strncasecmp(resp_addr, host, strlen(resp_addr))) { LOG(PIL_CRIT, "failed to Meatware-reset node %s", host); return S_RESETFAIL; }else{ LOG(PIL_INFO, "node Meatware-reset: %s", host); unlink(meatpipe); return S_OK; } }
/* * Return STONITH info string */ static const char * external_getinfo(StonithPlugin * s, int reqtype) { struct pluginDevice* sd; char * output = NULL; const char * op; int rc; if (Debug) { LOG(PIL_DEBUG, "%s: called.", __FUNCTION__); } ERRIFWRONGDEV(s,NULL); sd = (struct pluginDevice *)s; if (sd->subplugin == NULL) { LOG(PIL_CRIT, "%s: invoked without subplugin", __FUNCTION__); return(NULL); } switch (reqtype) { case ST_DEVICEID: op = "getinfo-devid"; break; case ST_DEVICENAME: op = "getinfo-devname"; break; case ST_DEVICEDESCR: op = "getinfo-devdescr"; break; case ST_DEVICEURL: op = "getinfo-devurl"; break; case ST_CONF_XML: op = "getinfo-xml"; break; default: return NULL; } rc = external_run_cmd(sd, op, &output); if (rc != 0) { LOG(PIL_CRIT, "%s: '%s %s' failed with rc %d", __FUNCTION__, sd->subplugin, op, rc); if (output) { LOG(PIL_CRIT, "plugin output: %s", output); FREE(output); } } else { if (Debug) { LOG(PIL_DEBUG, "%s: '%s %s' returned %d", __FUNCTION__, sd->subplugin, op, rc); } if (sd->outputbuf != NULL) { FREE(sd->outputbuf); } sd->outputbuf = output; return(output); } return(NULL); }
/* * Reset the given host on this Stonith device. */ static int ssh_reset_req(StonithPlugin * s, int request, const char * host) { struct pluginDevice* sd = (struct pluginDevice *)s; char cmd[4096]; int i, status = -1; ERRIFWRONGDEV(s, S_OOPS); if (request == ST_POWERON) { LOG(PIL_CRIT, "%s not capable of power-on operation", DEVICE); return S_INVAL; } else if (request != ST_POWEROFF && request != ST_GENERIC_RESET) { return S_INVAL; } for (i = 0; i < sd->hostcount; i++) { if (strcasecmp(host, sd->hostlist[i]) == 0) { break; } } if (i >= sd->hostcount) { LOG(PIL_CRIT, "%s doesn't control host [%s]" , sd->idinfo, host); return(S_BADHOST); } LOG(PIL_INFO, "Initiating ssh-%s on host: %s" , request == ST_POWEROFF ? "poweroff" : "reset", host); snprintf(cmd, sizeof(cmd)-1, "%s \"%s\" \"%s\"", SSH_COMMAND , host , request == ST_POWEROFF ? POWEROFF_COMMAND : REBOOT_COMMAND); status = system(cmd); if (WIFEXITED(status) && 0 == WEXITSTATUS(status)) { if (Debug) { LOG(PIL_DEBUG, "checking whether %s stonith'd", host); } snprintf(cmd, sizeof(cmd)-1 , "ping -w1 -c1 %s >/dev/null 2>&1", host); for (i = 0; i < MAX_PING_ATTEMPTS; i++) { status = system(cmd); if (WIFEXITED(status) && 1 == WEXITSTATUS(status)) { if (Debug) { LOG(PIL_DEBUG, "unable to ping %s" " after %d tries, stonith did work" , host, i); } return S_OK; } sleep(1); } LOG(PIL_CRIT, "still able to ping %s after %d tries, stonith" " did not work", host, MAX_PING_ATTEMPTS); return S_RESETFAIL; }else{ LOG(PIL_CRIT, "command %s failed", cmd); return S_RESETFAIL; } }