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

📄 hbaping.c

📁 linux集群服务器软件代码包
💻 C
字号:
/* * hbaping.c: Fiber Channel Host Bus Adapters (HBA) aliveness code for heartbeat * * Copyright (C) 2004 Alain St-Denis <alain.st-denis@ec.gc.ca>  *  * The checksum code in this file code was borrowed from the ping program. * * SECURITY NOTE:  It would be very easy for someone to masquerade as the * device that you're pinging.  If they don't know the password, all they can * do is echo back the packets that you're sending out, or send out old ones. * This does mean that if you're using such an approach, that someone could * make you think you have quorum when you don't during a cluster partition. * The danger in that seems small, but you never know ;-) * * 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 * *//* * This plugin only checks if it can reach device 0 by sending a HBA_SendScsiInquiry.  * There is room for improvement here. * */#include <time.h>#include <portability.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <ctype.h>#include <fcntl.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/param.h>#ifdef HAVE_NETINET_IN_SYSTM_H#	include <netinet/in_systm.h>#endif /* HAVE_NETINET_IN_SYSTM_H */#ifdef HAVE_NETINET_IP_VAR_H#	include <netinet/ip_var.h>#endif /* HAVE_NETINET_IP_VAR_H */#ifdef HAVE_NETINET_IP_H#	include <netinet/ip.h>#endif /* HAVE_NETINET_IP_H */#ifdef HAVE_NETINET_IP_COMPAT_H#	include <netinet/ip_compat.h>#endif /* HAVE_NETINET_IP_COMPAT_H */#ifdef HAVE_NETINET_IP_FW_H#	include <netinet/ip_fw.h>#endif /* HAVE_NETINET_IP_FW_H */#include <netinet/ip_icmp.h>#include <netdb.h>#include <hbaapi.h>#include <heartbeat.h>#include <HBcomm.h>#define PIL_PLUGINTYPE          HB_COMM_TYPE#define PIL_PLUGINTYPE_S        HB_COMM_TYPE_S#define PIL_PLUGIN              hbaping#define PIL_PLUGIN_S            "hbaping"#define PIL_PLUGINLICENSE	LICENSE_LGPL#define PIL_PLUGINLICENSEURL	URL_LGPL#include <pils/plugin.h>struct hbaping_private {        HBA_WWN		        addr;   	/* dest WWN */        HBA_HANDLE		handle;		/* hba handle */	char 			namebuf[1028];  /* interface name */	int			ident;		/* heartbeat pid */	int			iseq;		/* sequence number */};static struct hb_media*	hbaping_new (const char* interface);static int		hbaping_open (struct hb_media* mp);static int		hbaping_close (struct hb_media* mp);static void *		hbaping_read (struct hb_media* mp, int* lenp);static int		hbaping_write (struct hb_media* mp, void* p, int len);static struct hbaping_private *			new_hbaping_interface(const char * host);static int		hbaping_mtype(char **buffer);static int		hbaping_descr(char **buffer);static int		hbaping_isping(void);#define		ISPINGOBJECT(mp)	((mp) && ((mp)->vf == (void*)&hbapingOps))#define		PINGASSERT(mp)	g_assert(ISPINGOBJECT(mp))static struct hb_media_fns hbapingOps ={	hbaping_new,	/* Create single object function */	NULL,		/* whole-line parse function */	hbaping_open,	hbaping_close,	hbaping_read,	hbaping_write,	hbaping_mtype,	hbaping_descr,	hbaping_isping,};PIL_PLUGIN_BOILERPLATE2("1.0", Debug);static const PILPluginImports*  PluginImports;static PILPlugin*               OurPlugin;static PILInterface*		OurInterface;static struct hb_media_imports*	OurImports;static void*			interfprivate;#define LOG	PluginImports->log#define MALLOC	PluginImports->alloc#define FREE	PluginImports->mfreePIL_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	,	&hbapingOps	,	NULL		/*close */	,	&OurInterface	,	(void*)&OurImports	,	interfprivate); }static inthbaping_mtype(char **buffer) { 		*buffer = MALLOC((strlen(PIL_PLUGIN_S) * sizeof(char)) + 1);	strcpy(*buffer, PIL_PLUGIN_S);	return strlen(PIL_PLUGIN_S);}static inthbaping_descr(char **buffer) { 	const char *str = "hbaping membership";		*buffer = MALLOC((strlen(str) * sizeof(char)) + 1);	strcpy(*buffer, str);	return strlen(str);}/* Yes, a ping device */ static int hbaping_isping(void) {	return 1;}static struct hbaping_private *new_hbaping_interface(const char * host){	struct hbaping_private*	ppi;	HBA_UINT32 hba_cnt;	if ((ppi = (struct hbaping_private*)MALLOC(sizeof(struct hbaping_private))) == NULL) {		return NULL;	}	memset(ppi, 0, sizeof (*ppi));	if (HBA_LoadLibrary() != HBA_STATUS_OK) {		LOG(PIL_CRIT, "error loading hbaapi: %s", strerror(errno));		return(NULL);	}	hba_cnt = HBA_GetNumberOfAdapters();	if (hba_cnt == 0) {		LOG(PIL_CRIT, "no HBA found");		return(NULL);	}	/* adapter identified by its name (e.g. qlogic-qla2200-0)	 * only one HBA and one port per HBA. Bad.	 */	strncpy(ppi->namebuf, host, sizeof(ppi->namebuf));		return(ppi);}/* *	Create new ping heartbeat object  *	Name of host is passed as a parameter */static struct hb_media *hbaping_new(const char * host){	struct hbaping_private*	ipi;	struct hb_media *	ret;	ipi = new_hbaping_interface(host);	if (ipi == NULL) {		return(NULL);	}	ret = (struct hb_media *) MALLOC(sizeof(struct hb_media));	if (ret != NULL) {		char * name;		ret->pd = (void*)ipi;		name = MALLOC(strlen(host)+1);		strcpy(name, host);		ret->name = name;		add_node(host, PINGNODE_I);	}else{		FREE(ipi); ipi = NULL;	}	return(ret);}/* *	Close UDP/IP broadcast heartbeat interface */static inthbaping_close(struct hb_media* mp){	struct hbaping_private * ei;	int	rc = HA_OK;	PINGASSERT(mp);	ei = (struct hbaping_private *) mp->pd;	HBA_CloseAdapter(ei->handle);	return(rc);}/* * Receive a heartbeat ping reply packet. * Here we do a HBA_SendScsiInquiry and build a HA msg if it is * successful. */static void *hbaping_read(struct hb_media* mp, int *lenp){	struct hbaping_private *	ei;	char RspBuffer[96], SenseBuffer[96];	int rc;	struct ha_msg *nmsg;	static char ts[32];	void *pkt;	sleep(1); /* since we are not polling... */	PINGASSERT(mp);	ei = (struct hbaping_private *) mp->pd;	rc = HBA_SendScsiInquiry(ei->handle, ei->addr, 0, 0, 0,			(void *)&RspBuffer, sizeof(RspBuffer),			(void *)&SenseBuffer, sizeof(SenseBuffer));	if (rc != HBA_STATUS_OK) {		/* LOG(PIL_CRIT, "can't inquiry to %s, status = %d", ei->namebuf, rc); */		return NULL;	}	if ((nmsg = ha_msg_new(5)) == NULL) {		LOG(PIL_CRIT, "cannot create new message");		return NULL;	}        sprintf(ts, "%lx", time(NULL));	if (ha_msg_add(nmsg, F_TYPE, T_NS_STATUS) != HA_OK			||      ha_msg_add(nmsg, F_STATUS, PINGSTATUS) != HA_OK			||      ha_msg_add(nmsg, F_ORIG, ei->namebuf) != HA_OK			||      ha_msg_add(nmsg, F_TIME, ts) != HA_OK) {		ha_msg_del(nmsg); nmsg = NULL;		LOG(PIL_CRIT, "cannot add fields to message");		return NULL;	}	if (add_msg_auth(nmsg) != HA_OK) {		LOG(PIL_CRIT, "cannot add auth field to message");		ha_msg_del(nmsg); nmsg = NULL;		return NULL;	}		pkt = msg2wirefmt(nmsg, lenp);	if( pkt == NULL){		LOG(PIL_WARN, "containg msg to wirefmt failed in hbaping_read()\n");		return NULL;	}		ha_msg_del(nmsg);		return pkt;	}/* * Send a heartbeat packet over broadcast UDP/IP interface * * This is a noop. * * We ignore packets we're given to write that aren't "status" packets. * */static inthbaping_write(struct hb_media* mp, void *p, int len){/*  	struct hbaping_private *	ei; *//*  	HBA_PORTATTRIBUTES hba_portattrs; *//*  	int			rc; *//*  	const char *		type; *//*  	const char *		ts; */	PINGASSERT(mp);/*  	ei = (struct hbaping_private *) mp->pd; *//*  	type = ha_msg_value(msg, F_TYPE); *//*  	if (type == NULL || strcmp(type, T_STATUS) != 0  *//*  	|| ((ts = ha_msg_value(msg, F_TIME)) == NULL)) { *//*  		return HA_OK; *//*  	} */	/*rc = HBA_GetAdapterPortAttributes(ei->handle, 0, &hba_portattrs);*/	/*  	rc = HBA_STATUS_OK; */	/*  	if (rc != HBA_STATUS_OK) { */	/*  		LOG(PIL_CRIT, "can't get %s hba attributes (status = %d)!", ei->namebuf, rc); */	/*  		return HA_FAIL; */	/*  	} */		/*if (hba_portattrs.PortState != HBA_PORTSTATE_ONLINE) {		LOG(PIL_CRIT, "hba %s is not online!", ei->namebuf);		return HA_FAIL;	}*/	return HA_OK;}/* *	Open hbaping. Basically a noop... */static inthbaping_open(struct hb_media* mp){	struct hbaping_private * ppi;	int retval;	union {		HBA_FCPTARGETMAPPING	fcp_tmap;		struct {			HBA_UINT32	cnt;			HBA_FCPSCSIENTRY	entry[32];		} fcp_tmapi;	} map;	PINGASSERT(mp);	ppi = (struct hbaping_private *) mp->pd;		if ((ppi->handle = HBA_OpenAdapter(ppi->namebuf)) == 0) {		LOG(PIL_CRIT, "can't open adapter %s", ppi->namebuf);		return(HA_FAIL);	}		/* discover target mapping, use the first port only	 * will be used to contact shared device controller	 * in hbaping_write	 */		map.fcp_tmapi.cnt = 32;	retval = HBA_GetFcpTargetMapping(ppi->handle, &map.fcp_tmap);	if (retval != HBA_STATUS_OK) {		LOG(PIL_CRIT, "failure of HBA_GetFcpTargetMapping: %d", retval);		return(HA_FAIL);	}	if (map.fcp_tmap.NumberOfEntries == 0) {		LOG(PIL_CRIT, "no target found for adapter %s", ppi->namebuf);		return(HA_FAIL);	}	/*memcpy(&(ppi->addr), &(map.fcp_tmap.entry[0].FcpId.PortWWN), 	  sizeof(HBA_WWN));*/	ppi->addr = map.fcp_tmap.entry[0].FcpId.PortWWN;		ppi->ident = getpid() & 0xFFFF;	LOG(LOG_NOTICE, "hbaping heartbeat started.");	return HA_OK;}

⌨️ 快捷键说明

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