📄 apcmastersnmp.c
字号:
break; } if (h >= num_outlets) { /* put outletname in hostlist */ if (Debug) { LOG(PIL_DEBUG, "%s: added %s to hostlist" , __FUNCTION__, outlet_name); } if ((hl[num_outlets] = STRDUP(outlet_name)) == NULL) { LOG(PIL_CRIT, "%s: out of memory.", __FUNCTION__); stonith_free_hostlist(hl); hl = NULL; return (hl); } num_outlets++; } } if (Debug) { LOG(PIL_DEBUG, "%s: %d unique hosts connected to %d outlets" , __FUNCTION__, num_outlets, j); } /* return list */ return (hl);}/* * reset the host */static intapcmastersnmp_reset_req(StonithPlugin * s, int request, const char *host){ struct pluginDevice *ad; char objname[MAX_STRING]; char value[MAX_STRING]; char *outlet_name; int i, h, num_outlets, outlet, reboot_duration, *state, bad_outlets; int outlets[8]; /* Assume that one node is connected to a maximum of 8 outlets */ DEBUGCALL; ERRIFNOTCONFIGED(s, S_OOPS); ad = (struct pluginDevice *) s; num_outlets = 0; reboot_duration = 0; bad_outlets = 0; /* read max. as->num_outlets values */ for (outlet = 1; outlet <= ad->num_outlets; outlet++) { /* prepare objname */ snprintf(objname, MAX_STRING, OID_OUTLET_NAMES, outlet); /* read outlet name */ if ((outlet_name = APC_read(ad->sptr, objname, ASN_OCTET_STR)) == NULL) { LOG(PIL_DEBUG, "%s: cannot read outlet_names." , __FUNCTION__); return (S_ACCESS); } /* found one */ g_strdown(outlet_name); if (strcmp(outlet_name, host) == 0) { if (Debug) { LOG(PIL_DEBUG, "%s: Found %s at outlet: %d" , __FUNCTION__, host, outlet); } /* Check that the outlet is not administratively down */ /* prepare objname */ snprintf(objname, MAX_STRING, OID_OUTLET_STATE, outlet); /* get outlet's state */ if ((state = APC_read(ad->sptr, objname, ASN_INTEGER)) == NULL) { if (Debug) { LOG(PIL_DEBUG , "%s: %s %d" , "cannot read outlet_state for outlet" , __FUNCTION__, outlet); } return (S_ACCESS); } if (*state == OUTLET_OFF) { if (Debug) { LOG(PIL_DEBUG, "%s: outlet %d is off." , __FUNCTION__, outlet); } continue; } /* prepare oid */ snprintf(objname, MAX_STRING, OID_OUTLET_REBOOT_DURATION , outlet); /* read reboot_duration of the port */ if ((state = APC_read(ad->sptr, objname, ASN_INTEGER)) == NULL) { if (Debug) { LOG(PIL_DEBUG , "%s: %s." , __FUNCTION__ , "cannot read outlet's reboot duration"); } return (S_ACCESS); } if (num_outlets == 0) { /* save the inital value of the first port */ reboot_duration = *state; } else if (reboot_duration != *state) { LOG(PIL_WARN, "%s: Outlet %d has a different reboot duration!", __FUNCTION__, outlet); if (reboot_duration < *state) reboot_duration = *state; } /* Ok, add it to the list of outlets to control */ outlets[num_outlets]=outlet; num_outlets++; } } if (Debug) { LOG(PIL_DEBUG, "%s: outlet: %i", __FUNCTION__, outlet); } /* host not found in outlet names */ if (num_outlets < 1) { if (Debug) { LOG(PIL_DEBUG, "%s: no active outlet '%s'." , __FUNCTION__, host); } return (S_BADHOST); } /* Turn them all off */ for (outlet=outlets[0], i=0 ; i < num_outlets; i++, outlet = outlets[i]) { /* prepare objname */ snprintf(objname, MAX_STRING, OID_OUTLET_COMMAND_PENDING, outlet); /* are there pending commands ? */ if ((state = APC_read(ad->sptr, objname, ASN_INTEGER)) == NULL) { if (Debug) { LOG(PIL_DEBUG, "%s: cannot read outlet_pending." , __FUNCTION__); } return (S_ACCESS); } if (*state != OUTLET_NO_CMD_PEND) { if (Debug) { LOG(PIL_DEBUG, "%s: command pending.", __FUNCTION__); } return (S_RESETFAIL); } /* prepare objnames */ snprintf(objname, MAX_STRING, OID_OUTLET_STATE, outlet); snprintf(value, MAX_STRING, "%i", OUTLET_REBOOT); /* send reboot cmd */ if (!APC_write(ad->sptr, objname, 'i', value)) { if (Debug) { LOG(PIL_DEBUG , "%s: cannot send reboot cmd for outlet %d." , __FUNCTION__, outlet); } return (S_ACCESS); } } /* wait max. 2*reboot_duration for all outlets to go back on */ for (i = 0; i < reboot_duration << 1; i++) { sleep(1); bad_outlets = 0; for (outlet=outlets[0], h=0 ; h < num_outlets; h++, outlet = outlets[h]) { /* prepare objname of the first outlet */ snprintf(objname, MAX_STRING, OID_OUTLET_STATE, outlet); /* get outlet's state */ if ((state = APC_read(ad->sptr, objname, ASN_INTEGER)) == NULL) { if (Debug) { LOG(PIL_DEBUG , "%s: cannot read outlet_state of %d." , __FUNCTION__, outlets[0]); } return (S_ACCESS); } if (*state != OUTLET_ON) bad_outlets++; } if (bad_outlets == 0) return (S_OK); } if (bad_outlets == num_outlets) { /* reset failed */ LOG(PIL_CRIT, "%s: resetting host '%s' failed." , __FUNCTION__, host); return (S_RESETFAIL); } else { /* Not all outlets back on, but at least one; implies node was */ /* rebooted correctly */ LOG(PIL_WARN,"%s: Not all outlets came back online!" , __FUNCTION__); return (S_OK); }}/* * Get the configuration parameter names. */static const char **apcmastersnmp_get_confignames(StonithPlugin * s){ static const char * ret[] = {ST_IPADDR, ST_PORT, ST_COMMUNITY, NULL}; return ret;}/* * Set the configuration parameters. */static intapcmastersnmp_set_config(StonithPlugin * s, StonithNVpair * list){ struct pluginDevice* sd = (struct pluginDevice *)s; int rc; int * i; StonithNamesToGet namestoget [] = { {ST_IPADDR, NULL} , {ST_PORT, NULL} , {ST_COMMUNITY, NULL} , {NULL, NULL} }; DEBUGCALL; ERRIFWRONGDEV(s,S_INVAL); if (sd->sp.isconfigured) { return S_OOPS; } if ((rc=OurImports->GetAllValues(namestoget, list)) != S_OK) { return rc; } sd->hostname = namestoget[0].s_value; sd->port = atoi(namestoget[1].s_value); sd->community = namestoget[2].s_value; /* try to resolve the hostname/ip-address */ if (gethostbyname(sd->hostname) != NULL) { /* init snmp library */ init_snmp("apcmastersnmp"); /* now try to get a snmp session */ if ((sd->sptr = APC_open(sd->hostname, sd->port, sd->community)) != NULL) { /* ok, get the number of outlets from the masterswitch */ if ((i = APC_read(sd->sptr, OID_NUM_OUTLETS, ASN_INTEGER)) == NULL) { LOG(PIL_DEBUG , "%s: cannot read number of outlets." , __FUNCTION__); return (S_ACCESS); } /* store the number of outlets */ sd->num_outlets = *i; if (Debug) { LOG(PIL_DEBUG, "%s: number of outlets: %i" , __FUNCTION__, sd->num_outlets ); } /* Everything went well */ sd->config = TRUE; return (S_OK); } if (Debug) { LOG(PIL_DEBUG, "%s: cannot create snmp session" , __FUNCTION__); } } else { LOG(PIL_DEBUG, "%s: cannot resolve hostname '%s'" , __FUNCTION__, sd->hostname); } /* not a valid config */ return (S_BADCONFIG);}/* * get info about the stonith device */static const char *apcmastersnmp_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->pluginid; break; case ST_DEVICEDESCR: ret = _("APC MasterSwitch (via SNMP)\n" "The APC MasterSwitch can accept multiple simultaneous SNMP clients"); break; case ST_DEVICEURL: ret = "http://www.apc.com/"; break; } return ret;}/* * APC StonithPlugin destructor... */static voidapcmastersnmp_destroy(StonithPlugin * s){ struct pluginDevice *ad; DEBUGCALL; VOIDERRIFWRONGDEV(s); ad = (struct pluginDevice *) s; ad->pluginid = NOTpluginID; ad->config = FALSE; /* release snmp session */ if (ad->sptr != NULL) { snmp_close(ad->sptr); ad->sptr = NULL; } /* reset defaults */ ad->hostname = NULL; ad->community = NULL; ad->num_outlets = 0; PluginImports->mfree(ad); /* Our caller will release the STONITH object itself */}/* * Create a new APC StonithPlugin device. Too bad this function can't be * static */static StonithPlugin *apcmastersnmp_new(void){ struct pluginDevice *ad = MALLOCT(struct pluginDevice); DEBUGCALL; /* no memory for stonith-object */ if (ad == NULL) { LOG(PIL_CRIT, "%s: out of memory.", __FUNCTION__); return (NULL); } /* clear stonith-object */ memset(ad, 0, sizeof(*ad)); /* set defaults */ ad->pluginid = pluginid; ad->sptr = NULL; ad->hostname = NULL; ad->community = NULL; ad->num_outlets = 0; ad->sp.s_ops = &apcmastersnmpOps; /* return the object */ return (&(ad->sp));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -