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

📄 stonithd.c

📁 linux集群服务器软件代码包
💻 C
📖 第 1 页 / 共 5 页
字号:
	executing_queue = g_hash_table_new_full(g_int_hash, g_int_equal,						 destory_key_of_op_htable,						 free_common_op_t);	/* To avoid the warning message when app_interval is very small. */	MY_APPHB_HB	/* drop_privs(0, 0); */  /* very important. cpu limit */	stonithd_log(LOG_DEBUG, "Enter g_mainloop\n");	stonithd_log(LOG_NOTICE, "%s %s", argv[0], M_STARTUP );	 	g_main_run(mainloop);	MY_APPHB_HB	if (SIGNONED_TO_APPHBD == TRUE) {		apphb_unregister();		SIGNONED_TO_APPHBD = FALSE;	}signoff_quit:	if (hb != NULL && hb->llc_ops->signoff(hb) != HA_OK) {		stonithd_log(LOG_ERR, "Cannot sign off from heartbeat.");		stonithd_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb));		main_rc = LSB_EXIT_GENERIC;	}delhb_quit:	if (hb != NULL) {		if (hb->llc_ops->delete(hb) != HA_OK) {			stonithd_log(LOG_ERR, "Cannot delete API object.");			stonithd_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb));			main_rc = LSB_EXIT_GENERIC;		}	}	g_list_free(client_list); /* important. Others! free each item! pls check */	g_hash_table_destroy(executing_queue); /* ? */	if (unlink(PID_FILE) != 0) {                stonithd_log(LOG_ERR, "it failed to remove pidfile %s.", PIDFILE);		main_rc = LSB_EXIT_GENERIC;        }	if (0 == main_rc) {		stonithd_log(LOG_NOTICE, "%s %s", argv[0], M_QUIT );	} else {		stonithd_log(LOG_NOTICE, "%s %s", argv[0], M_ABORT );	}	return (STARTUP_ALONE == TRUE) ? main_rc : MAGIC_EC;}/*  * Notes:  * 1) Not use daemon() API for its portibility, any comment?*/static voidbecome_daemon(gboolean startup_alone){	pid_t pid;	int j;	if (startup_alone == TRUE) {		pid = fork();		if (pid < 0) { /* in parent process and fork failed. */			stonithd_log(LOG_ERR, 				     "become_daemon: forking a child failed.");			stonithd_log(LOG_ERR, 				     "exit due to not becoming a daemon.");			exit(LSB_EXIT_GENERIC);		} else if (pid > 0) {  /* in parent process and fork is ok */			exit(LSB_EXIT_OK);		}	}	chdir("/");	umask(022);	setsid();	for (j=0; j < 3; ++j) {		close(j);		(void)open("/dev/null", j == 0 ? O_RDONLY : O_RDONLY);	}	CL_IGNORE_SIG(SIGINT);	CL_IGNORE_SIG(SIGHUP);	CL_SIGNAL(SIGTERM, stonithd_quit);	CL_SIGNAL(SIGQUIT, stonithd_quit);	CL_SIGNAL(SIGCHLD, child_quit);		if (0 != create_pidfile(PIDFILE)) {		stonithd_log(LOG_ERR, "%s %s", stonithd_name, M_ABORT);		exit((STARTUP_ALONE == TRUE) ? LSB_EXIT_GENERIC : MAGIC_EC);	}}static voidstonithd_quit(int signo){	if (mainloop != NULL && g_main_is_running(mainloop)) {		g_main_quit(mainloop);	} else {		/*apphb_unregister();*/		exit((STARTUP_ALONE == TRUE) ? LSB_EXIT_OK : MAGIC_EC);	}}/* * The following three functions are for GSourceFuncs. This type of * source is for dealing with child signal - exit from child. * This method is used to avoid high cpu usage or reentrance issue. */static gbooleanon_polled_input_prepare(GSource * source, gint * timeout){	return childs_quit;}static gbooleanon_polled_input_check(GSource * source){	return childs_quit;}/* handle the child quit event */static gbooleanon_polled_input_dispatch(GSource * source, GSourceFunc callback, 			 gpointer user_data){	int exit_status;		pid_t pid = 0;	int num_of_quitted_childs = 0;	gboolean rc;	common_op_t * op = NULL;	int * orignal_key = NULL;	stonithd_log(LOG_DEBUG, "on_polled_input_dispatch: begin"); 	while ((pid = wait(&exit_status)) > 0) {		num_of_quitted_childs++;		stonithd_log(LOG_DEBUG, "child %d exit code : %d", 				     pid, WEXITSTATUS(exit_status));		rc = g_hash_table_lookup_extended(executing_queue, &pid, 				(gpointer *)&orignal_key, (gpointer *)&op);		if (rc == FALSE ) { /* || op == NULL)  */			stonithd_log(LOG_ERR, "received child quit signal, "				"but no this child pid in excuting list.");			continue;		}		if ( op == NULL) {			stonithd_log(LOG_ERR, "received child quit signal: "				"but op==NULL");			continue;		}		if ( op->scenario == STONITH_RA_OP ) {			if (op->op_union.ra_op == NULL || op->result_receiver == NULL) {				stonithd_log(LOG_ERR, 					"on_polled_input_dispatch: "					"op->op_union.ra_op == NULL or "					"op->result_receiver == NULL");				continue;			}			op->op_union.ra_op->call_id = pid;			op->op_union.ra_op->op_result = exit_status;			send_stonithRAop_final_result(op->op_union.ra_op, 						      op->result_receiver);			post_handle_raop(op->op_union.ra_op);			g_hash_table_remove(executing_queue, &pid);			continue;		}		/* next is stonith operation related */		if ( op->scenario == STONITH_INIT || 		     op->scenario == STONITH_REQ ) {			if (op->op_union.st_op == NULL || op->result_receiver == NULL ) {				stonithd_log(LOG_ERR, 					"on_polled_input_dispatch: "					"op->op_union.st_op == NULL or "					"op->result_receiver == NULL");				continue;			}						if (WEXITSTATUS(exit_status) == S_OK) {				op->op_union.st_op->op_result = STONITH_SUCCEEDED;				send_stonithop_final_result(op); 				g_hash_table_remove(executing_queue, &pid);				continue;			}			/* Go ahead when WEXITSTATUS(exit_status) != S_OK */			if (ST_OK == continue_local_stonithop(pid)) {				continue;			} else {				if (changeto_remote_stonithop(pid) != ST_OK) {					op->op_union.st_op->op_result = STONITH_GENERIC;					send_stonithop_final_result(op);					g_hash_table_remove(executing_queue,							    &pid);				}			}				}	}	/* important, or incorrectly go here repeatly */	childs_quit = FALSE;	if ( num_of_quitted_childs == 0) {		stonithd_log(LOG_ERR, "on_polled_input_dispatch: why no "			     "child to quit.");		/* To handle ? */	}	return TRUE;}static voidchild_quit(int signo){	childs_quit = TRUE;}static intinit_hb_msg_handler(void){	IPC_Channel * hbapi_ipc = NULL;	unsigned int msg_mask;		stonithd_log(LOG_DEBUG, "init_hb_msg_handler: begin");	/* Set message callback */	if (hb->llc_ops->set_msg_callback(hb, T_WHOCANST, 				  handle_msg_twhocan, hb) != HA_OK) {		stonithd_log(LOG_ERR, "Cannot set msg T_WHOCAN callback");		stonithd_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb));		return LSB_EXIT_GENERIC;	}	if (hb->llc_ops->set_msg_callback(hb, T_ICANST, 				  handle_msg_ticanst, hb) != HA_OK) {		stonithd_log(LOG_ERR, "Cannot set msg T_ICANST callback");		stonithd_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb));		return LSB_EXIT_GENERIC;	}	if (hb->llc_ops->set_msg_callback(hb, T_STIT, 				  handle_msg_tstit, hb) != HA_OK) {		stonithd_log(LOG_ERR, "Cannot set msg T_STIT callback");		stonithd_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb));		return LSB_EXIT_GENERIC;	}	if (hb->llc_ops->set_msg_callback(hb, T_RSTIT, 				  handle_msg_trstit, hb) != HA_OK) {		stonithd_log(LOG_ERR, "Cannot set msg t_WHOCAN callback");		stonithd_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb));		return LSB_EXIT_GENERIC;	}	msg_mask = LLC_FILTER_DEFAULT;	cl_log(LOG_DEBUG, "Setting message filter mode");	if (hb->llc_ops->setfmode(hb, msg_mask) != HA_OK) {		stonithd_log(LOG_ERR, "Cannot set filter mode");		stonithd_log(LOG_ERR, "REASON: %s", hb->llc_ops->errmsg(hb));		return LSB_EXIT_GENERIC;	}	if (NULL == (hbapi_ipc = hb->llc_ops->ipcchan(hb))) {		stonithd_log(LOG_ERR,"Cannot get hb's client IPC channel.");		return LSB_EXIT_GENERIC;	}	/* Watch the hearbeat API's IPC channel for input */	G_main_add_IPC_Channel(G_PRIORITY_HIGH, hbapi_ipc, FALSE, 				stonithd_hb_msg_dispatch, (gpointer)hb, 				stonithd_hb_msg_dispatch_destroy);	return 0;}static gbooleanstonithd_hb_msg_dispatch(IPC_Channel * ipcchan, gpointer user_data){	ll_cluster_t *hb = (ll_cluster_t*)user_data;    	while (hb->llc_ops->msgready(hb)) {		/* FIXME:  This should be a higher-level API function (broken API) */		if (hb->llc_ops->ipcchan(hb)->ch_status == IPC_DISCONNECT) {			stonithd_quit(0);		}		/* invoke the callbacks with none-block mode */		stonithd_log(LOG_DEBUG, "there are hb msg received.");		hb->llc_ops->rcvmsg(hb, 0);	}	/* deal with some abnormal errors/bugs? */	return TRUE;}static voidstonithd_hb_msg_dispatch_destroy(gpointer user_data){	return;}static voidhandle_msg_twhocan(const struct ha_msg* msg, void* private_data){	const char * target = NULL;	const char * from = NULL;	int call_id;	stonithd_log(LOG_DEBUG, "I got T_WHOCANST msg.");		if ( (from = cl_get_string(msg, F_ORIG)) == NULL) {		stonithd_log(LOG_ERR, "handle_msg_twhocan: no F_ORIG field.");		return;	}	/* Don't handle the message sent by myself */	if ( strncmp(from, local_nodename, strlen(local_nodename)) 		== 0) {		stonithd_log(LOG_DEBUG, "received a T_WHOCAN msg from myself.");		return;	}	if ( (target = cl_get_string(msg, F_STONITHD_NODE)) == NULL) {		stonithd_log(LOG_ERR, "handle_msg_twhocan: no F_STONITHD_NODE "			     "field.");		return;	}	if (HA_OK != ha_msg_value_int(msg, F_STONITHD_CALLID, &call_id)) {		stonithd_log(LOG_ERR, "handle_msg_twhocan: no F_STONITHD_CALLID "			     "field.");		return;	}	if (get_local_stonithobj_can_stonith(target, NULL) != NULL ) {		struct ha_msg * reply;		if ((reply = ha_msg_new(1)) == NULL) {			stonithd_log(LOG_ERR, "handle_msg_twhocan: "					"out of memory");			return;		}		if ( (ha_msg_add(reply, F_TYPE, T_ICANST) != HA_OK)	    	    ||(ha_msg_add(reply, F_ORIG, local_nodename) != HA_OK)	    	    ||(ha_msg_add_int(reply, F_STONITHD_CALLID, call_id)			!= HA_OK)) {			stonithd_log(LOG_ERR, "handle_msg_twhocan: "					"cannot add field.");			ZAPMSG(reply);			return;		}		if (hb == NULL) {			stonithd_log(LOG_ERR, "handle_msg_twhocan: hb==NULL");			ZAPMSG(reply);			return;		}		if (HA_OK!=hb->llc_ops->sendnodemsg(hb, reply, from)) {			stonithd_log(LOG_ERR, "handle_msg_twhocan: "					"sendnodermsg failed.");			return;		}		ZAPMSG(reply);		stonithd_log(LOG_DEBUG,"handle_msg_twhocan: "				"send reply successfully.");	}}static voidhandle_msg_ticanst(const struct ha_msg* msg, void* private_data){	const char * from = NULL;	int  call_id;	int * orig_key = NULL;	common_op_t * op = NULL;	stonithd_log(LOG_DEBUG, "handle_msg_ticanst: got T_ICANST msg.");	if ( (from = cl_get_string(msg, F_ORIG)) == NULL) {		stonithd_log(LOG_ERR, "handle_msg_ticanst: no F_ORIG field.");		return;	}	/* Don't handle the message sent by myself */	if ( strncmp(from, local_nodename, strlen(local_nodename)) 		== 0) {		stonithd_log(LOG_DEBUG, "received a T_ICANST msg from myself.");		return;	}	if ( HA_OK != ha_msg_value_int(msg, F_STONITHD_CALLID, &call_id) ) { 		stonithd_log(LOG_ERR, "handle_msg_ticanst: no F_STONITHD_CALLID"			     " field.");		return;	}	my_hash_table_find(executing_queue, (gpointer *)&orig_key, 			   (gpointer *)&op, &call_id);	if ( op != NULL &&  /* QUERY only */	    (op->scenario == STONITH_INIT || op->scenario == STONITH_REQ)) {		/* add the separator blank space */		op->op_union.st_op->node_list = 			g_string_append(op->op_union.st_op->node_list, " ");		op->op_union.st_op->node_list = 			g_string_append(op->op_union.st_op->node_list, from);		stonithd_log(LOG_DEBUG, "handle_msg_ticanst: QUERY operation "			"(call_id=%d): added a node's name who can stonith "			"another node.", call_id);	}	/* wait the timeout function to send back the result */}static voidhandle_msg_tstit(const struct ha_msg* msg, void* private_data){	const char * target = NULL;	const char * from = NULL;	int call_id;	int timeout;	int optype;	stonith_rsc_t * srsc = NULL;	stonith_ops_t * st_op = NULL;	stonithd_log(LOG_DEBUG, "handle_msg_tstit: got T_STIT msg.");		if ( (from = cl_get_string(msg, F_ORIG)) == NULL) {		stonithd_log(LOG_ERR, "handle_msg_tstit: no F_ORIG field.");		return;	}	/* Don't handle the message sent by myself */	if ( strncmp(from, local_nodename, strlen(local_nodename)) 		== 0 && TEST == FALSE ) {		stonithd_log(LOG_DEBUG, "received a T_STIT msg from myself, "			     "will abandon it.");		return;	}	if ( (target = cl_get_string(msg, F_STONITHD_NODE)) == NULL) {		stonithd_log(LOG_ERR, "handle_msg_tstit: no F_STONITHD_NODE "			     "field.");		return;	}

⌨️ 快捷键说明

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