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

📄 nw_rpc100s.c

📁 linux集群服务器软件代码包
💻 C
📖 第 1 页 / 共 2 页
字号:
		ret[0]=STRDUP(ctx->node);		if (ret[0] == NULL) {			LOG(PIL_CRIT, "out of memory");			FREE(ret);			ret = NULL;		} else {			g_strdown(ret[0]);		}	}	return(ret);} /* end si_hostlist() *//* *	Parse the given configuration information, and stash it away... * *      <info> contains the parameters specific to this type of object * *         The format of <parameters> for this module is: *            <serial device> <remotenode> <outlet> [<remotenode> <outlet>] ... * *      e.g. A machine named 'nodea' can kill a machine named 'nodeb' through *           a device attached to serial port /dev/ttyS0. *           A machine named 'nodeb' can kill machines 'nodea' and 'nodec' *           through a device attached to serial port /dev/ttyS1 (outlets 0  *             and 1 respectively) * *      stonith nodea NW_RPC100S /dev/ttyS0 nodeb 0  *      stonith nodeb NW_RPC100S /dev/ttyS0 nodea 0 nodec 1 * *      Another possible configuration is for 2 stonith devices accessible *         through 2 different serial ports on nodeb: * *      stonith nodeb NW_RPC100S /dev/ttyS0 nodea 0  *      stonith nodeb NW_RPC100S /dev/ttyS1 nodec 0 */static intRPC_parse_config_info(struct pluginDevice* ctx, const char * info){	char *copy;	char *token;	if (ctx->config) {		/* The module is already configured. */		return(S_OOPS);	}	/* strtok() is nice to use to parse a string with 	   (other than it isn't threadsafe), but it is destructive, so	   we're going to alloc our own private little copy for the	   duration of this function.	*/	copy = STRDUP(info);	if (!copy) {		LOG(PIL_CRIT, "out of memory");		return S_OOPS;	}	/* Grab the serial device */	token = strtok (copy, " \t");	if (!token) {		LOG(PIL_CRIT, "%s: Can't find serial device on config line '%s'",		       pluginid, info);		goto token_error;			}	ctx->device = STRDUP(token);	if (!ctx->device) {		LOG(PIL_CRIT, "out of memory");		goto token_error;	}	/* Grab <nodename>  */	token = strtok (NULL, " \t");	if (!token) {		LOG(PIL_CRIT, "%s: Can't find node name on config line '%s'",		       pluginid, info);		goto token_error;			}	ctx->node = STRDUP(token);	if (!ctx->node) {		LOG(PIL_CRIT, "out of memory");		goto token_error;	}				/* free our private copy of the string we've been destructively 	   parsing with strtok()	*/	FREE(copy);	ctx->config = 1;	return S_OK;token_error:	FREE(copy);	return(S_BADCONFIG);}/* * RPCConnect - * * Connect to the given NW_RPC100S device.   * Side Effects *    ctx->fd now contains a valid file descriptor to the serial port *    ??? LOCK THE SERIAL PORT ??? *   * Returns  *    S_OK on success *    S_OOPS on error *    S_TIMEOUT if the device did not respond * */static intRPCConnect(struct pluginDevice * ctx){  	  	/* Open the serial port if it isn't already open */	if (ctx->fd < 0) {		struct termios tio;		ctx->fd = open (ctx->device, O_RDWR);		if (ctx->fd <0) {			LOG(PIL_CRIT, "%s: Can't open %s : %s",				pluginid, ctx->device, strerror(errno));			return S_OOPS;		}		/* set the baudrate to 9600 8 - N - 1 */		memset (&tio, 0, sizeof(tio));		/* ??? ALAN - the -tradtitional flag on gcc causes the 		   CRTSCTS constant to generate a warning, and warnings                    are treated as errors, so I can't set this flag! - EZA ???		                      Hmmm. now that I look at the documentation, RTS		   is just wired high on this device! we don't need it.		*/		/* tio.c_cflag = B9600 | CS8 | CLOCAL | CREAD | CRTSCTS ;*/		tio.c_cflag = B9600 | CS8 | CLOCAL | CREAD ;		tio.c_lflag = ICANON;		if (tcsetattr (ctx->fd, TCSANOW, &tio) < 0) {			LOG(PIL_CRIT, "%s: Can't set attributes %s : %s",				pluginid, ctx->device, strerror(errno));			close (ctx->fd);			ctx->fd=-1;			return S_OOPS;		}		/* flush all data to and fro the serial port before we start */		if (tcflush (ctx->fd, TCIOFLUSH) < 0) {			LOG(PIL_CRIT, "%s: Can't flush %s : %s",				pluginid, ctx->device, strerror(errno));			close (ctx->fd);			ctx->fd=-1;			return S_OOPS;				}			}	/* Send a BOGUS string */	SENDCMD("//0,0,BOGUS;\r\n", 10);		/* Should reply with "Invalid Command" */	if (gbl_debug) {		printf ("Waiting for \"Invalid Entry\"n");	}	EXPECT(ctx->fd, NWtokInvalidEntry, 12);	if (gbl_debug) {		printf ("Got Invalid Entry\n");	}	EXPECT(ctx->fd, NWtokCRNL, 2);	if (gbl_debug) {		printf ("Got NL\n");	}	     return(S_OK);}static intRPCDisconnect(struct pluginDevice * ctx){  if (ctx->fd >= 0) {    /* Flush the serial port, we don't care what happens to the characters       and failing to do this can cause close to hang.    */    tcflush(ctx->fd, TCIOFLUSH);    close (ctx->fd);  }  ctx->fd = -1;  return S_OK;} /* * RPCNametoOutlet - Map a hostname to an outlet number on this stonith device. * * Returns: *     0 on success ( the outlet number on the RPS10 - there is only one ) *     -1 on failure (host not found in the config file) *  */static intRPCNametoOutlet ( struct pluginDevice * ctx, const char * host ){	char *shost;	int rc = -1;		if ( (shost = strdup(host)) == NULL) {		LOG(PIL_CRIT, "strdup failed in RPCNametoOutlet");		return -1;	}	if (!strcmp(ctx->node, host))		rc = 0;	free(shost);	return rc;}/* *	nw_rpc100s_reset - API call to Reset (reboot) the given host on  *          this Stonith device.  This involves toggling the power off  *          and then on again, OR just calling the builtin reset command *          on the stonith device. */static intnw_rpc100s_reset_req(StonithPlugin * s, int request, const char * host){	int	rc = S_OK;	int	lorc = S_OK;	int outletnum = -1;	struct pluginDevice*	ctx;		if (gbl_debug) {		printf ("Calling nw_rpc100s_reset (%s)\n", pluginid);	}		ERRIFNOTCONFIGED(s,S_OOPS);	ctx = (struct pluginDevice*) s;	if ((rc = RPCConnect(ctx)) != S_OK) {		return(rc);	}	outletnum = RPCNametoOutlet(ctx, host);	LOG(PIL_DEBUG, "zk:outletname=%d", outletnum);	if (outletnum < 0) {		LOG(PIL_WARN, "%s %s %s[%s]",		       ctx->idinfo, ctx->unitid, _("doesn't control host"), host);		RPCDisconnect(ctx);		return(S_BADHOST);	}	switch(request) {#if defined(ST_POWERON) 		case ST_POWERON:			rc = RPCOn(ctx, outletnum, host);			break;#endif#if defined(ST_POWEROFF)		case ST_POWEROFF:			rc = RPCOff(ctx, outletnum, host);			break;#endif	case ST_GENERIC_RESET:		rc = RPCReset(ctx, outletnum, host);		break;	default:		rc = S_INVAL;		break;	}	lorc = RPCDisconnect(ctx);	return(rc != S_OK ? rc : lorc);}/* *	Parse the information in the given string  *	and stash it away... */static intnw_rpc100s_set_config(StonithPlugin* s, StonithNVpair *list){	char	cfgline[MAX_CFGLINE];	struct pluginDevice*	ctx;	StonithNamesToGet	namestoget [] =	{	{ST_TTYDEV,	NULL}	,	{ST_HOSTLIST,	NULL}	,	{NULL,		NULL}	};	int rc = 0;	ERRIFWRONGDEV(s,S_OOPS);	ctx = (struct pluginDevice*) s;		if ((rc = OurImports->GetAllValues(namestoget , list)) != S_OK) {		return rc;	}	if ((snprintf(cfgline,MAX_CFGLINE , "%s %s" , namestoget[0].s_value , namestoget[1].s_value)) <= 0){		LOG(PIL_CRIT, "Can not copy parameter to cfgline");	}	return (RPC_parse_config_info(ctx, cfgline));}/* * Return STONITH config vars */static const char **nw_rpc100s_get_confignames(StonithPlugin* p){	static const char *	RpcParams[] = {ST_TTYDEV , ST_HOSTLIST, NULL };	return RpcParams;}/* * nw_rpc100s_getinfo - API entry point to retrieve something from the handle */static const char *nw_rpc100s_getinfo(StonithPlugin * s, int reqtype){	struct pluginDevice* ctx;	const char *		ret;	ERRIFWRONGDEV(s,NULL);	/*	 *	We look in the ST_TEXTDOMAIN catalog for our messages	 */	ctx = (struct pluginDevice *)s;	switch (reqtype) {		case ST_DEVICEID:			ret = ctx->idinfo;			break;		case ST_DEVICEDESCR:			ret = _("Micro Energetics Night/Ware RPC100S");			break;		default:			ret = NULL;			break;	}	return ret;}/* * nw_rpc100s_destroy - API entry point to destroy a NW_RPC100S Stonith object. */static voidnw_rpc100s_destroy(StonithPlugin *s){	struct pluginDevice* ctx;	VOIDERRIFWRONGDEV(s);	ctx = (struct pluginDevice *)s;	ctx->pluginid = NOTrpcid;	/*  close the fd if open and set ctx->fd to invalid */	RPCDisconnect(ctx);		if (ctx->device != NULL) {		FREE(ctx->device);		ctx->device = NULL;	}	if (ctx->idinfo != NULL) {		FREE(ctx->idinfo);		ctx->idinfo = NULL;	}	if (ctx->unitid != NULL) {		FREE(ctx->unitid);		ctx->unitid = NULL;	}}/*  * nw_rpc100s_new - API entry point called to create a new NW_RPC100S Stonith device *          object.  */static StonithPlugin *nw_rpc100s_new(void){	struct pluginDevice*	ctx = MALLOCT(struct pluginDevice);	if (ctx == NULL) {		LOG(PIL_CRIT, "out of memory");		return(NULL);	}	memset(ctx, 0, sizeof(*ctx));	ctx->pluginid = pluginid;	ctx->fd = -1;	ctx->config = 0;	ctx->device = NULL;	ctx->node = NULL;	ctx->idinfo = NULL;	ctx->unitid = NULL;	REPLSTR(ctx->idinfo, DEVICE);	REPLSTR(ctx->unitid, "unknown");	ctx->sp.s_ops = &nw_rpc100sOps;	return &(ctx->sp);}

⌨️ 快捷键说明

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