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

📄 cyclades.c

📁 在LINUX下实现HA的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: cyclades.c,v 1.1.2.8 2005/05/20 19:43:33 blaschke Exp $ *//* * Stonith module for Cyclades AlterPath PM * Bases off the SSH plugin * * Copyright (c) 2004 Cyclades corp. * * Author: Jon Taylor <jon.taylor@cyclades.com> * * Rewritten from scratch using baytech.c structure and code  * and currently maintained by *       Marcelo Tosatti  <marcelo.tosatti@cyclades.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *  * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Lesser General Public License for more details. *  * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * */#include <portability.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <errno.h>#include <syslog.h>#include <libintl.h>#include <sys/wait.h>#include <glib.h>#include <stonith/stonith.h>#include "stonith_signal.h"#define PIL_PLUGINTYPE          STONITH_TYPE#define PIL_PLUGINTYPE_S        STONITH_TYPE_S#define PIL_PLUGIN              cyclades #define PIL_PLUGIN_S            "cyclades"#define PIL_PLUGINLICENSE 	LICENSE_LGPL#define PIL_PLUGINLICENSEURL 	URL_LGPL#include <pils/plugin.h>/* * cycladesclose is called as part of unloading the cyclades STONITH plugin. * If there was any global data allocated, or file descriptors opened, etc. * which is associated with the plugin, and not a single interface * in particular, here's our chance to clean it up. */static voidcycladesclosepi(PILPlugin*pi){}/* * cycladescloseintf called as part of shutting down the cyclades STONITH * interface.  If there was any global data allocated, or file descriptors * opened, etc.  which is associated with the ssh implementation, * here's our chance to clean it up. */static PIL_rccycladescloseintf(PILInterface* pi, void* pd){	return PIL_OK;}static void *		cyclades_new(void);static void		cyclades_destroy(Stonith *);static int		cyclades_set_config_file(Stonith *, const char * cfgname);static int		cyclades_set_config_info(Stonith *, const char * info);static const char *	cyclades_getinfo(Stonith * s, int InfoType);static int		cyclades_status(Stonith * );static int		cyclades_reset_req(Stonith * s, int request, const char * host);static char **		cyclades_hostlist(Stonith  *);static void		cyclades_free_hostlist(char **);static struct stonith_ops cycladesOps ={	cyclades_new,			/* Create new STONITH object	*/	cyclades_destroy,		/* Destroy STONITH object	*/	cyclades_set_config_file,	/* set configuration from file	*/	cyclades_set_config_info,	/* Get configuration from file	*/	cyclades_getinfo,		/* Return STONITH info string	*/	cyclades_status,		/* Return STONITH device status	*/	cyclades_reset_req,		/* Request a reset */	cyclades_hostlist,		/* Return list of supported hosts */	cyclades_free_hostlist		/* free above list */};PIL_PLUGIN_BOILERPLATE("1.0", Debug, cycladesclosepi);static const PILPluginImports*  PluginImports;static PILPlugin*               OurPlugin;static PILInterface*		OurInterface;static StonithImports*		OurImports;static void*			interfprivate;#define LOG		PluginImports->log#define MALLOC		PluginImports->alloc#define STRDUP  	PluginImports->mstrdup#define FREE		PluginImports->mfree#define EXPECT_TOK	OurImports->ExpectToken#define STARTPROC	OurImports->StartProcessPIL_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	,	&cycladesOps	,	cycladescloseintf		/*close */	,	&OurInterface	,	(void*)&OurImports	,	&interfprivate); }#define	DEVICE	"Cyclades PM"#define WHITESPACE	" \t\n\r\f"/* *    Cyclades STONITH device * */struct cycladesDevice {	const char *	cycladesid;	char *		device;	char *		user;	int config;	int serial_port;	/* pid of ssh client process and its in/out file descriptors */	pid_t		pid; 	int 		rdfd, wrfd;		};static struct Etoken StatusOutput[] = { 	{ "Outlet\t\tName\t\tStatus\t\tUsers\t\tInterval (s)", 0, 0},	{ NULL, 0, 0} };static struct Etoken CRNL[] =           { {"\n",0,0},{"\r\n",0,0},{NULL,0,0}};/* Commands of PM devices */static char status_all[] = "status all";static char cycle[] = "cycle";static int CYC_robust_cmd(struct cycladesDevice *, char *);static void CYCkillcomm(struct cycladesDevice *);static int CYCScanLine(struct cycladesDevice*, int, char *, int);static const char * cycladesid = "CycladesDevice-Stonith";static const char * NOTcycladesID = "Cyclades device has been destroyed";#define MAX_OUTLETS	128#define	ISCYCLADESDEV(i)	(((i)!= NULL && (i)->pinfo != NULL)	\	&& ((struct cycladesDevice *)(i->pinfo))->cycladesid == cycladesid)#ifndef MALLOCT#	define     MALLOCT(t)      ((t *)(MALLOC(sizeof(t)))) #endif#define N_(text)	(text)#define _(text)		dgettext(ST_TEXTDOMAIN, text)#define EXPECT(p,t,b,l)     {						\                        	if (LookFor(sd, p, t, b, l) < 0)	\                                	return(errno == ETIMEDOUT	\                        	?       S_TIMEOUT : S_OOPS);		\                        }#define NULLEXPECT(p,t,b,l) {						\                                if (LookFor(sd, p, t, b, l) < 0)	\                                        return(NULL);			\                        }#define ZEROEXPECT(p,t,b,l) {						\                                if (LookFor(sd, p, t, b, l) < 0)	\                                        return(0);			\                        }#define RESETEXPECT(p,t,b,l)     {					\                        	if (LookFor(sd, p, t, b, l) < 0) {      \					FREE(outletstr);		\	                                return(errno == ETIMEDOUT       \        	                ?       S_RESETFAIL : S_OOPS);          \				}					\                        }static intCYCScanLine(struct cycladesDevice* sd, int timeout, char * buf, int max){        if (EXPECT_TOK(sd->rdfd, CRNL, timeout, buf, max) < 0) {                CYCkillcomm(sd);                sd->pid = -1;                return(S_OOPS);        }        return(S_OK);}#define MAXSAVE 512static intLookFor(struct cycladesDevice* sd, struct Etoken * tlist, int timeout, char *buf,		int max){        int     rc;                                                                                             if ((rc = EXPECT_TOK(sd->rdfd, tlist, timeout, buf, max)) < 0){		if (tlist == StatusOutput) {			/* if status all returns nothing, unknown device */			syslog(LOG_ERR, _("Unknown " DEVICE " device %s")			,	sd->device);		}else{	                syslog(LOG_ERR, _("Did not find string: '%s' from "				DEVICE "."), tlist[0].string);                	syslog(LOG_ERR, _("Got '%s' from " DEVICE " instead.")	                ,       buf);		}                CYCkillcomm(sd);                return(-1);        }#if 0        syslog(LOG_INFO        ,       "Cyclades: Expecting [%s] Received [%s]"        ,       tlist[0].string        ,       buf);#endif        return(rc);}static intcyclades_status(Stonith  *s){	struct cycladesDevice *sd = s->pinfo;	char *cmd = status_all;	char    savebuf[MAXSAVE];        savebuf[MAXSAVE-1] = EOS;        savebuf[0] = EOS;	if (!ISCYCLADESDEV(s)) {		syslog(LOG_ERR, "invalid argument to cyclades_status");		return(S_OOPS);	}	if (CYC_robust_cmd(sd, cmd) != S_OK) {		syslog(LOG_ERR, "can't run status all command");		return(S_OOPS);	}	EXPECT(StatusOutput, 50, savebuf, sizeof(savebuf));	return (S_OK);}static void CYCkillcomm(struct cycladesDevice *sd){	if (sd->pid > 0) {		STONITH_KILL(sd->pid, SIGKILL);                (void)waitpid(sd->pid, NULL, 0);                sd->pid = -1;	}}static int CYC_run_command(struct cycladesDevice *sd, char *cmd){	char	SshCommand[MAX_OUTLETS*4];	snprintf(SshCommand, sizeof(SshCommand),			"exec ssh -q %s@%s /bin/pmCommand %d %s 2>/dev/null", 			sd->user, sd->device, sd->serial_port, cmd);	sd->pid = STARTPROC(SshCommand, &sd->rdfd, &sd->wrfd);	if (sd->pid <= 0)		return(S_OOPS);	return(S_OK);}static int CYC_robust_cmd(struct cycladesDevice *sd, char *cmd){	int rc = S_OOPS;	int i;	for (i=0; i < 20 && rc != S_OK; i++) {		if (sd->pid > 0)			CYCkillcomm(sd);		if (CYC_run_command(sd, cmd) != S_OK) {			CYCkillcomm(sd);			continue;		} 		rc = S_OK;	}	return rc;}static int CYCNametoOutlet(struct cycladesDevice *sd, const char *host, int *outlets, int maxoutlet){	char *cmd = status_all;	char	savebuf[MAXSAVE];	int err;	int outlet, numoutlet = 0;	char name[10], locked[10], on[4];	if (CYC_robust_cmd(sd, cmd) != S_OK) {		syslog(LOG_ERR, "can't run status all command");		return 0;	}	ZEROEXPECT(StatusOutput, 50, savebuf, sizeof(savebuf));	ZEROEXPECT(CRNL, 50, savebuf, sizeof(savebuf));	do {		memset(savebuf, 0, sizeof(savebuf));		memset(name, 0, sizeof(name));		memset(locked, 0, sizeof(locked));		memset(on, 0, sizeof(on));		err = CYCScanLine(sd, 2, savebuf, sizeof(savebuf));		if ((err == S_OK) &&		    (sscanf(savebuf,"%3d %10s %10s %3s", &outlet, 			name, locked, on) > 0)) {			g_strdown(name);			if (strstr(locked, "ocked") && !strcmp(name, host)) {				if (numoutlet >= maxoutlet) {					syslog(LOG_ERR, "too many outlets");					return 0;				}				outlets[numoutlet++] = outlet;			}		}	} while (err == S_OK);	return numoutlet;}/* *	Return the list of hosts configured for this Cyclades device */static char **cyclades_hostlist(Stonith  *s){	struct cycladesDevice*	sd;	char *cmd = status_all;	char    savebuf[MAXSAVE];	int err, i;	int outlet;	int numnames = 0;	char name[10], locked[10], on[4];	char *NameList[MAX_OUTLETS];	char **ret = NULL;	if (!ISCYCLADESDEV(s)) {		syslog(LOG_ERR, "invalid argument to cyclades_hostlist");		return(NULL);	}	sd = (struct cycladesDevice*) s->pinfo;	if (CYC_robust_cmd(sd, cmd) != S_OK) {		syslog(LOG_ERR, "can't run status all command");		return (NULL);	}	memset(savebuf, 0, sizeof(savebuf));	NULLEXPECT(StatusOutput, 50, savebuf, sizeof(savebuf));	NULLEXPECT(CRNL, 50, savebuf, sizeof(savebuf));	do {		char *nm;		memset(savebuf, 0, sizeof(savebuf));

⌨️ 快捷键说明

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