⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apcmastersnmp.c

📁 在LINUX下实现HA的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	       "%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 + -