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

📄 vacm.c

📁 linux集群服务器软件代码包
💻 C
字号:
/* $Id: vacm.c,v 1.10 2005/01/31 09:45:31 sunjd Exp $ *//********************************************************************************    Copyright 2000 Sistina Software, Inc.*    Tiny bits Copyright 2000 Alan Robertson <alanr@unix.sh>*    Tiny bits Copyright 2000 Zac Sprackett, VA Linux Systems*    Tiny bits Copyright 2005 International Business Machines*    Significantly Mangled by Sun Jiang Dong <sunjd@cn.ibm.com>, IBM, 2005	**    This is free software released under the GNU General Public License.*    There is no warranty for this software.  See the file COPYING for*    details.**    See the file CONTRIBUTORS for a list of contributors.**    This file is maintained by:*      Michael C Tilstra <conrad@sistina.com>**    Becasue I have no device to test, now I just make it pass the compiling*    with vacm-2.0.5a. Please review before using.*		Sun Jiang Dong <sunjd@cn.ibm.com>, IBM, 2005**    This module provides a driver for the VA Linux Cluster Manager.*    For more information on VACM, see http://vacm.sourceforge.net/**    This module is rather poorly commented.  But if you've read the*    VACM Manual, and looked at the code example they have, this*    should make pretty clean sense. (You obiviously should have*    looked at the other stonith source too)* */#include "stonith_plugin_common.h"#include "vacmclient_api.h"#define PIL_PLUGIN              vacm#define PIL_PLUGIN_S            "vacm"#define PIL_PLUGINLICENSE 	LICENSE_LGPL#define PIL_PLUGINLICENSEURL 	URL_LGPL#include <pils/plugin.h>static StonithPlugin *	vacm_new(void);static void		vacm_destroy(StonithPlugin *);static const char **	vacm_get_confignames(StonithPlugin *);static int		vacm_set_config(StonithPlugin *, StonithNVpair *);static const char *	vacm_getinfo(StonithPlugin * s, int InfoType);static int		vacm_status(StonithPlugin * );static int		vacm_reset_req(StonithPlugin * s, int request, const char * host);static char **		vacm_hostlist(StonithPlugin  *);static struct stonith_ops vacmOps ={	vacm_new,		/* Create new STONITH object	*/	vacm_destroy,		/* Destroy STONITH object	*/	vacm_getinfo,		/* Return STONITH info string	*/	vacm_get_confignames,	/* Return configuration parameters */	vacm_set_config,	/* Set configuration		*/	vacm_status,		/* Return STONITH device status	*/	vacm_reset_req,		/* Request a reset */	vacm_hostlist,		/* Return list of supported hosts */};PIL_PLUGIN_BOILERPLATE2("1.0", Debug);static const PILPluginImports*  PluginImports;static PILPlugin*               OurPlugin;static PILInterface*		OurInterface;static StonithImports*		OurImports;static void*			interfprivate;PIL_rcPIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports);PIL_rcPIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports){	/* Force the compiler to do a little type checking */	(void)(PILPluginInitFun)PIL_PLUGIN_INIT;	PluginImports = imports;	OurPlugin = us;	/* Register ourself as a plugin */	imports->register_plugin(us, &OurPIExports);  	/*  Register our interface implementation */ 	return imports->register_interface(us, PIL_PLUGINTYPE_S	,	PIL_PLUGIN_S	,	&vacmOps	,	NULL		/*close */	,	&OurInterface	,	(void*)&OurImports	,	&interfprivate); }/*structs*/struct pluginDevice {	StonithPlugin sp; 	const char * pluginid;	void *h; /* a handle to the nexxus. */	char *	nexxus;	char *	user;	char *	passwd;};#define ST_NEXXUS   "nexxus"static const char * pluginid = "VACMDevice-Stonith";static const char * NOTpluginid = "VACM device has been destroyed";/*funcs*/intvacm_status(StonithPlugin *s){	struct pluginDevice *sd;	char snd[] = "NEXXUS:VERSION";	char *rcv, *tk;	int rcvlen;	ERRIFWRONGDEV(s,S_OOPS);	sd = (struct pluginDevice*)s;	/* If grabbing the nexxus version works, then the stauts must be ok.	 * right?	 */	api_nexxus_send_ipc(sd->h, snd, strlen(snd)+1);	while(1) {		if (api_nexxus_wait_for_data(sd->h, &rcv, &rcvlen, 20)<0) {			break;		}		if (!(tk = strtok(rcv,":"))) { /*NEXXUS*/			break;		}else if (!(tk=strtok(NULL,":"))) { /* Job ID */			break;		}else if (!(tk=strtok(NULL,":"))) { /* one of the below */			break;		} else if ( !strcmp(tk, "JOB_COMPLETED")) {			free(rcv);			return S_OK; /* YEAH!! */		}else if(!strcmp(tk, "JOB_STARTED")) {			free(rcv);			continue;		}else if(!strcmp(tk, "JOB_ERROR")) {			free(rcv);			break;		}else if(!strcmp(tk, "VERSION")) {			free(rcv);			continue;		} else {			LOG(PIL_CRIT, "Unexpected token \"%s\" in line \"%s\"\n"			    , tk, rcv);			break;		}	}	return S_OOPS;}/* Better make sure the current group is correct.  * Can't think of a good way to do this. */char **vacm_hostlist(StonithPlugin *s){   struct pluginDevice *sd;   char snd[] = "NEXXUS:NODE_LIST";   char *rcv,*tk;   int rcvlen;   char ** hlst=NULL;   int hacnt=0, hrcnt=0;#define MSTEP 20      ERRIFWRONGDEV(s, NULL);   sd = (struct pluginDevice*)s;   hlst = (char **)malloc(MSTEP * sizeof(char*));   hacnt=MSTEP;   api_nexxus_send_ipc(sd->h, snd, strlen(snd)+1);   while(1) {      if(api_nexxus_wait_for_data(sd->h, &rcv, &rcvlen, 20)<0) {         goto HL_cleanup;      }      if(!(tk=strtok(rcv, ":"))) { /* NEXXUS */         goto HL_cleanup;      }else if(!(tk=strtok(NULL,":"))) { /* Job ID */         goto HL_cleanup;      }else if(!(tk=strtok(NULL,":"))) { /* JOB_* or NODELIST */         goto HL_cleanup;      }else if( !strcmp(tk, "JOB_STARTED")) {         free(rcv);         continue;      }else if( !strcmp(tk, "JOB_COMPLETED")) {         free(rcv);         return hlst;      }else if( !strcmp(tk, "JOB_ERROR")) {         free(rcv);         break;      }else if( !strcmp(tk, "NODELIST")) {         if(!(tk = strtok(NULL,":"))) { /* group */            goto HL_cleanup;         }else if((tk = strtok(NULL," \t\n\r"))) { /*Finally, a machine name.*/            if( hrcnt >= (hacnt-1)) { /* grow array. */               hlst = (char **)realloc(hlst, (hacnt +MSTEP)*sizeof(char*));               if( !hlst ) return NULL; /* yeah, i know. possible leak */               hacnt += MSTEP;            }            hlst[hrcnt++] = strdup(tk); /* stuff the name. */            hlst[hrcnt] = NULL; /* set next to NULL for looping */         }      }else {         /* WTF?! */         LOG(PIL_CRIT, "Unexpected token \"%s\" in line \"%s\"\n",tk,rcv);         break;      }   }HL_cleanup:   stonith_free_hostlist(hlst); /* give the mem back */   return NULL;}#define SND_SIZE 256intvacm_reset_req(StonithPlugin *s, int request, const char *host){	struct pluginDevice *sd;	char snd[SND_SIZE]; /* god forbid its bigger than this */	char *rcv, *tk;	int rcvlen;	ERRIFWRONGDEV(s,S_OOPS);	sd = (struct pluginDevice*)s;	switch(request) {#ifdef ST_POWERON	case ST_POWERON:		snprintf(snd, SND_SIZE, "EMP:POWER_ON:%s", host);		break;#endif /*ST_POWERON*/#ifdef ST_POWEROFF	case ST_POWEROFF:		snprintf(snd, SND_SIZE, "EMP:POWER_OFF:%s", host);		break;#endif /*ST_POWEROFF*/	case ST_GENERIC_RESET:		snprintf(snd, SND_SIZE, "EMP:POWER_CYCLE:%s", host);		break;	default:		return S_INVAL;	}	api_nexxus_send_ipc(sd->h, snd, strlen(snd)+1);	while(1) {		if (api_nexxus_wait_for_data(sd->h, &rcv, &rcvlen, 20)<0) {			return S_RESETFAIL;		}		if (!(tk = strtok(rcv,":"))) { /*EMP*/			break;		}else if (!(tk=strtok(NULL,":"))) { /* Job ID */			break;		}else if (!(tk=strtok(NULL,":"))) { /* one of teh below */			break;		} else if ( !strcmp(tk, "JOB_COMPLETED")) {			free(rcv);			return S_OK;		} else if(!strcmp(tk, "JOB_STARTED")) {			free(rcv);			continue;		} else if(!strcmp(tk, "JOB_ERROR")) {			free(rcv);			return S_RESETFAIL;		} else {			/* WTF?! */			LOG(PIL_CRIT, "Unexpected token \"%s\" in line \"%s\"\n"			    , tk, rcv);			break;		}	}	return S_RESETFAIL;}/* list => "nexxus:username:password" */static const char **vacm_get_confignames(StonithPlugin * s){	static const char * ret[] = {ST_NEXXUS, ST_LOGIN, ST_PASSWD, NULL};	return ret;}static intvacm_set_config(StonithPlugin *s, StonithNVpair * list){	struct pluginDevice* sd = (struct pluginDevice *)s;	int		rc;	StonithNamesToGet	namestoget [] =	{	{ST_NEXXUS,	NULL}	,	{ST_LOGIN,	NULL}	,	{ST_PASSWD,	NULL}	,	{NULL,		NULL}	};	ERRIFWRONGDEV(s, S_OOPS);	if (sd->sp.isconfigured) {		return S_OOPS;	}	if ((rc=OurImports->GetAllValues(namestoget, list)) != S_OK) {		return rc;	}	sd->nexxus = namestoget[0].s_value;	sd->user   = namestoget[1].s_value;	sd->passwd = namestoget[2].s_value;	/* When to initialize the sd->h */	return(S_OK);}/* * The "vacmconf:" is in the conffile so that one file could be used for * multiple device configs.  This module will only look at the first line * that starts with this token.  All other line are ignored. (and thus * could contain configs for other modules.) * * I don't think any other stonith modules do this currently. */const char *vacm_getinfo(StonithPlugin *s, int reqtype){	const char *		ret;   	ERRIFWRONGDEV(s, NULL);	switch (reqtype) {		case ST_DEVICEID:		/* What type of device? */			ret = dgettext(ST_TEXTDOMAIN, "VACM");			break;		case ST_DEVICENAME:		/* Which particular device? */			ret = dgettext(ST_TEXTDOMAIN, "VACM");			break;		case ST_DEVICEDESCR:		/* Description of dev type */			ret = "A driver for the VA Linux Cluster Manager.";			break;		case ST_DEVICEURL:		/* VACM's web site */			ret = "http://vacm.sourceforge.net/";			break;		default:			ret = NULL;			break;	}	return ret;}voidvacm_destroy(StonithPlugin *s){	struct pluginDevice *sd;	VOIDERRIFWRONGDEV(s);	sd = (struct pluginDevice*)s;	if( sd->h ) {		api_nexxus_disconnect(sd->h);	}	sd->pluginid = NOTpluginid;	if (sd->nexxus != NULL) {		FREE(sd->nexxus);		sd->nexxus = NULL;	}	if (sd->user != NULL) {		FREE(sd->user);		sd->user = NULL;	}	if (sd->passwd != NULL) {		FREE(sd->passwd);		sd->passwd = NULL;	}	free(sd); sd = NULL;}static StonithPlugin *vacm_new(void){	struct pluginDevice *sd;	sd = malloc(sizeof(struct pluginDevice));	if (sd == NULL) {		LOG(PIL_CRIT,	"%s", "out of memory");		return(NULL);	}	memset(sd, 0, sizeof(*sd));	sd->h = NULL;	sd->pluginid = pluginid;	sd->nexxus = NULL;	sd->user = NULL;	sd->passwd = NULL;	sd->sp.s_ops = &vacmOps;	return &(sd->sp);	/* same as "sd" */}

⌨️ 快捷键说明

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