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

📄 recoverymgrd.c

📁 linux集群服务器软件代码包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: recoverymgrd.c,v 1.12 2005/02/20 03:02:43 alan Exp $ *//* * Generic Recovery manager implementation *  * Copyright (c) 2002 Intel Corporation  * 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 is a generic implementation of a recovery manager. * For the most basic case, the recovery manager will handle  * recovery of an application that misses a heartbeat with the * apphbd. *  * The recovery manager plug-in must be loaded by apphbd. * The apphbd will send notifications to the recovery manager via * the recovery manager plug-in. *  */#include <portability.h>#include <sys/time.h>#include <stdlib.h>#include <signal.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/wait.h>#include <apphb.h>#include <clplumbing/cl_log.h>#include <clplumbing/ipc.h>#include <clplumbing/cl_signal.h>#include <clplumbing/longclock.h>#include <clplumbing/Gmain_timeout.h>#include <clplumbing/GSource.h>#include <clplumbing/cl_poll.h>#include <clplumbing/uids.h>#include <clplumbing/recoverymgr_cs.h>#include <clplumbing/lsb_exitcodes.h>#include <clplumbing/coredumps.h>#include <apphb_notify.h>#include <recoverymgr.h>#include "recoverymgrd.h"#include "configfile.h"/* indicates how many milliseconds between heartbeats */#define HBINTERVAL_MSEC		2000#define CONFIG_FILE	"./recoverymgrd.conf"#define DEBUG #define         DBGMIN          1#define         DBGDETAIL       3int             debug = 10;const char* cmdname = "recoverymgrd";extern FILE* yyin;/** The main event loop */GMainLoop*      mainloop = NULL;GHashTable 	*scripts; /* location for recovery info */RecoveryInfo 	*current; /* used for inserting to hash table */int 		eventindex; int		length;/* used for obtaining the basename of the script */char 		*tempname; void yyerror(const char *str){        fprintf(stderr,"error parsing config file: %s\n", str);}int yywrap(void){        return 1;}static void print_hash(gpointer key, gpointer value, gpointer userdata){	char* key_str = key;	char* value_str = value;	cl_log(LOG_INFO, "key[%s], value[%s]\n", key_str, value_str);}gbooleanparseConfigFile(const char* conf_file){   gboolean retval = TRUE;   scripts = g_hash_table_new(g_str_hash, g_int_equal);      if((yyin = fopen(conf_file,"r")) == NULL){   	cl_log(LOG_ERR, "Cannot open configure file:[%s]"			, conf_file);	;	return(FALSE);   }      if(yyparse()){   	retval = FALSE;   };   fclose(yyin);   if(debug > DBGMIN){   	g_hash_table_foreach(scripts, print_hash, NULL);    }   return retval;}intmain(int argc, char *argv[]){   	int rc;    	int retval = 0;     	const char* conf_file = CONFIG_FILE;	cl_cdtocoredir();		if(argc == 2){		conf_file = argv[1];	}else if(argc > 2){		printf("Usage: %s [config_file]\n", cmdname);		exit(LSB_EXIT_NOTCONFIGED);	}   		cl_log_set_entity(argv[0]);   	cl_log_enable_stderr(TRUE);   	cl_log_set_facility(LOG_USER);   	cl_log(LOG_INFO, "Starting %s", argv[0]);   	signal(SIGCHLD, sigchld_handler);		if(parseConfigFile(conf_file) == FALSE){		exit(LSB_EXIT_NOTCONFIGED);	};   /* make self a daemon */#ifndef DEBUG   	daemon(0,0);#else     	printf("Debug mode -- non daemon\n");#endif   	/* register with apphbd as a client and send pings */   	retval = register_hb();   	if (0 != retval)   	{     		cl_perror("Error registering -- is apphbd running??");     		exit(retval);   	}      	create_connection();      	/* unregister and shutdown */   	rc = apphb_unregister();   	if (rc < 0)    	{      		cl_perror("apphb_unregister failure");      		exit(3);   	}   	return 0; }/** * Sends a registration message to the apphbd  * and sets the heartbeat interval. * Sets up a callback for sending heartbeats. */int register_hb(void){   	int rc;   	rc = apphb_register("recovery manager", "normal");   	if (rc < 0)    	{      		cl_perror("registration failure");      		return 1;   	}   	rc = apphb_setinterval(HBINTERVAL_MSEC);   	if (rc < 0)    	{      		cl_perror("setinterval failure");      		return 2;   	}   	setup_hb_callback();   	return 0;}/** * Sets up apphb_hb as a signal handler for SIGALRM,  * then sets up a timer to go off on the  * heartbeat interval */int setup_hb_callback(void){   	struct itimerval itimerValue;	struct itimerval itimerOldValue;   	signal(SIGALRM, (void (*) (int)) (apphb_hb));   	itimerValue.it_interval.tv_sec = 0;   	itimerValue.it_interval.tv_usec = HBINTERVAL_MSEC;   	itimerValue.it_value.tv_sec = 0;   	itimerValue.it_value.tv_usec = HBINTERVAL_MSEC;   	if (setitimer(ITIMER_REAL, &itimerValue, &itimerOldValue)!=0)   	{       		cl_log(LOG_CRIT, "error setting up hb callback");       		return 1;   	}   	return 0;}/** * *@return non-zero on failure */int create_connection(void){        char            path[] = IPC_PATH_ATTR;        char            commpath[] = RECOVERYMGRSOCKPATH;        struct IPC_WAIT_CONNECTION*     wconn;        GHashTable*     wconnattrs;        /* Create a "waiting for connection" object */        wconnattrs = g_hash_table_new(g_str_hash, g_str_equal);        g_hash_table_insert(wconnattrs, path, commpath);        wconn = ipc_wait_conn_constructor(IPC_ANYTYPE, wconnattrs);        if (wconn == NULL) {                cl_log(LOG_CRIT, "Unable to create wcon of type %s", IPC_ANYTYPE);                return 1;        }        /* Create a source to handle new connection requests */        G_main_add_IPC_WaitConnection(G_PRIORITY_HIGH, wconn        ,       NULL, FALSE, pending_conn_dispatch, wconn, NULL);	g_main_set_poll_func(cl_glibpoll);        /* Create the mainloop and run it... */        mainloop = g_main_new(FALSE);                g_main_run(mainloop);        wconn->ops->destroy(wconn);	/* free script hash table */	g_hash_table_foreach_remove(scripts, hash_remove_func, NULL);        /*unlink(PIDFILE); */        return 0;}/** * Frees memory allocated in the parser for the hash table * contents. * */gbooleanhash_remove_func(gpointer key, gpointer value, gpointer user_data){  	if (value)		free(value);	/* the key is a pointer to value->appname */	return TRUE;}/** * This function is called for every requested connection. * This is where we accept it or not. */static gboolean pending_conn_dispatch(IPC_Channel* src, gpointer user){        if (debug >= DBGMIN) 	{		cl_log(LOG_DEBUG,"received connection request\n");                cl_log(LOG_DEBUG, "recoverymgr dispatch: IPC_channel: 0x%x"                " pid=%d"                ,       GPOINTER_TO_UINT(src)                ,       src->farside_pid);        }        if (src != NULL) 	{                /* This sets up comm channel w/client                 * Ignoring the result value is OK, because                 * the client registers itself w/event system.                 */                (void)recoverymgr_client_new(src);        }	else	{                cl_perror("accept_connection failed");                sleep(1); /* WHY IS THIS HERE? */        }        return TRUE;}/** *  Create new client (we don't know appname or pid yet) . * This is called when a connection is first established. */static recoverymgr_client_t*recoverymgr_client_new(struct IPC_CHANNEL* ch){        recoverymgr_client_t* ret;        ret = g_new(recoverymgr_client_t, 1);	memset(ret, 0, sizeof(*ret));	        ret->appname = NULL;        ret->appinst = NULL;        ret->ch = ch;        ret->pid = 0;        ret->deleteme = FALSE;        ret->rcmsg.msg_body = &ret->rc;        ret->rcmsg.msg_len = sizeof(ret->rc);        ret->rcmsg.msg_done = NULL;        ret->rcmsg.msg_private = NULL;        ret->rc.rc = 0;        if (debug >= DBGMIN) {                cl_log(LOG_DEBUG, "recoverymgr_client_new: channel: 0x%x"                " pid=%d"                ,       GPOINTER_TO_UINT(ch)                ,       ch->farside_pid);        }        ret->source = G_main_add_IPC_Channel(G_PRIORITY_DEFAULT        ,       ch, FALSE, recoverymgr_dispatch, (gpointer)ret        ,       recoverymgr_client_remove);        if (!ret->source) {                memset(ret, 0, sizeof(*ret));                ret=NULL;                return ret;        }        return ret;}/**  * This function is called for every incoming message on an * existing connection.  */static gbooleanrecoverymgr_dispatch(IPC_Channel* src, gpointer Client){        recoverymgr_client_t*         client  = Client;        if (debug >= DBGDETAIL) {                cl_log(LOG_DEBUG, "recoverymgr_dispatch: client: %ld"                ,       (long)client->pid);        }        if (client->ch->ch_status == IPC_DISCONNECT) {                client->deleteme = TRUE;                return FALSE;        }        while (!client->deleteme        &&      client->ch->ops->is_message_pending(client->ch)) {

⌨️ 快捷键说明

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