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

📄 apcsmart.c

📁 linux集群服务器软件代码包
💻 C
📖 第 1 页 / 共 2 页
字号:
intAPC_set_ups_var(int upsfd, const char *cmd, char *newval){	char resp[MAX_STRING];	char orig[MAX_STRING];	int rc;	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	if (((rc = APC_enter_smartmode(upsfd)) != S_OK)	||	((rc = APC_send_cmd(upsfd, cmd)) != S_OK)	||	((rc = APC_recv_rsp(upsfd, orig)) != S_OK)) {			return (rc);	}	if (strcmp(orig, newval) == 0) {		return (S_OK);		/* already set */	}	*resp = '\0';	while (strcmp(resp, orig) != 0) {		if (((rc = APC_send_cmd(upsfd, SWITCH_TO_NEXT_VAL)) != S_OK)		||	((rc = APC_recv_rsp(upsfd, resp)) != S_OK)) {	    			return (rc);		}		if (((rc = APC_enter_smartmode(upsfd)) != S_OK)		||	((rc = APC_send_cmd(upsfd, cmd)) != S_OK)		||	((rc = APC_recv_rsp(upsfd, resp)) != S_OK)) {	    			return (rc);		}		if (strcmp(resp, newval) == 0) {			strcpy(newval, orig);	/* return the old value */			return (S_OK);		/* got it */		}	}	LOG(PIL_CRIT, "%s(): Could not set variable '%s' to %s!"	,	__FUNCTION__, cmd, newval);	LOG(PIL_CRIT, "%s(): This UPS may not support STONITH :-("	,	 __FUNCTION__);	return (S_OOPS);}/* * Initialize the ups */intAPC_init(struct pluginDevice *ad){	int upsfd;	char value[MAX_STRING];	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	/* if ad->upsfd == -1 -> dev configured! */	if(ad->upsfd >= 0 ) {		 return S_OK;	}	/* open serial port and store the fd in ad->upsfd */	if ((upsfd = APC_open_serialport(ad->upsdev, B2400)) == -1) {		return -1;	}	/* switch into smart mode */	if (APC_enter_smartmode(upsfd) != S_OK) {		return -1;	}	/* get the old settings and store them */	strcpy(value, SHUTDOWN_DELAY);	if (APC_set_ups_var(upsfd, CMD_SHUTDOWN_DELAY, value) != S_OK) {		return -1;	}	strcpy(old_shutdown_delay, value);	strcpy(value, WAKEUP_DELAY);	if (APC_set_ups_var(upsfd, CMD_WAKEUP_DELAY, value) != S_OK) {		return (-1);	}	strcpy(old_wakeup_delay, value);	ad->upsfd = upsfd;	return S_OK;}/* * Restore original settings and close the port */voidAPC_deinit( int upsfd ){	APC_enter_smartmode( upsfd );	APC_set_ups_var(upsfd, CMD_SHUTDOWN_DELAY, old_shutdown_delay);	APC_set_ups_var(upsfd, CMD_WAKEUP_DELAY, old_wakeup_delay);	/* close serial port */	APC_close_serialport(upsfd);}static const char**apcsmart_get_confignames(StonithPlugin* sp){	static const char * names[] =  {ST_TTYDEV, ST_HOSTLIST, NULL};	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	return names;}/* * Stash away the config info we've been given... */static intapcsmart_set_config(StonithPlugin * s, StonithNVpair* list){	struct pluginDevice *	ad = (struct pluginDevice*)s;	StonithNamesToGet	namestoget [] =	{	{ST_TTYDEV,	NULL}	,	{ST_HOSTLIST,	NULL}	,	{NULL,		NULL}	};	int			rc;	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	ERRIFWRONGDEV(s, S_OOPS);	if ((rc=OurImports->GetAllValues(namestoget, list)) != S_OK) {		return rc;	}	ad->hostlist =	OurImports->StringToHostList(namestoget[1].s_value);	if (ad->hostlist == NULL) {		LOG(PIL_CRIT,"StringToHostList() failed");		return S_OOPS;	}	for (ad->hostcount = 0; ad->hostlist[ad->hostcount]	;	ad->hostcount++) {		/* Just count */	}	if (access(namestoget[0].s_value, R_OK|W_OK|F_OK) < 0) {		LOG(PIL_CRIT,"Cannot access tty [%s]"		,	namestoget[0].s_value);		return S_BADCONFIG;	}	ad->upsdev = namestoget[0].s_value;	return ad->hostcount ? S_OK : S_BADCONFIG;}/* * return the status for this device  */static intapcsmart_status(StonithPlugin * s){	struct pluginDevice *ad = (struct pluginDevice *) s;	char resp[MAX_STRING];	int rc;	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	ERRIFNOTCONFIGED(s,S_OOPS);	/* get status */	if (((rc = APC_init( ad ) == S_OK)	&&	((rc = APC_send_cmd(ad->upsfd, CMD_GET_STATUS)) == S_OK)	&&	((rc = APC_recv_rsp(ad->upsfd, resp)) == S_OK))) {		return (S_OK);		/* everything ok. */	}	if (Debug) {		LOG(PIL_DEBUG, "%s: failed.", __FUNCTION__);	}	return (rc);}/* * return the list of hosts configured for this device  */static char **apcsmart_hostlist(StonithPlugin * s){	struct pluginDevice *ad = (struct pluginDevice *) s;	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	ERRIFNOTCONFIGED(s,NULL);	return OurImports->CopyHostList((const char **)ad->hostlist);}static gbooleanapcsmart_RegisterBitsSet(struct pluginDevice * ad, int nreg, unsigned bits,	gboolean* waserr){	const char*	reqregs[4] = {"?", "~", "'", "8"};	unsigned	regval;	char		resp[MAX_STRING];	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	if (APC_enter_smartmode(ad->upsfd) != S_OK	||	APC_send_cmd(ad->upsfd, reqregs[nreg]) != S_OK	||	APC_recv_rsp(ad->upsfd, resp) != S_OK	||	(sscanf(resp, "%02x", &regval) != 1)) {		if (waserr){			*waserr = TRUE;		}		return FALSE;	}	if (waserr){		*waserr = FALSE;	}	return ((regval & bits) == bits);}#define	apcsmart_IsPoweredOff(ad, err) apcsmart_RegisterBitsSet(ad,1,0x40,err)#define	apcsmart_ResetHappening(ad,err) apcsmart_RegisterBitsSet(ad,3,0x08,err)static intapcsmart_ReqOnOff(struct pluginDevice * ad, int request){	const char *	cmdstr;	int		rc;	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	cmdstr = (request == ST_POWEROFF ? CMD_OFF : CMD_ON);	/* enter smartmode, send on/off command */	if ((rc =APC_enter_smartmode(ad->upsfd)) != S_OK	||	(rc = APC_send_cmd(ad->upsfd, cmdstr)) != S_OK) {		return rc;	}	sleep(2);	if ((rc = APC_send_cmd(ad->upsfd, cmdstr)) == S_OK) {		gboolean ison;		gboolean waserr;		sleep(1);		ison = !apcsmart_IsPoweredOff(ad, &waserr);		if (waserr) {			return S_RESETFAIL;		}		if (request == ST_POWEROFF) {			return ison ?  S_RESETFAIL : S_OK;		}else{			return ison ?  S_OK : S_RESETFAIL;		}	}	return rc;}/* * reset the host  */static intapcsmart_ReqGenericReset(struct pluginDevice *ad){	char		resp[MAX_STRING];	int		rc = S_RESETFAIL;	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	/* enter smartmode, send reset command */	if (((rc = APC_init(ad)) == S_OK)		&& ((rc = APC_send_cmd(ad->upsfd, CMD_RESET)) == S_OK)		&& ((rc = APC_recv_rsp(ad->upsfd, resp)) == S_OK)		&& (	strcmp(resp, RSP_RESET)  == 0		||	strcmp(resp, RSP_RESET2) == 0)) {		int	maxdelay = atoi(SHUTDOWN_DELAY)+5;		int	j;		for (j=0; j < maxdelay; ++j) {			gboolean	err;			if (apcsmart_ResetHappening(ad, &err)) {				return err ? S_RESETFAIL : S_OK;			}			sleep(1);		}		return S_RESETFAIL;	}else{		LOG(PIL_DEBUG, "APC: rc = %d resp[%s]"		,	rc, resp);		if (rc == S_OK && strcmp(resp, RSP_NA) == 0){			gboolean iserr;			/* This means it's currently powered off */			/* or busy on a previous command... */			if (apcsmart_IsPoweredOff(ad, &iserr)) {				if (iserr) {					return S_RESETFAIL;				}				return apcsmart_ReqOnOff(ad, ST_POWERON);			}		}	}	strcpy(resp, "?");	/* reset failed */	return S_RESETFAIL;}static intapcsmart_req_reset(StonithPlugin * s, int request, const char *host){	char **			hl;	int			b_found=FALSE;	struct pluginDevice *	ad = (struct pluginDevice *) s;	int			rc;	ERRIFNOTCONFIGED(s, S_OOPS);	if (host == NULL) {		LOG(PIL_CRIT, "%s: invalid hostname argument.", __FUNCTION__);		return (S_INVAL);	}    	/* look through the hostlist */	hl = ad->hostlist;	while (*hl && !b_found ) {		if( strcmp( *hl, host ) == 0 ) {			b_found = TRUE;			break;		}else{        		++hl;		}	}    	/* host not found in hostlist */	if( !b_found ) {		LOG(PIL_CRIT, "%s: host '%s' not in hostlist."		,	__FUNCTION__, host);		return S_BADHOST;	}	if ((rc = APC_init(ad)) != S_OK) {		return rc;	}	if (request == ST_POWERON || request == ST_POWEROFF) {		return apcsmart_ReqOnOff(ad, request);	}	return apcsmart_ReqGenericReset(ad);}/* * get info about the stonith device  */static const char *apcsmart_get_info(StonithPlugin * s, int reqtype){	struct pluginDevice *ad = (struct pluginDevice *) s;	const char *ret;	if (Debug) {    		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	ERRIFWRONGDEV(s,NULL);   	switch (reqtype) {    		case ST_DEVICEID:		ret = ad->pluginid;		break;		case ST_DEVICEDESCR:		ret = "APC Smart UPS"			" (via serial port - NOT USB!). "			" Works with higher-end APC UPSes, like"			" Back-UPS Pro, Smart-UPS, Matrix-UPS, etc. "			" (Smart-UPS may have to be >= Smart-UPS 700?)\n"		" See http://us1.networkupstools.org/protocols/apcsmart.html"			" for protocol compatibility details.";			break;		case ST_DEVICEURL:			ret = "http://www.apc.com/";			break;		default:			ret = NULL;			break;	}	return (ret);}/* * APC Stonith destructor...  */static voidapcsmart_destroy(StonithPlugin * s){    struct pluginDevice *ad = (struct pluginDevice *) s;	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);    	}	VOIDERRIFWRONGDEV(s);	APC_deinit( ad->upsfd );	ad->pluginid = NOTpluginID;	if (ad->hostlist) {		stonith_free_hostlist(ad->hostlist);		ad->hostlist = NULL;	}	ad->hostcount = -1;	ad->upsfd = -1;	FREE(ad);}/* * Create a new APC Stonith device.  Too bad this function can't be * static  */static StonithPlugin *apcsmart_new(void){    struct pluginDevice *ad = MALLOCT(struct pluginDevice);	if (Debug) {		LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);	}	if (ad == NULL) {		LOG(PIL_CRIT, "%s: out of memory.", __FUNCTION__);		return (NULL);	}	memset(ad, 0, sizeof(*ad));	ad->pluginid = pluginid;	ad->hostlist = NULL;	ad->hostcount = -1;	ad->upsfd = -1;	ad->sp.s_ops = &apcsmartOps;	if (Debug) {		LOG(PIL_DEBUG, "%s: returning successfully.", __FUNCTION__);	}	return &(ad->sp);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -