📄 apcmastersnmp.c
字号:
"%s: module not tested with this hardware '%s'.", __FUNCTION__, ident); } /* status ok */ return (S_OK);}/* * return the list of hosts configured for this device */char **apcmastersnmp_hostlist(Stonith * s){ char **hl; struct APCDevice *ad; int j, h, num_outlets; char *outlet_name; char objname[MAX_STRING];#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: called.", __FUNCTION__);#endif if (!ISAPCDEV(s)) { syslog(LOG_ERR, "%s: invalid argument.", __FUNCTION__); return (NULL); } if (!ISCONFIGED(s)) { syslog(LOG_ERR, "%s: device is UNCONFIGURED!", __FUNCTION__); return (NULL); } ad = (struct APCDevice *) s->pinfo; /* allocate memory for array of up to NUM_OUTLETS strings */ if ((hl = (char **) APC_MALLOC(ad->num_outlets * sizeof(char *))) == NULL) { syslog(LOG_ERR, "%s: out of memory.", __FUNCTION__); return (NULL); } /* clear hostlist array */ memset(hl, 0, (ad->num_outlets + 1) * sizeof(char *)); num_outlets = 0; /* read NUM_OUTLETS values and put them into hostlist array */ for (j = 0; j < ad->num_outlets; ++j) { /* prepare objname */ snprintf(objname, MAX_STRING, OID_OUTLET_NAMES, j + 1); /* read outlet name */ if ((outlet_name = APC_read(ad->sptr, objname, ASN_OCTET_STR)) == NULL) { syslog(LOG_ERR, "%s: cannot read name for outlet %d.", __FUNCTION__, j+1); apcmastersnmp_free_hostlist(hl); hl = NULL; return (hl); } /* Check whether the host is already listed */ for (h = 0; h < num_outlets; ++h) { if (strcmp(hl[h],outlet_name) == 0) break; } if (h >= num_outlets) { /* put outletname in hostlist */#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: added %s to hostlist.", __FUNCTION__, outlet_name);#endif if ((hl[num_outlets] = APC_STRDUP(outlet_name)) == NULL) { syslog(LOG_ERR, "%s: out of memory.", __FUNCTION__); apcmastersnmp_free_hostlist(hl); hl = NULL; return (hl); } num_outlets++; } }#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: %d unique hosts connected to %d outlets.", __FUNCTION__, num_outlets, j);#endif /* return list */ return (hl);}/* * free the hostlist */voidapcmastersnmp_free_hostlist(char **hlist){ char **hl = hlist;#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: called.", __FUNCTION__);#endif /* empty list */ if (hl == NULL) return; /* walk through the list and release the strings */ while (*hl) { APC_FREE(*hl); *hl = NULL; ++hl; } /* release the list itself */ APC_FREE(hlist); hlist = NULL;}/* * reset the host */intapcmastersnmp_reset_req(Stonith * s, int request, const char *host){ struct APCDevice *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 */ #ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: called.", __FUNCTION__);#endif if (!ISAPCDEV(s)) { syslog(LOG_ERR, "%s: invalid argument.", __FUNCTION__); return (S_INVAL); } if (!ISCONFIGED(s)) { syslog(LOG_ERR, "%s: device is UNCONFIGURED!", __FUNCTION__); return (S_OOPS); } ad = (struct APCDevice *) s->pinfo; 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) { syslog(LOG_ERR, "%s: cannot read name for outlet %d.", __FUNCTION__, outlet); return (S_ACCESS); } /* found one */ g_strdown(outlet_name); if (strcmp(outlet_name, host) == 0) {#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: found %s at outlet %i.", __FUNCTION__, host, outlet);#endif /* 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) { syslog(LOG_ERR, "%s: cannot read state for outlet %d.", __FUNCTION__, outlet); return (S_ACCESS); } if (*state == OUTLET_OFF) {#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: outlet %d is off.", __FUNCTION__, outlet);#endif 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) { syslog(LOG_ERR, "%s: cannot read reboot duration for outlet %d.", __FUNCTION__, outlet); return (S_ACCESS); } if (num_outlets == 0) { /* save the inital value of the first port */ reboot_duration = *state; } else if (reboot_duration != *state) { syslog(LOG_WARNING, "%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++; } }#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: outlet: %i.", __FUNCTION__, outlet);#endif /* host not found in outlet names */ if (num_outlets < 1) { syslog(LOG_ERR, "%s: no active outlet for '%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) { syslog(LOG_ERR, "%s: cannot read pending commands for " "outlet %d.", __FUNCTION__, outlet); return (S_ACCESS); } if (*state != OUTLET_NO_CMD_PEND) {#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: command pending.", __FUNCTION__);#endif 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)) { syslog(LOG_ERR, "%s: cannot send reboot command 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) { syslog(LOG_ERR, "%s: cannot read state for outlet %d.", __FUNCTION__, outlet); return (S_ACCESS); } if (*state != OUTLET_ON) bad_outlets++; } if (bad_outlets == 0) return (S_OK); } if (bad_outlets == num_outlets) { /* reset failed */ syslog(LOG_ERR, "%s: resetting host '%s' failed.", __FUNCTION__, host); return (S_RESETFAIL); } else { /* Not all outlets back on, but at least one; implies the node was */ /* rebooted correctly */ syslog(LOG_WARNING,"%s: Not all outlets came back online!", __FUNCTION__); return (S_OK); }}/* * parse the information in the given configuration file, * and stash it away... */intapcmastersnmp_set_config_file(Stonith * s, const char *configname){ FILE *cfgfile; char confline[MAX_STRING]; struct APCDevice *ad;#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: called, file '%s'.", __FUNCTION__, configname);#endif if (!ISAPCDEV(s)) { syslog(LOG_ERR, "%s: invalid argument.", __FUNCTION__); return (S_INVAL); } ad = (struct APCDevice *) s->pinfo; if ((cfgfile = fopen(configname, "r")) == NULL) { syslog(LOG_ERR, "cannot open %s.", configname); return (S_BADCONFIG); } while (fgets(confline, sizeof(confline), cfgfile) != NULL) { if (*confline == '#' || *confline == '\n' || *confline == EOS) continue; return (APC_parse_config_info(ad, confline)); } return (S_BADCONFIG);}/* * Parse the config information in the given string, and stash it away... */intapcmastersnmp_set_config_info(Stonith * s, const char *info){ struct APCDevice *ad;#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: called, info '%s'.", __FUNCTION__, info);#endif if (!ISAPCDEV(s)) { syslog(LOG_ERR, "%s: invalid argument.", __FUNCTION__); return (S_INVAL); } ad = (struct APCDevice *) s->pinfo; return (APC_parse_config_info(ad, info));}/* * get info about the stonith device */const char *apcmastersnmp_getinfo(Stonith * s, int reqtype){ struct APCDevice *ad; const char *ret = NULL;#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: called.", __FUNCTION__);#endif if (!ISAPCDEV(s)) { syslog(LOG_ERR, "%s: invalid argument.", __FUNCTION__); return (NULL); } ad = (struct APCDevice *) s->pinfo; switch (reqtype) { case ST_DEVICEID: ret = ad->APCid; break; case ST_CONF_INFO_SYNTAX: ret = _("hostname/ip-address port community\n" "The hostname/IP-address, SNMP port and community string are white-space delimited."); break; case ST_CONF_FILE_SYNTAX: ret = _("hostname/ip-address port community\n" "The hostname/IP-address, SNMP port and community string are white-space delimited.\n" "All items must be on one line.\n" "Blank lines and lines beginning with # are ignored."); 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 Stonith destructor... */voidapcmastersnmp_destroy(Stonith * s){ struct APCDevice *ad;#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: called.", __FUNCTION__);#endif if (!ISAPCDEV(s)) { syslog(LOG_ERR, "%s: invalid argument.", __FUNCTION__); return; } ad = (struct APCDevice *) s->pinfo; ad->APCid = NOTapcID; /* 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; APC_FREE(ad); /* Our caller will release the STONITH object itself */}/* * Create a new APC Stonith device. Too bad this function can't be * static */void *apcmastersnmp_new(void){ struct APCDevice *ad = APC_MALLOCT(struct APCDevice);#ifdef APC_DEBUG syslog(LOG_DEBUG, "%s: called.", __FUNCTION__);#endif /* no memory for stonith-object */ if (ad == NULL) { syslog(LOG_ERR, "%s: out of memory.", __FUNCTION__); return (NULL); } /* clear stonith-object */ memset(ad, 0, sizeof(*ad)); /* set defaults */ ad->APCid = APCid; ad->sptr = NULL; ad->hostname = NULL; ad->community = NULL; ad->num_outlets = 0; /* return the object */ return ((void *) ad);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -