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

📄 stonithd_lib.c

📁 linux集群服务器软件代码包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* File: stonithd_lib.c * Description: Client library to STONITH deamon. * * Author: Sun Jiang Dong <sunjd@cn.ibm.com> * Copyright (c) 2004 International Business Machines * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU 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 software 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 * General Public License for more details. *  * You should have received a copy of the GNU 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 <config.h>#include <portability.h>#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <unistd.h>#include <fcntl.h>#include <signal.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/wait.h>#include <errno.h>#include <glib.h>#include <ha_msg.h>#include <clplumbing/cl_signal.h>#include <clplumbing/GSource.h>#include <clplumbing/uids.h>#include <clplumbing/cl_log.h>#include <clplumbing/lsb_exitcodes.h>#include <clplumbing/proctrack.h>#include <fencing/stonithd_api.h>#include <fencing/stonithd_msg.h>static const char * CLIENT_NAME = NULL;static pid_t CLIENT_PID = 0;static char CLIENT_PID_STR[16];static gboolean DEBUG_MODE	   = FALSE;static gboolean SIGNONED_TO_STONITHD = FALSE;static IPC_Channel * chan	   = NULL;static gboolean INT_BY_ALARM = FALSE;static unsigned int DEFAULT_TIMEOUT = 6;/* Must correspond to stonith_type_t *//* Not use it yet static const char * stonith_op_strname[] ={         "QUERY", "RESET", "POWERON", "POWEROFF"};*/static stonith_ops_callback_t stonith_ops_cb = NULL; static void * stonith_ops_cb_private_data = NULL;static stonithRA_ops_callback_t stonithRA_ops_cb = NULL;static void * stonithRA_ops_cb_private_data = NULL;static struct ha_msg * create_basic_reqmsg_fields(const char * apitype);static gboolean is_expected_msg(const struct ha_msg * msg,				const char * field_name1,				const char * field_content1,				const char * field_name2,				const char * field_content2 );static int chan_waitin_timeout(IPC_Channel * chan, unsigned int timeout);static int chan_waitout_timeout(IPC_Channel * chan, unsigned int timeout);static void sigalarm_handler(int signum);static void stdlib_log(int priority, const char * fmt, ...)G_GNUC_PRINTF(2,3);static void free_stonith_ops_t(stonith_ops_t * st_op);static void free_stonithRA_ops_t(stonithRA_ops_t * ra_op);intstonithd_signon(const char * client_name){	int rc = ST_FAIL;	char	path[] = IPC_PATH_ATTR;	char	sock[] = STONITHD_SOCK;	struct  ha_msg * request;	struct  ha_msg * reply;	GHashTable *	 wchanattrs;	uid_t	my_euid;	gid_t	my_egid;	const char * tmpstr;	if ( SIGNONED_TO_STONITHD ) {		/* if server is broken, then signoff and signon? important */		stdlib_log(LOG_INFO, "stonithd_signon: has sigoned to "			   "stonithd.");		return ST_OK;	}	wchanattrs = g_hash_table_new(g_str_hash, g_str_equal);        g_hash_table_insert(wchanattrs, path, sock);	/* Connect to the stonith deamon */	chan = ipc_channel_constructor(IPC_ANYTYPE, wchanattrs);	g_hash_table_destroy(wchanattrs);		if (chan == NULL) {		stdlib_log(LOG_ERR, "stonithd_signon: Can't connect to "			   "stonithd");		return ST_FAIL;	}        if (chan->ops->initiate_connection(chan) != IPC_OK) {		stdlib_log(LOG_ERR, "stonithd_signon: Can't initiate "			   "connection to stonithd");                return ST_FAIL;        }	CLIENT_PID = getpid();	snprintf(CLIENT_PID_STR, sizeof(CLIENT_PID_STR), "%d", CLIENT_PID);	if ( client_name != NULL ) {		CLIENT_NAME = client_name;	} else {		CLIENT_NAME = CLIENT_PID_STR;	}	if ( (request = create_basic_reqmsg_fields(ST_SIGNON)) == NULL) {		return ST_FAIL;	}	/* important error check client name length */	my_euid = geteuid();	my_egid = getegid();	if (  (	ha_msg_add_int(request, F_STONITHD_CEUID, my_euid) != HA_OK )	    ||(	ha_msg_add_int(request, F_STONITHD_CEGID, my_egid) != HA_OK )	   ) {		stdlib_log(LOG_ERR, "stonithd_signon: "			   "cannot add field to ha_msg.");		ZAPMSG(request);		ZAPCHAN(chan);		return ST_FAIL;	}	/* Send the registration request message */	if (msg2ipcchan(request, chan) != HA_OK) {		ZAPMSG(request);		ZAPCHAN(chan);		stdlib_log(LOG_ERR, "can't send signon message to IPC");		return ST_FAIL;	}	/* waiting for the output to finish */	chan_waitout_timeout(chan, DEFAULT_TIMEOUT);	ZAPMSG(request);	/* Read the reply... */	stdlib_log(LOG_DEBUG, "waiting for the signon reply msg.");        if ( IPC_OK != chan_waitin_timeout(chan, DEFAULT_TIMEOUT) ) {		stdlib_log(LOG_ERR, "waitin failed."); /*  how to deal. important */		return ST_FAIL;	}	if ( (reply = msgfromIPC_noauth(chan)) == NULL ) {		stdlib_log(LOG_ERR, "stonithd_signon: to fetch reply failed.");		return ST_FAIL;	}		if ( TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, 			     F_STONITHD_APIRPL, ST_RSIGNON) ) {		if ( ((tmpstr=cl_get_string(reply, F_STONITHD_APIRET)) != NULL)	   	    && (strncmp(tmpstr, ST_APIOK, strlen(ST_APIOK)) == 0) ) {			SIGNONED_TO_STONITHD = TRUE;			rc = ST_OK;			stdlib_log(LOG_DEBUG, "signoned to the stonithd.");		} else {			stdlib_log(LOG_DEBUG, "failed to signon to the "				   "stonithd.");		}	} else {		stdlib_log(LOG_DEBUG, "stonithd_signon: "			   "Got an unexpected message.");		/* Handle it furtherly ? */	}	ZAPMSG(reply);	return rc;}int stonithd_signoff(void){	int rc = ST_FAIL;	struct ha_msg * request, * reply;	const char * tmpstr;		if (SIGNONED_TO_STONITHD == FALSE) {		stdlib_log(LOG_NOTICE, "Has been in signoff status.");		return ST_OK;	}	if ( (request = create_basic_reqmsg_fields(ST_SIGNOFF)) == NULL) {		return ST_FAIL;	}	/* Send the signoff request message */	if (msg2ipcchan(request, chan) != HA_OK) {		ZAPMSG(request);		stdlib_log(LOG_ERR, "can't send signoff message to IPC");		return ST_FAIL;	}	/*  waiting for the output to finish */	chan_waitout_timeout(chan, DEFAULT_TIMEOUT);	ZAPMSG(request);	/* Read the reply... */	stdlib_log(LOG_DEBUG, "waiting for the signoff reply msg.");        if ( IPC_OK != chan_waitin_timeout(chan, DEFAULT_TIMEOUT) ) {		stdlib_log(LOG_ERR, "waitin failed.");		return ST_FAIL;	}	if ( (reply = msgfromIPC_noauth(chan)) == NULL ) {		stdlib_log(LOG_ERR, "stonithd_signoff: to fetch the reply msg "			   "failed.");		return ST_FAIL;	}		if ( TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, 			     F_STONITHD_APIRPL, ST_RSIGNOFF) ) {		if ( ((tmpstr=cl_get_string(reply, F_STONITHD_APIRET)) != NULL)	   	    && (strncmp(tmpstr, ST_APIOK, strlen(ST_APIOK)) == 0) ) {			SIGNONED_TO_STONITHD = FALSE;			CLIENT_NAME = NULL;			rc = ST_OK;			stdlib_log(LOG_INFO, "succeeded to sign off the "				   "stonithd.");		} else {			stdlib_log(LOG_INFO, "fail to sign off the stonithd.");		}	} else {		stdlib_log(LOG_DEBUG, "stonithd_signoff: "			   "Got an unexpected message.");	}	ha_msg_del(reply);	return rc;}IPC_Channel *stonithd_input_IPC_channel(void){	if ( SIGNONED_TO_STONITHD == TRUE ) {		return chan;	} else {		stdlib_log(LOG_ERR, "stonithd_input_IPC_channel: not signon.");		return NULL;	}}int stonithd_node_fence(stonith_ops_t * op){	int rc = ST_FAIL;	struct ha_msg * request, * reply;	const char * tmpstr;	if (op == NULL) {		stdlib_log(LOG_ERR, "stonithd_node_fence: op==NULL");		return ST_FAIL;	}		if (SIGNONED_TO_STONITHD == FALSE) {		stdlib_log(LOG_NOTICE, "Has been in signoff status.");		return ST_FAIL;	}	if ( (request = create_basic_reqmsg_fields(ST_STONITH)) == NULL) {		return ST_FAIL;	}	if (  (ha_msg_add_int(request, F_STONITHD_OPTYPE, op->optype) != HA_OK )	    ||(ha_msg_add(request, F_STONITHD_NODE, op->node_name ) != HA_OK)	    ||(ha_msg_add_int(request, F_STONITHD_TIMEOUT, op->timeout) 		!= HA_OK) ) {		stdlib_log(LOG_ERR, "stonithd_node_fence: "			   "cannot add field to ha_msg.");		ZAPMSG(request);		return ST_FAIL;	}	/* Send the stonith request message */	if (msg2ipcchan(request, chan) != HA_OK) {		ZAPMSG(request);		stdlib_log(LOG_ERR, "can't send signoff message to IPC");		return ST_FAIL;	}	/*  waiting for the output to finish */	chan_waitout_timeout(chan, DEFAULT_TIMEOUT);	ZAPMSG(request);		/* Read the reply... */	stdlib_log(LOG_DEBUG, "waiting for the stonith reply msg.");        if ( IPC_OK != chan_waitin_timeout(chan, DEFAULT_TIMEOUT) ) {		stdlib_log(LOG_ERR, "stonithd_node_fence: waitin failed.");		/* how to deal. important */		return ST_FAIL;	}	if ( (reply = msgfromIPC_noauth(chan)) == NULL ) {		stdlib_log(LOG_ERR, "stonithd_node_fence: fail to fetch reply");		return ST_FAIL;	}		if ( TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, 			     F_STONITHD_APIRPL, ST_RSTONITH) ) {		if ( ((tmpstr = cl_get_string(reply, F_STONITHD_APIRET)) != NULL) 	   	    && (strncmp(tmpstr, ST_APIOK, strlen(ST_APIOK)) == 0) ) {			rc = ST_OK;			stdlib_log(LOG_DEBUG, "stonith msg is sent to stonithd.");		} else {			stdlib_log(LOG_DEBUG, "failed to send stonith request to "				   "the stonithd.");		}	} else {		stdlib_log(LOG_DEBUG, "stonithd_node_fence: "			   "Got an unexpected message.");		/* Need to handle in other way? */	}	ZAPMSG(reply);	return rc;}gboolean stonithd_op_result_ready(void){	if ( SIGNONED_TO_STONITHD == FALSE ) {		stdlib_log(LOG_ERR, "stonithd_op_result_ready: "			   "failed due to not on signon status.");		return FALSE;	}		if ( chan == NULL ) {		stdlib_log(LOG_ERR, "stonithd_op_result_ready: "			   "failed due to IPC channel chan == NULL.");		return FALSE;	}		/* 	 * Regards IPC_DISCONNECT as a special result, so to prevent the caller	 * from the possible endless waiting. That can be caused by the way	 * in which the caller uses it.	 */	return (chan->ops->is_message_pending(chan)		|| chan->ch_status == IPC_DISCONNECT);}intstonithd_receive_ops_result(gboolean blocking){	struct ha_msg* reply = NULL;	const char * tmpstr = NULL;	int tmpint = 0;	int rc = ST_OK;	stdlib_log(LOG_DEBUG, "stonithd_receive_ops_result: begin");	/* If there is no msg ready and none blocking mode, then return */	if ((stonithd_op_result_ready() == FALSE) && (blocking == FALSE)) {		stdlib_log(LOG_INFO, "stonithd_receive_ops_result: "			   "no result available.");		return ST_OK;	}	if (stonithd_op_result_ready() == FALSE) {	/* at that time, blocking must be TRUE */		if (IPC_OK != chan->ops->waitin(chan)) {			return ST_FAIL;		}	}	reply = msgfromIPC_noauth(chan);	if ( TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL, 			     F_STONITHD_APIRPL, ST_STRET)  ) {		stonith_ops_t * st_op = NULL;		stdlib_log(LOG_DEBUG, "received stonith final ret.");		/* handle the stonith op result message */		st_op = g_new(stonith_ops_t, 1);			if ( ha_msg_value_int(reply, F_STONITHD_OPTYPE, &tmpint)			== HA_OK) {			st_op->optype = tmpint;			} else {			stdlib_log(LOG_ERR, "stonithd_receive_ops_result: the "				   "reply message contains no optype field.");			rc = ST_FAIL;		}		if ((tmpstr = cl_get_string(reply, F_STONITHD_NODE)) != NULL) {			st_op->node_name = g_strdup(tmpstr);		} else {			stdlib_log(LOG_ERR, "stonithd_receive_ops_result: the "				   "reply contains no node_name field.");			rc = ST_FAIL;		}		if ( ha_msg_value_int(reply, F_STONITHD_TIMEOUT, &tmpint)			== HA_OK ) {			st_op->timeout =  tmpint;			} else {			stdlib_log(LOG_ERR, "stonithd_receive_ops_result: the "				   "reply message contains no timeout field.");			rc = ST_FAIL;		}		if ( ha_msg_value_int(reply, F_STONITHD_CALLID, &tmpint)			== HA_OK ) {			st_op->call_id = tmpint;			} else {			stdlib_log(LOG_ERR, "stonithd_receive_ops_result: the "				   "reply message contains no call_id field.");			rc = ST_FAIL;		}		if (ha_msg_value_int(reply, F_STONITHD_FRC, &tmpint) == HA_OK) {			st_op->op_result = tmpint;		} else {			stdlib_log(LOG_ERR, "stonithd_receive_ops_result: the "				   "reply contains no op_result field.");			rc = ST_FAIL;		}		if ((tmpstr=cl_get_string(reply, F_STONITHD_APPEND)) != NULL) {			st_op->node_list = g_strdup(tmpstr);		} else {			st_op->node_list = NULL;			stdlib_log(LOG_DEBUG, "stonithd_receive_ops_result: the "				   "reply message contains no appendix field.");		}				if (stonith_ops_cb != NULL) {			stdlib_log(LOG_DEBUG, "trigger stonith op callback.");			stonith_ops_cb(st_op, stonith_ops_cb_private_data);		} else { 			stdlib_log(LOG_DEBUG, "No stonith op callback.");		}		free_stonith_ops_t(st_op);		ZAPMSG(reply);		return ST_OK;	}	if (  TRUE == is_expected_msg(reply, F_STONITHD_TYPE, ST_APIRPL,			     F_STONITHD_APIRPL, ST_RAOPRET ) ) {		stonithRA_ops_t * ra_op = NULL;		stdlib_log(LOG_DEBUG, "received stonithRA op final ret.");		/* handle the stonithRA op result message */		ra_op = g_new(stonithRA_ops_t, 1);		tmpstr = cl_get_string(reply, F_STONITHD_RSCID);		if (tmpstr != NULL) {			ra_op->rsc_id = g_strdup(tmpstr);			stdlib_log(LOG_DEBUG, "ra_op->rsc_id=%s.", 				     ra_op->rsc_id);		} else {			stdlib_log(LOG_ERR, "stonithd_receive_ops_result: the "				   "reply message contains no rsc_id field.");			rc = ST_FAIL;

⌨️ 快捷键说明

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