[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-ha-dev
Subject:    Re: [Linux-ha-dev] Dynamic Modify the timeout values
From:       "DAIKI MATSUDA" <d.matuda () gmail ! com>
Date:       2007-07-27 1:07:35
Message-ID: de654a0d0707261807u485e659bv483cab78b2657006 () mail ! gmail ! com
[Download RAW message or body]

Thank you for reply, Horms-san and Lars-san.

> > >> Hello, All.
> > >>
> > >> I post patch files again, because I added a new feature to send the
> > >> modified timeout values to other nodes. Its description is at the
> > >> bottom. I could make the nodes that received the message over-write
> > >> the ha.cf file. But I feel that it is meddlesome and I implemented the
> > >> all required features by this patch.
> > >>
> > >> And I attach all patch files because after posting the previous e-mail
> > >> I have fixed some bugs.
> > >>
> > >> 6_send_values_to_cluster.patch:
> > >> This patch is to send modified timeout values to the other nodes with
> > >> the existing communication channel. The node that received a signal
> > >> SIGRTMAX sends a message for the other nodes. They receive message,
> > >> decode it to know the new timeout values and try to reflect them.
> > >>
> > >> Best Regards
> > >> MATSUDA, Daiki
> > >
> > >Hi Matsuda-san,
> > >
> > >sorry for taking so long to reply again. I've taken a look over these
> > >patches, and they seem to be looking quite good. There is still quite a
> > >lot of material, so I am sure that there are some things that I have
> > >missed. bUt here are my comments for now.
> > >
> > >
> > >I think that the patches need to be reordered. I found that with a small
> > >ammount of rediffing of the hb_config.h fragements, the flolowing order
> > >worked:
> > >
> > >1_remember_timeout_to_array.patch
> > >4_apply_modified_value.patch
> > >3_add_parse_function.patch
> > >2_add_signal_handler.patch
> > >5_send_keepalive_to_ccm.patch
> > >6_send_values_to_cluster.patch
> > >6_send_values_to_cluster-fix.patch
> > >
> > >The original order did not work as 2_add_signal_handler.patch requires
> > >light_parse_config(), which is provided by 3_add_parse_function.patch,
> > >and 3_add_parse_function.patch requires modify_keepalive_value() and
> > >modify_deadtime_value() which are provided by 4_apply_modified_value.patch
> >
> > Hi, Horms-san.
> >
> > Thank you for reply and sorry for confusing by similar name patches. I
> > attached the re-made patches with references of your suggestion. They
> > can be applied to heartbeat-2.1.1 and works well.
> >
> > And I answer about important question.
>
> Hi Matsuda-san,
>
> thanks for cleaning up the patches and addressing my questions.
> I only have two problems left.
>
> 1. patch order (very minor)
>
> The patches need to be in the following order.
> You can see why if you try to compile with only patches 1 & 2 or
> only patches 1, 2 & 3 applied. The patches 3 and 4 need minor
> modifications to the hb_config.h hunk in order to apply cleanly
> in the new order.
>
> 1_remember_timeout_to_array_20070725.patch
> 4_apply_modified_value_20070725.patch
> 3_add_parse_function_20070725.patch
> 2_add_signal_handler_20070725.patch
> 5_send_keepalive_to_ccm_20070725.patch
> 6_send_values_to_cluster_20070725.patch

I re-made patches again and combined 3_add. with 4_apply... In
addition, I fixed them to be built one by one. So, you will apply them
from 1_... to 6_... and can build step by step.

> 2. bash vs sh
>
> Its been the policy of linux-ha for a long time to use sh instead of
> bash. I know that there are sometimes good reasons to use bash, but so
> far the project has been successful in only using sh.
>
> There really are systems out there running linux-ha that don't have
> bash. For instance, some Debian systems have dash installed not bash.
>
> It is true that bash's kill allows SIGRTMAX while /bin/kill does
> not. But I think we should look for another solution. Here
> are some ideas that I have.
>
> 1. Use pkill. Is this on all platforms that linux-ha supports?
>
> 2. Choose another signal. But I don't think there are any good candidates.
>
> 3. Write a simple ha_kill command in C. This should be easy enough.
>
> 4. Signal the running process in a different way. Perhaps through the
>    API. But this is probably very heavy.
>
> I think that I like 1 and 3 the best. But perhaps there are better ideas.

As Lars-san pointed, I did not modify. If they are imported, SIGRTMAX
should be changed to other signal and then kill command on not bash
works well.

Best Regards
MATSUDA, Daiki

["1_remember_timeout_to_array_20070727.patch" (text/x-patch)]

diff -uNrp heartbeat-2.1.1.orig/heartbeat/hb_api.c heartbeat-2.1.1/heartbeat/hb_api.c
--- heartbeat-2.1.1.orig/heartbeat/hb_api.c	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/hb_api.c	2007-07-27 08:36:46.000000000 +0900
@@ -1290,6 +1290,15 @@ process_registerevent(IPC_Channel* chan,
 	,	client, G_remove_client);
 	G_main_setdescription((GSource*)client->gsource, "API client");
 	G_main_setmaxdispatchdelay((GSource*)client->gsource, config->heartbeat_ms);
+
+	if (maxdispatchdelay_array_add((void*)(client->gsource), KEEPALIVE_TYPE
+	,	cl_strdup("* 1")) != HA_OK) {
+                cl_log(LOG_ERR, "%s: maxdispatchdelay_array_add can not "
+			"allocate memory", __FUNCTION__);
+		return;
+        }
+
+
 	G_main_setmaxdispatchtime((GSource*)client->gsource, 100);
 	if (ANYDEBUG) {
 		cl_log(LOG_DEBUG
diff -uNrp heartbeat-2.1.1.orig/heartbeat/hb_config.h heartbeat-2.1.1/heartbeat/hb_config.h
--- heartbeat-2.1.1.orig/heartbeat/hb_config.h	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/hb_config.h	2007-07-27 08:36:46.000000000 +0900
@@ -30,5 +30,55 @@ int   		parse_authfile(void);
 int		init_config(const char * cfgfile);
 int		StringToBaud(const char * baudstr);
 const char *	GetParameterValue(const char * name);
+/* maxdispatchdelay_array_add() records calls to G_main_setmaxdispatchdelay()
+ * so that is can be called once again if the base timeout is updated.
+ *
+ * Calls to G_main_setmaxdispatchdelay() are of the form
+ * G_main_setmaxdispatchdelay((GSource*)addr, config->deadtime_ms / value);
+ * or
+ * G_main_setmaxdispatchdelay((GSource*)addr, config->deadtime_ms * value);
+ *
+ * addr:
+ *   GSource addr ass passed as the first argument of
+ *   G_main_setmaxdispatchdelay()
+ *
+ * type:
+ *   The type argument to maxdispatchdelay_array_add() denotes which
+ *   element of config is being used as the base value for the timeout
+ *
+ *   KEEPALIVE_TYPE: config->heartbeat_ms
+ *   DEADTIME_TYPE:  config->deadtime_ms
+ *   WARNTIME_TYPE:  config->warntime_ms
+ *   DEADPING_TYPE:  config->deadping_ms
+ *
+ * mode:
+ *   The mode specifies the operation that should occur on the
+ *   base timeout value
+ *
+ *   '*': multiplication
+ *   '/': division
+ *
+ * calc:
+ *   modification to be made to the base timeout before passing it
+ *   to G_main_setmaxdispatchdelay()
+ *   - whitespace must be present between numbers and operands
+ *   - only  +, -, * and / are permitted as operands
+ *   e.g. "/ 2 + 10"
+ */
+int		maxdispatchdelay_array_add(void *addr, int type, char * calc);
+
+/* maxdispatchdelay_array_add records calls to G_main_setall_id() so
+ * that they can be called once again if the base timeout is changed
+ *
+ * id:
+ *   id as passed as the first argument of G_main_setall_id()
+ *
+ * type:
+ *   as described in the description of G_main_setmaxdispatchdelay
+ *
+ * calc:
+ *   as described in the description of G_main_setmaxdispatchdelay
+ */
+int		setall_array_add(long id, int type, char * calc);
 
 #endif /* _HB_CONFIG_H */
diff -uNrp heartbeat-2.1.1.orig/heartbeat/hb_rexmit.c heartbeat-2.1.1/heartbeat/hb_rexmit.c
--- heartbeat-2.1.1.orig/heartbeat/hb_rexmit.c	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/hb_rexmit.c	2007-07-27 08:36:46.000000000 +0900
@@ -35,6 +35,9 @@
 #include <clplumbing/GSource.h>
 #include <clplumbing/cl_random.h>
 
+#include <hb_config.h>
+
+extern GPtrArray *setall_array;
 
 static void	schedule_rexmit_request(struct node_info* node, seqno_t seq, int delay);
 
@@ -236,6 +239,11 @@ schedule_rexmit_request(struct node_info
 	sourceid = Gmain_timeout_add_full(G_PRIORITY_HIGH - 1, delay, 
 					  send_rexmit_request, ri, NULL);
 	G_main_setall_id(sourceid, "retransmit request", config->heartbeat_ms/2, 10);
+
+	if (setall_array_add(sourceid, KEEPALIVE_TYPE, cl_strdup("/ 2")) != HA_OK) {
+		cl_log(LOG_ERR, "%s: setall_array_add can not allocate memory "
+			"(id %ld)", __FUNCTION__, sourceid);
+	}
 	
 	if (sourceid == 0){
 		cl_log(LOG_ERR, "%s: scheduling a timeout event failed", 
diff -uNrp heartbeat-2.1.1.orig/heartbeat/heartbeat.c heartbeat-2.1.1/heartbeat/heartbeat.c
--- heartbeat-2.1.1.orig/heartbeat/heartbeat.c	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/heartbeat.c	2007-07-27 08:36:46.000000000 +0900
@@ -338,6 +338,9 @@ GTRIGSource*			write_hostcachefile = NUL
 GTRIGSource*			write_delcachefile = NULL;
 extern GSList*			del_node_list;
 
+GPtrArray *maxdispatchdelay_array;
+GPtrArray *setall_array;
+GArray * timeout_add_full_array;
 
 #undef DO_AUDITXMITHIST
 #ifdef DO_AUDITXMITHIST
@@ -486,6 +489,40 @@ static GSourceFuncs		polled_input_Source
 	NULL,
 };
 
+int
+maxdispatchdelay_array_add(void * addr, int type, char * calc)
+{
+	struct MaxDispatchDelay_Array*	carray;
+
+	carray = (struct MaxDispatchDelay_Array*)
+		cl_malloc(sizeof(struct MaxDispatchDelay_Array));
+	if (carray == NULL || calc == NULL) return HA_FAIL;
+
+	carray->addr = addr;
+	carray->calc = calc;
+
+	g_ptr_array_add(maxdispatchdelay_array, (gpointer)carray);
+
+	return HA_OK;
+}
+
+int
+setall_array_add(long id, int type, char * calc)
+{
+	struct SetAll_Array*	sarray;
+
+	sarray = (struct SetAll_Array*)
+		cl_malloc(sizeof(struct SetAll_Array));
+	if (sarray == NULL || calc == NULL) return HA_FAIL;
+
+	sarray->id = id;
+	sarray->type = type;
+	sarray->calc = calc;
+	g_ptr_array_add(setall_array, (gpointer)sarray);
+
+	return HA_OK;
+}
+
 static void
 init_procinfo()
 {
@@ -703,6 +740,13 @@ SetupFifoChild(void) {
 	G_main_setmaxdispatchdelay((GSource*)FifoChildSource, config->heartbeat_ms);
 	G_main_setmaxdispatchtime((GSource*)FifoChildSource, 50);
 	G_main_setdescription((GSource*)FifoChildSource, "FIFO");
+
+	if (maxdispatchdelay_array_add((void*)FifoChildSource, KEEPALIVE_TYPE
+	,	cl_strdup("* 1")) != HA_OK) {
+		cl_log(LOG_ERR, "%s: maxdispatchdelay_array_add can not "
+			"allocate memory", __FUNCTION__);
+		return HA_FAIL;
+	}
 	
 	return HA_OK;
 }
@@ -1415,6 +1459,12 @@ master_control_process(void)
 		G_main_setmaxdispatchtime((GSource*)s, 50);
 		G_main_setdescription((GSource*)s, "write child");
 
+		if (maxdispatchdelay_array_add((void*)s, KEEPALIVE_TYPE
+		,	cl_strdup("/ 4")) != HA_OK) {
+			cl_log(LOG_ERR, "%s 0: maxdispatchdelay_array_add can not"
+				" allocate memory", __FUNCTION__);
+			return;
+		}
 		
 		/* Connect up the read child IPC channel... */
 		s = G_main_add_IPC_Channel(PRI_READPKT
@@ -1427,8 +1477,13 @@ master_control_process(void)
 		G_main_setmaxdispatchtime((GSource*)s, 50);
 		G_main_setdescription((GSource*)s, "read child");
 
-}	
-	
+		if (maxdispatchdelay_array_add((void*)s, KEEPALIVE_TYPE
+		,	cl_strdup("/ 4")) != HA_OK) {
+			cl_log(LOG_ERR, "%s 1: maxdispatchdelay_array_add can not"
+				" allocate memory", __FUNCTION__);
+			return;
+		}
+	}	
 
 	/*
 	 * Things to do on a periodic basis...
@@ -1439,6 +1494,13 @@ master_control_process(void)
 	,	hb_send_local_status, NULL, NULL);
 	G_main_setall_id(id, "send local status", 10+config->heartbeat_ms/2, 50);
 
+	g_array_append_val(timeout_add_full_array, id);
+	if (setall_array_add(id, KEEPALIVE_TYPE, cl_strdup("/ 2 + 10")) != HA_OK) {
+		cl_log(LOG_ERR, "%s: setall_array_add can not allocate memory "
+			"(id %d)", __FUNCTION__, id);
+			return;
+	}
+
 	id=Gmain_timeout_add_full(PRI_AUDITCLIENT
 	,	config->initial_deadtime_ms
 	,	set_init_deadtime_passed_flag
@@ -1446,6 +1508,12 @@ master_control_process(void)
 	,	NULL);
 	G_main_setall_id(id, "init deadtime passed", config->warntime_ms, 50);
 
+	if (setall_array_add(id, WARNTIME_TYPE, cl_strdup("")) != HA_OK) {
+		cl_log(LOG_ERR, "%s: setall_array_add can not allocate memory "
+			"(id %d)", __FUNCTION__, id);
+			return;
+	}
+
 	/* Dump out memory stats periodically... */
 	memstatsinterval = (debug_level ? 10*60*1000 : ONEDAY*1000);
 	id=Gmain_timeout_add_full(PRI_DUMPSTATS, memstatsinterval
@@ -1469,10 +1537,23 @@ master_control_process(void)
 	,       Gmain_hb_signal_process_pending, NULL, NULL);
 	G_main_setall_id(id, "check for signals", 10+config->heartbeat_ms/2, 50);
 	
+	g_array_append_val(timeout_add_full_array, id);
+	if (setall_array_add(id, KEEPALIVE_TYPE, cl_strdup("/ 2 + 10")) != HA_OK) {
+		cl_log(LOG_ERR, "%s: setall_array_add can not allocate memory "
+			"(id %d)", __FUNCTION__, id);
+		return;
+	}
+
 	id=Gmain_timeout_add_full(PRI_FREEMSG, 500
 	,	Gmain_update_msgfree_count, NULL, NULL);
 	G_main_setall_id(id, "update msgfree count", config->deadtime_ms, 50);
 	
+	if (setall_array_add(id, DEADTIME_TYPE, cl_strdup("")) != HA_OK) {
+		cl_log(LOG_ERR, "%s: setall_array_add can not allocate memory "
+			"(id %d)", __FUNCTION__, id);
+		return;
+	}
+
 	if (UseApphbd) {
 		Gmain_timeout_add_full(PRI_DUMPSTATS
 		,	60*(1000-10) /* Not quite on a minute boundary */
@@ -1771,6 +1852,12 @@ comm_now_up()
 	G_main_setmaxdispatchtime((GSource*)regsource, 20);
 	G_main_setdescription((GSource*)regsource, "client registration");
 	
+	if( maxdispatchdelay_array_add((void*)regsource, DEADTIME_TYPE
+	,	cl_strdup("* 1")) != HA_OK) {
+		cl_log(LOG_ERR, "%s: maxdispatchdelay_array_add can not"
+			" allocate memory", __FUNCTION__);
+		return;
+	}
 
 	if (regsource == NULL) {
 		cl_log(LOG_DEBUG
@@ -1861,6 +1948,8 @@ hb_kill_core_children(int nsig)
 void
 hb_initiate_shutdown(int quickshutdown)
 {
+	int i;
+
 	if (ANYDEBUG) {
 		cl_log(LOG_DEBUG, "hb_initiate_shutdown() called.");
 	}
@@ -1883,6 +1972,24 @@ hb_initiate_shutdown(int quickshutdown)
 		,	"Shutdown delayed until Communication is up.");
 		return;
 	}
+
+	for (i=maxdispatchdelay_array->len-1; i >= 0 ; --i) {
+		struct MaxDispatchDelay_Array* carray
+		= g_ptr_array_index(maxdispatchdelay_array, i);
+		if (carray != NULL) {
+			g_ptr_array_remove_index(maxdispatchdelay_array, i);
+			cl_free(carray);
+		}
+	}
+	g_ptr_array_free(maxdispatchdelay_array, TRUE);
+
+	for (i=0; i < setall_array->len; ++i) {
+		struct SetAll_Array* sarray = g_ptr_array_index(setall_array, i);
+		if (sarray != NULL) cl_free(sarray->calc);
+	}
+	g_ptr_array_free(setall_array, TRUE);
+	g_array_free(timeout_add_full_array, TRUE);
+
 	send_local_status();
 	if (!quickshutdown && DoManageResources) {
 		/* THIS IS RESOURCE WORK!  FIXME */
@@ -4122,6 +4229,13 @@ send_reqnodes_msg(gpointer data){
 	
 	id = Gmain_timeout_add(1000, send_reqnodes_msg, (gpointer)i);
 	G_main_setall_id(id, "send_reqnodes_msg", config->heartbeat_ms, 100);
+
+	if( setall_array_add(id, KEEPALIVE_TYPE, cl_strdup("")) != HA_OK) {
+		cl_log(LOG_ERR, "%s: setall_array_add can not allocate memory "
+			"(id %d)", __FUNCTION__, id);
+		return HA_FAIL;
+	}
+
 	return FALSE;
 }
 
@@ -4746,6 +4860,9 @@ main(int argc, char * argv[], char **env
 	/*init table for nodename/uuid lookup*/
 	inittable();
 
+	maxdispatchdelay_array = g_ptr_array_new();
+	setall_array = g_ptr_array_new();
+	timeout_add_full_array = g_array_new(FALSE, FALSE, sizeof(guint));
 
 	/*
 	 *	We think we just performed an "exec" of ourselves to restart.
diff -uNrp heartbeat-2.1.1.orig/include/heartbeat.h heartbeat-2.1.1/include/heartbeat.h
--- heartbeat-2.1.1.orig/include/heartbeat.h	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/include/heartbeat.h	2007-07-27 08:36:46.000000000 +0900
@@ -334,6 +334,24 @@ struct client_child {
 	char*		path;		/* Path (argv[0])? */
 };
 
+#define TMOUTNUMS		4
+#define KEEPALIVE_TYPE		0
+#define DEADTIME_TYPE		1
+#define WARNTIME_TYPE		2
+#define DEADPING_TYPE		3
+
+struct MaxDispatchDelay_Array {
+	void *		addr;
+	int		type;
+	char *		calc;
+};
+
+struct SetAll_Array {
+	unsigned long	id;
+	int		type;
+	char *		calc;
+};
+
 int api_remove_client_pid(pid_t c_pid, const char * reason);
 
 

["2_add_signal_handler_20070727.patch" (text/x-patch)]

diff -uNrp heartbeat-2.1.1.orig/heartbeat/hb_signal.c \
                heartbeat-2.1.1/heartbeat/hb_signal.c
--- heartbeat-2.1.1.orig/heartbeat/hb_signal.c	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/hb_signal.c	2007-07-27 08:38:31.000000000 +0900
@@ -59,6 +59,7 @@ static volatile unsigned int __hb_signal
 #define HB_SIG_PARENT_DEBUG_USR2_SIG           0x0020UL
 #define HB_SIG_REREAD_CONFIG_SIG               0x0040UL
 #define HB_SIG_FALSE_ALARM_SIG                 0x0080UL
+#define HB_SIG_LIGHT_REREAD_CONFIG_SIG         0x0100UL
 
 
 /*
@@ -353,6 +354,17 @@ hb_signal_reread_config_action(void)
 	}
 }
 
+void
+hb_signal_light_reread_config_handler(int sig)
+{
+	__hb_signal_pending |= HB_SIG_LIGHT_REREAD_CONFIG_SIG;
+}
+
+void
+hb_signal_light_reread_config_action(void)
+{
+	return;
+}
 
 void
 hb_signal_false_alarm_handler(int sig)
@@ -443,6 +455,10 @@ hb_signal_process_pending(void)
 			hb_signal_reread_config_action();
 		}
 
+		if (handlers&HB_SIG_LIGHT_REREAD_CONFIG_SIG) {
+			hb_signal_light_reread_config_action();
+		}
+
 		if (handlers&HB_SIG_FALSE_ALARM_SIG) {
 			hb_signal_false_alarm_action();
 		}
@@ -477,6 +493,7 @@ hb_signal_set_common(sigset_t *set)
 	,	{SIGALRM,	hb_signal_false_alarm_handler,	1}
 	,	{SIGUSR1,	hb_signal_debug_usr1_handler,	1}
 	,	{SIGUSR2,	hb_signal_debug_usr2_handler,	1}
+	,	{SIGRTMAX,	hb_signal_light_reread_config_handler,	1}
 	,	{0,		0,				0}
 	};
 
@@ -633,6 +650,7 @@ hb_signal_set_master_control_process(sig
 	{	{SIGTERM,	hb_signal_term_handler,	1}
 	,	{SIGUSR1,	parent_hb_signal_debug_usr1_handler,	1}
 	,	{SIGUSR2,	parent_hb_signal_debug_usr2_handler,	1}
+	,	{SIGRTMAX,	hb_signal_light_reread_config_handler,	1}
 	,	{SIGALRM,       hb_signal_false_alarm_handler,        	1}
 	,	{0,		0,					0}
 	};
diff -uNrp heartbeat-2.1.1.orig/heartbeat/hb_signal.h \
                heartbeat-2.1.1/heartbeat/hb_signal.h
--- heartbeat-2.1.1.orig/heartbeat/hb_signal.h	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/hb_signal.h	2007-07-27 08:37:49.000000000 +0900
@@ -56,6 +56,10 @@ void hb_signal_reread_config_handler(int
 
 void hb_signal_reread_config_action(void);
 
+void hb_signal_light_reread_config_handler(int sig);
+
+void hb_signal_light_reread_config_action(void);
+
 void hb_signal_false_alarm_handler(int sig);
 
 void hb_signal_false_alarm_action(void);
diff -uNrp heartbeat-2.1.1.orig/heartbeat/init.d/heartbeat.in \
                heartbeat-2.1.1/heartbeat/init.d/heartbeat.in
--- heartbeat-2.1.1.orig/heartbeat/init.d/heartbeat.in	2007-07-24 11:25:17.000000000 \
                +0900
+++ heartbeat-2.1.1/heartbeat/init.d/heartbeat.in	2007-07-27 08:37:49.000000000 +0900
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/bin/bash
 #
 #
 # heartbeat     Start high-availability services
@@ -401,6 +401,22 @@ ReloadHA() {
   fi
 }
 
+#
+#	heartbeat light reload for timeout values.
+#       It will *not stop* its resources
+#
+LightReloadHA() {
+  EchoNoNl "Light Reloading High-Availability services: "
+
+  if
+    [  ! -f /var/run/heartbeat.pid ]
+  then
+    EchoNoNl "Heartbeat Service not running"
+  else
+    kill -s SIGRTMAX `/bin/cat /var/run/heartbeat.pid`
+  fi
+}
+
 RunStartStop() {
   # Run pre-startup script if it exists
   if
@@ -470,8 +486,13 @@ case "$1" in
 	RC=$?
 	;;
 
+  light-reload|lreload)
+	LightReloadHA
+	Echo
+	;;
+
   *)
-	Echo "Usage: $0 {start|stop|status|restart|reload|force-reload}"
+	Echo "Usage: $0 {start|stop|status|restart|reload|force-reload|light-reload|lreload}"
  exit 1
 esac
 


["4_apply_modified_value_20070727.patch" (text/x-patch)]

diff -uNrp heartbeat-2.1.1.orig/heartbeat/config.c heartbeat-2.1.1/heartbeat/config.c
--- heartbeat-2.1.1.orig/heartbeat/config.c	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/config.c	2007-07-27 09:26:18.000000000 +0900
@@ -48,6 +48,7 @@
 #include <heartbeat_private.h>
 #include <ha_msg.h>
 #include <pils/plugin.h>
+#include <clplumbing/GSource_internal.h>
 #include <clplumbing/realtime.h>
 #include <clplumbing/netstring.h>
 #include <clplumbing/coredumps.h>
@@ -112,6 +113,11 @@ static int set_quorum_server(const char 
   static int set_normalpoll(const char *);
 #endif
 
+long get_timeout_value_from_type(int);
+int calc_timeout_value(long *, char *);
+void modify_setmaxdispatchdelay_value(int);
+void modify_setall_id_value(int);
+void modify_channel_value(int);
 
 void hb_set_max_rexmit_delay(int);
 /*
@@ -208,10 +214,12 @@ extern int    				debug_level;
 int					netstring_format = FALSE;
 extern int				UseApphbd;
 GSList*					del_node_list;
+extern int				watchdog_timeout_ms;
 
 
 static int	islegaldirective(const char *directive);
-static int	parse_config(const char * cfgfile, char *nodename);
+static int	parse_config(const char * cfgfile, char *nodename
+		,	struct new_timeout_vals *new_val);
 static long	get_msec(const char * input);
 static int	add_option(const char *	option, const char * value);
 
@@ -225,6 +233,9 @@ struct hb_media_fns**	hbmedia_types;
 	void setenv(const char *name, const char * value, int);
 #endif
 
+extern GPtrArray*			maxdispatchdelay_array;
+extern GPtrArray*			setall_array;
+extern GArray*				timeout_add_full_array;
 
 static void
 check_logd_usage(int* errcount)
@@ -331,7 +342,7 @@ init_config(const char * cfgfile)
 	
 	curnode = NULL;
 
-	if (!parse_config(cfgfile, localnodename)) {
+	if (!parse_config(cfgfile, localnodename, NULL)) {
 		err = errno;
 		ha_log(LOG_ERR, "Heartbeat not started: configuration error.");
 		errno=err;
@@ -582,7 +593,8 @@ init_node_link_info(struct node_info *  
  *	Parse the configuration file and stash away the data
  */
 static int
-parse_config(const char * cfgfile, char *nodename)
+parse_config(const char * cfgfile, char *nodename
+,	struct new_timeout_vals* new_val)
 {
 	FILE	*	f;
 	char		buf[MAXLINE];
@@ -592,6 +604,7 @@ parse_config(const char * cfgfile, char 
 	char		option[MAXLINE];
 	size_t		optionlength;
 	int		errcount = 0;
+	int		light_mode = 0;
 	int		j;
 	int		i;
 	struct stat	sbuf;
@@ -606,6 +619,8 @@ parse_config(const char * cfgfile, char 
 	,	{"anon",	"gid=" HA_APIGROUP}
 	};
 
+	if (nodename == NULL) light_mode = 1;
+
 	if ((f = fopen(cfgfile, "r")) == NULL) {
 		ha_log(LOG_ERR, "Cannot open config file [%s]", cfgfile);
 		ha_log(LOG_INFO
@@ -619,10 +634,17 @@ parse_config(const char * cfgfile, char 
 
 		return(HA_FAIL);
 	}
-	APIAuthorization = g_hash_table_new(g_str_hash, g_str_equal);
+	if (light_mode == 0)
+		APIAuthorization = g_hash_table_new(g_str_hash, g_str_equal);
 
 	fstat(fileno(f), &sbuf);
-	config->cfg_time = sbuf.st_mtime;
+	if ( light_mode == 0 ) {
+		config->cfg_time = sbuf.st_mtime;
+	}else if (config->cfg_time == sbuf.st_mtime) {
+		ha_log(LOG_ERR, "The timestamp of %s is not changed!"
+		,	cfgfile);
+		return 1;
+        }
 
 	/* It's ugly, but effective  */
 
@@ -654,6 +676,8 @@ parse_config(const char * cfgfile, char 
 		dirlength = strcspn(bp, WHITESPACE);
 		strncpy(directive, bp, dirlength);
 		directive[dirlength] = EOS;
+
+		if (light_mode == 1) goto skip1;
 #ifdef DIRTYALIASKLUDGE
 		if (strcmp(directive, "udp") == 0) {
 			ha_log(LOG_WARNING
@@ -668,11 +692,14 @@ parse_config(const char * cfgfile, char 
 			continue;
 		}
 
+skip1:
 		bp += dirlength;
 
 		/* Skip over Delimiters */
 		bp += strspn(bp, DELIMS);
 
+		if (light_mode == 1) goto skip2;
+
 		/* Load the medium plugin if its not already loaded... */
 		if ((funs=g_hash_table_lookup(CommFunctions, directive))
 		==	NULL) {
@@ -735,14 +762,33 @@ parse_config(const char * cfgfile, char 
 				*bp = EOS;
 			}
 		}
+
+skip2:
 		/* Now Check for  the options-list stuff */
 		while (IsOptionDirective && *bp != EOS) {
 			optionlength = strcspn(bp, DELIMS);
 			strncpy(option, bp, optionlength);
 			option[optionlength] = EOS;
 			bp += optionlength;
-			if (add_option(directive, option) != HA_OK) {
-				errcount++;
+
+			if (light_mode == 0) {
+				if (add_option(directive, option) != HA_OK) {
+					errcount++;
+				}
+			}else{
+				if (strcmp(directive, KEY_KEEPALIVE) == 0) {
+                                	new_val[KEEPALIVE_TYPE].timeout = get_msec(option);
+                                	new_val[KEEPALIVE_TYPE].string = cl_strdup(option);
+                        	}else if (strcmp(directive, KEY_DEADTIME) == 0) {
+                                	new_val[DEADTIME_TYPE].timeout = get_msec(option);
+                                	new_val[DEADTIME_TYPE].string = cl_strdup(option);
+                        	}else if (strcmp(directive, KEY_WARNTIME) == 0) {
+                                	new_val[WARNTIME_TYPE].timeout = get_msec(option);
+                                	new_val[WARNTIME_TYPE].string = cl_strdup(option);
+                        	}else if (strcmp(directive, KEY_DEADPING) == 0) {
+                                	new_val[DEADPING_TYPE].timeout = get_msec(option);
+                                	new_val[DEADPING_TYPE].string = cl_strdup(option);
+                        	}
 			}
 
 			/* Skip over Delimiters */
@@ -750,6 +796,11 @@ parse_config(const char * cfgfile, char 
 		}
 	}
 
+	if (light_mode == 1) {
+		fclose(f);
+		return 0;
+	}
+
 	/* Provide default authorization information for well-known services */
 	for (i=0; i < DIMOF(defserv); ++i) {
 		char	buf[100];
@@ -777,6 +828,374 @@ parse_config(const char * cfgfile, char 
 	return(errcount ? HA_FAIL : HA_OK);
 }
 
+long
+get_timeout_value_from_type(int timeout_type)
+{
+	long value;
+
+	switch (timeout_type) {
+		case KEEPALIVE_TYPE:
+			value = config->heartbeat_ms;
+			break;
+		case DEADTIME_TYPE:
+			value = config->deadtime_ms;
+			break;
+		case WARNTIME_TYPE:
+			value = config->warntime_ms;
+			break;
+		case DEADPING_TYPE:
+			value = config->deadping_ms;
+			break;
+		default:
+			value = -1;
+	}
+	return value;
+}
+
+int
+calc_timeout_value(long * value, char * ptr1)
+{
+	char *ptr2;
+	long val = *value;
+
+	for (;;) {
+		char buf[2];
+		int num;
+
+		ptr2 = strchr (ptr1, ' ');
+		if (ptr2 != NULL) ptr2 = strchr(++ptr2, ' ');
+
+		if (ptr2 != NULL) {
+			*ptr2 = '\0';
+		}
+		if (sscanf(ptr1, "%s %d", buf, &num) != 2) {
+			cl_log(LOG_ERR, "%s: calc strings is not correct."
+			,	__FUNCTION__);
+			return HA_FAIL;
+		}
+		switch (buf[0]) {
+			case '+':
+				val += num;
+				break;	
+			case '-':
+				val -= num;
+				break;	
+			case '*':
+				val *= num;
+				break;	
+			case '/':
+				val /= num;
+				break;	
+			default:
+				break;
+		}
+		if (ptr2 == NULL) {
+			break;
+		}else{
+			*ptr2 = ' ';
+			ptr1 = ptr2 + 1;
+		}
+	}
+	*value = val;
+	return HA_OK;
+}
+
+/* care for G_main_setmaxdispatchdelay() function */
+void
+modify_setmaxdispatchdelay_value(int timeout_type)
+{
+	int i;
+	long value;
+
+	if ((value = get_timeout_value_from_type(timeout_type)) < 0) return;
+
+	for (i=0; i < maxdispatchdelay_array->len; ++i) {
+		struct MaxDispatchDelay_Array *carray
+		= g_ptr_array_index(maxdispatchdelay_array, i);
+
+		if (carray->type == timeout_type) {
+			if (carray->calc[0] != '\0') {
+				if (calc_timeout_value(&value, carray->calc))
+					return;
+			}
+			G_main_setmaxdispatchdelay((GSource*)(carray->addr)
+			,	value);
+		}
+	}
+}
+
+/* care for Gmain_setall_id() function */
+void
+modify_setall_id_value(int timeout_type)
+{
+	int i;
+	long value;
+
+	if ((value = get_timeout_value_from_type(timeout_type)) < 0) return;
+
+	for (i=0; i < setall_array->len; ++i) {
+		struct SetAll_Array *sarray
+		= g_ptr_array_index(setall_array, i);
+
+		if (sarray->type == timeout_type) {
+			if (sarray->calc[0] != '\0') {
+				if (calc_timeout_value(&value, sarray->calc))
+					return;
+			}
+			G_main_setmaxdispatchdelay_id(sarray->id, value);
+		}
+	}
+}
+
+void
+apply_new_timeout_value(long mode, struct new_timeout_vals *new_val)
+{
+	int		i;
+	long		new_keepalive_ms;
+	long		new_deadtime_ms;
+	long		new_warntime_ms;
+	long		new_deadping_ms;
+	char *		new_keepalive_string = NULL;
+	char *		new_deadtime_string = NULL;
+	char *		new_warntime_string = NULL;
+	char *		new_deadping_string = NULL;
+
+	new_keepalive_ms = new_val[KEEPALIVE_TYPE].timeout;
+	new_keepalive_string = new_val[KEEPALIVE_TYPE].string;
+	new_deadtime_ms = new_val[DEADTIME_TYPE].timeout;
+	new_deadtime_string = new_val[DEADTIME_TYPE].string;
+	new_warntime_ms = new_val[WARNTIME_TYPE].timeout;
+	new_warntime_string = new_val[WARNTIME_TYPE].string;
+	new_deadping_ms = new_val[DEADPING_TYPE].timeout;
+	new_deadping_string = new_val[DEADPING_TYPE].string;
+
+	/*
+	 * Maybe following is safe
+	*/
+	if (mode&(OW_KEEPALIVE|OW_DEADTIME)) {
+		if (new_keepalive_ms > config->deadtime_ms) {
+			modify_deadtime_value(new_deadtime_ms
+			,	new_deadtime_string);
+			modify_keepalive_value(new_keepalive_ms
+			,	new_keepalive_string);
+		}else{
+			modify_keepalive_value(new_keepalive_ms
+			,	new_keepalive_string);
+			modify_deadtime_value(new_deadtime_ms
+			,	new_deadtime_string);
+		}
+	}else{
+		if (mode&OW_KEEPALIVE) {
+			modify_keepalive_value(new_keepalive_ms
+			,	new_keepalive_string);
+		}
+
+		if (mode&OW_DEADTIME){
+			modify_deadtime_value(new_deadtime_ms
+			,	new_deadtime_string);
+		}
+	}
+
+	if (mode&OW_WARNTIME) {
+		cl_log(LOG_INFO, "%s: warntime %ld time is over-written "
+		"to new value %ld.\n", __FUNCTION__
+		,	config->warntime_ms, new_warntime_ms);
+		SetParameterValue(KEY_WARNTIME, new_warntime_string);
+		config->warntime_ms = new_warntime_ms;
+		modify_channel_value(WARNTIME_TYPE);
+	}
+
+	if (mode&OW_DEADPING) {
+		cl_log(LOG_INFO, "%s: deadping %ld time is over-written "
+		"to new value %ld.\n", __FUNCTION__
+		,	config->deadping_ms, new_deadping_ms);
+		SetParameterValue(KEY_DEADPING, new_deadping_string);
+		config->deadping_ms = new_deadping_ms;
+
+		for (i=0; i < config->nodecount; ++i) {
+			if (config->nodes[i].nodetype == PINGNODE_I) {
+				config->nodes[i].dead_ticks
+				=	msto_longclock(new_deadping_ms);
+			}
+		}
+		hb_send_local_status(NULL);
+		modify_channel_value(DEADPING_TYPE);
+	}
+
+	return;
+}
+
+void
+modify_channel_value(int timeout_type)
+{
+	modify_setmaxdispatchdelay_value(timeout_type);
+	modify_setall_id_value(timeout_type);
+}
+
+void
+new_timeout_vals_free(struct new_timeout_vals *new_val)
+{
+	int		i;
+
+	if (new_val == NULL) return;
+	for (i=0; i < TMOUTNUMS; ++i)
+		if (new_val[i].string != NULL) cl_free(new_val[i].string);
+	cl_free(new_val);
+	return;
+}
+
+int
+light_parse_config(const char * cfgfile)
+{
+	int		i;
+	unsigned long	mode = 0x0UL;
+	long		new_keepalive_ms;
+	long		new_deadtime_ms;
+	long		new_warntime_ms;
+	long		new_deadping_ms;
+	char *		new_keepalive_string = NULL;
+	char *		new_deadtime_string = NULL;
+	char *		new_warntime_string = NULL;
+	char *		new_deadping_string = NULL;
+	struct new_timeout_vals *new_val;
+
+	new_val = (struct new_timeout_vals *)
+		cl_malloc(sizeof(struct new_timeout_vals)*TMOUTNUMS);
+	if (new_val == NULL) {
+		cl_log(LOG_ERR, "%s: can not allocate memory.", __FUNCTION__);
+		return HA_FAIL;
+	}
+	new_val[KEEPALIVE_TYPE].timeout = 0;
+	new_val[DEADTIME_TYPE].timeout = 0;
+	new_val[WARNTIME_TYPE].timeout = 0;
+	new_val[DEADPING_TYPE].timeout = -1;
+	for (i=0; i < TMOUTNUMS; ++i) new_val[i].string = NULL;
+
+	if (parse_config(cfgfile, NULL, new_val) > 0) return 1;
+
+	new_keepalive_ms = new_val[KEEPALIVE_TYPE].timeout;
+	new_keepalive_string = new_val[KEEPALIVE_TYPE].string;
+	new_deadtime_ms = new_val[DEADTIME_TYPE].timeout;
+	new_deadtime_string = new_val[DEADTIME_TYPE].string;
+	new_warntime_ms = new_val[WARNTIME_TYPE].timeout;
+	new_warntime_string = new_val[WARNTIME_TYPE].string;
+	new_deadping_ms = new_val[DEADPING_TYPE].timeout;
+	new_deadping_string = new_val[DEADPING_TYPE].string;
+
+	if (new_keepalive_ms == 0) {
+		ha_log(LOG_ERR, "keepalive value is not set.\n");
+		new_timeout_vals_free(new_val);
+		return 2;
+	}
+
+	if (new_deadtime_ms == 0) {
+		ha_log(LOG_ERR, "deadtime value is not set.\n");
+		new_timeout_vals_free(new_val);
+		return 2;
+	}
+
+	if (new_keepalive_ms != config->heartbeat_ms) mode |= OW_KEEPALIVE;
+	if (new_deadtime_ms != config->deadtime_ms) mode |= OW_DEADTIME;
+	if (new_warntime_ms != config->warntime_ms) mode |= OW_WARNTIME;
+	if (new_deadping_ms != config->deadping_ms) mode |= OW_DEADPING;
+
+	if (new_deadtime_ms < new_keepalive_ms * 2){
+		ha_log(LOG_ERR, "deadtime value is smaller "
+		"than keepalive time * 2.\n");
+		ha_log(LOG_ERR, "keepalive value: %ld\n", new_keepalive_ms);
+		ha_log(LOG_ERR, "deadtime value: %ld\n", new_deadtime_ms);
+		new_timeout_vals_free(new_val);
+		return 3;
+	}
+
+	if (new_deadping_ms < new_keepalive_ms * 2) {
+		ha_log(LOG_ERR, "deadping value is smaller "
+		"than keepalive time * 2.\n");
+		ha_log(LOG_ERR, "keepalive value: %ld\n", new_keepalive_ms);
+		ha_log(LOG_ERR, "deadping value: %ld\n", new_deadping_ms);
+		new_timeout_vals_free(new_val);
+		return 4;
+	}
+
+	apply_new_timeout_value(mode, new_val);
+
+	new_timeout_vals_free(new_val);
+
+	return 0;
+}
+
+void
+modify_keepalive_value(long new_keepalive_ms, char *new_keepalive_string)
+{
+	int i;
+
+	cl_log(LOG_INFO, "%s: keepalive %ld time is over-written "
+	"to new value %ld", __FUNCTION__
+	,	config->heartbeat_ms, new_keepalive_ms);
+	config->heartbeat_ms = new_keepalive_ms;
+	SetParameterValue(KEY_KEEPALIVE, new_keepalive_string);
+
+	modify_channel_value(KEEPALIVE_TYPE);
+	for (i=0; i < timeout_add_full_array->len; ++i) {
+		/*
+		 * This part is duplicated from Gmain_timeout_add_full()
+		 * in lib/clplumbing/GSource.c
+		 */
+		struct GTimeoutAppend *append;
+		guint id = g_array_index(timeout_add_full_array, guint, i);
+		GSource *source;
+
+		source  = g_main_context_find_source_by_id(NULL, id);
+
+		if (source != NULL) {
+			append = GTIMEOUT(source);
+			append->interval = config->heartbeat_ms;
+		}
+	}
+}
+
+void
+modify_deadtime_value(long new_deadtime_ms, char *new_deadtime_string)
+{
+	int i;
+
+	cl_log(LOG_INFO, "%s: deadtime %ld time is over-written "
+	"to new value %ld", __FUNCTION__
+	,	config->deadtime_ms, new_deadtime_ms);
+	SetParameterValue(KEY_DEADTIME, new_deadtime_string);
+
+	/*
+	 * this part is taken from init_config().
+	 */
+	for (i=0; i < config->nodecount; ++i) {
+		if (config->nodes[i].nodetype != PINGNODE_I
+		&&	strcmp(config->nodes[i].nodename
+		,	curnode->nodename) == 0) {
+			config->nodes[i].dead_ticks
+			=	msto_longclock(new_deadtime_ms);
+		}
+	}
+
+	/*
+	 * for heartbeat.c hb_init_watchdog_interval().
+	 */
+	if (watchdog_timeout_ms == 0L ||
+		watchdog_timeout_ms == (config->deadtime_ms + 10))
+		watchdog_timeout_ms = new_deadtime_ms + 10;
+
+	config->deadtime_ms = new_deadtime_ms;
+	hb_send_local_status(NULL);
+	modify_channel_value(DEADTIME_TYPE);
+
+	/*
+	 * for heartbeat.c hb_reregister_with_apphbd()
+	 * and hb_init_watchdog().
+	 */
+	if (UseApphbd == TRUE) {
+		hb_init_register_with_apphbd_dummy();
+	}
+}
+
 /*
  *	Dump the configuration file - as a configuration file :-)
  *
diff -uNrp heartbeat-2.1.1.orig/heartbeat/hb_config.h \
                heartbeat-2.1.1/heartbeat/hb_config.h
--- heartbeat-2.1.1.orig/heartbeat/hb_config.h	2007-07-27 09:26:08.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/hb_config.h	2007-07-27 09:26:18.000000000 +0900
@@ -22,14 +22,25 @@
 #ifndef _HB_CONFIG_H
 #define _HB_CONFIG_H
 
+struct new_timeout_vals {
+	long		timeout;
+	char *		string;
+};
+
 int		parse_ha_resources(const char * cfgfile);
 void		dump_config(void);
 void		dump_default_config(int wikiout);
 int		add_node(const char * value, int nodetype);
 int   		parse_authfile(void);
 int		init_config(const char * cfgfile);
+int		light_parse_config(const char * cfgfile);
+void		apply_new_timeout_value(long mode, struct new_timeout_vals *new_val);
+void		modify_keepalive_value(long new_keepalive_ms, char * new_keepalive_string);
+void		modify_deadtime_value(long new_deadtime_ms, char * new_deadtime_string);
+void		new_timeout_vals_free(struct new_timeout_vals *new_val);
 int		StringToBaud(const char * baudstr);
 const char *	GetParameterValue(const char * name);
+void		hb_init_register_with_apphbd_dummy(void);
 /* maxdispatchdelay_array_add() records calls to G_main_setmaxdispatchdelay()
  * so that is can be called once again if the base timeout is updated.
  *
diff -uNrp heartbeat-2.1.1.orig/heartbeat/hb_signal.c \
                heartbeat-2.1.1/heartbeat/hb_signal.c
--- heartbeat-2.1.1.orig/heartbeat/hb_signal.c	2007-07-27 09:26:12.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/hb_signal.c	2007-07-27 09:27:05.000000000 +0900
@@ -363,6 +363,7 @@ hb_signal_light_reread_config_handler(in
 void
 hb_signal_light_reread_config_action(void)
 {
+	light_parse_config(CONFIG_NAME);
 	return;
 }
 
diff -uNrp heartbeat-2.1.1.orig/heartbeat/heartbeat.c \
                heartbeat-2.1.1/heartbeat/heartbeat.c
--- heartbeat-2.1.1.orig/heartbeat/heartbeat.c	2007-07-27 09:26:08.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/heartbeat.c	2007-07-27 09:26:18.000000000 +0900
@@ -312,7 +312,7 @@ static gboolean			RegisteredWithApphbd =
 
 char *				watchdogdev = NULL;
 static int			watchdogfd = -1;
-static int			watchdog_timeout_ms = 0L;
+int			watchdog_timeout_ms = 0L;
 
 int				shutdown_in_progress = FALSE;
 int				startup_complete = FALSE;
@@ -5194,6 +5194,12 @@ hb_init_register_with_apphbd(void)
 	}
 }
 
+void
+hb_init_register_with_apphbd_dummy(void)
+{
+	hb_init_register_with_apphbd();
+}
+
 static gboolean
 hb_reregister_with_apphbd(gpointer dummy)
 {
diff -uNrp heartbeat-2.1.1.orig/include/clplumbing/GSource_internal.h \
                heartbeat-2.1.1/include/clplumbing/GSource_internal.h
--- heartbeat-2.1.1.orig/include/clplumbing/GSource_internal.h	2007-07-24 \
                11:25:17.000000000 +0900
+++ heartbeat-2.1.1/include/clplumbing/GSource_internal.h	2007-07-27 \
09:26:18.000000000 +0900 @@ -98,6 +98,14 @@ struct GTRIGSource_s {
 	gboolean 	(*dispatch)(gpointer user_data);
 };
 
+struct GTimeoutAppend {
+	COMMON_STRUCTSTART;
+	longclock_t	nexttime;
+	guint		interval;
+};
+
+#define        GTIMEOUT(GS)    ((struct GTimeoutAppend*)((void*)(GS)))
+
 /************************************************************
  *		Functions for IPC_Channels
  ***********************************************************/
diff -uNrp heartbeat-2.1.1.orig/include/heartbeat.h \
                heartbeat-2.1.1/include/heartbeat.h
--- heartbeat-2.1.1.orig/include/heartbeat.h	2007-07-27 09:26:08.000000000 +0900
+++ heartbeat-2.1.1/include/heartbeat.h	2007-07-27 09:26:18.000000000 +0900
@@ -335,6 +335,12 @@ struct client_child {
 };
 
 #define TMOUTNUMS		4
+
+#define OW_KEEPALIVE		0x0001UL
+#define OW_DEADTIME		0x0002UL
+#define OW_WARNTIME		0x0004UL
+#define OW_DEADPING		0x0008UL
+
 #define KEEPALIVE_TYPE		0
 #define DEADTIME_TYPE		1
 #define WARNTIME_TYPE		2
diff -uNrp heartbeat-2.1.1.orig/lib/clplumbing/GSource.c \
                heartbeat-2.1.1/lib/clplumbing/GSource.c
--- heartbeat-2.1.1.orig/lib/clplumbing/GSource.c	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/lib/clplumbing/GSource.c	2007-07-27 09:26:18.000000000 +0900
@@ -1403,14 +1403,6 @@ static GSourceFuncs Gmain_timeout_funcs 
 };
 
 
-struct GTimeoutAppend {
-	COMMON_STRUCTSTART;
-	longclock_t	nexttime;
-	guint		interval;
-};
-
-#define        GTIMEOUT(GS)    ((struct GTimeoutAppend*)((void*)(GS)))
-
 guint
 Gmain_timeout_add(guint interval
 ,	GSourceFunc	function


["5_send_keepalive_to_ccm_20070727.patch" (text/x-patch)]

diff -uNrp heartbeat-2.1.1.orig/heartbeat/config.c heartbeat-2.1.1/heartbeat/config.c
--- heartbeat-2.1.1.orig/heartbeat/config.c	2007-07-27 09:03:35.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/config.c	2007-07-27 09:03:47.000000000 +0900
@@ -1152,6 +1152,26 @@ modify_keepalive_value(long new_keepaliv
 			append->interval = config->heartbeat_ms;
 		}
 	}
+
+	{
+		/*
+		 * This part is for ccm. Sending new keepalive value.
+		 */
+		struct ha_msg * msg;
+		char keepalive[64];
+
+		snprintf(keepalive, sizeof(keepalive), "%lx"
+		,	config->heartbeat_ms);
+		msg = ha_msg_new(4);
+		ha_msg_add(msg, F_TYPE, "new keepalive");
+		ha_msg_add(msg, F_ORIG, curnode->nodename);
+		ha_msg_add(msg, F_STATUS, "new keepalive");
+		ha_msg_add(msg, F_KEEPALIVE, keepalive);
+
+		heartbeat_monitor(msg, KEEPIT, NULL);
+
+		ha_msg_del(msg);
+	}
 }
 
 void
diff -uNrp heartbeat-2.1.1.orig/heartbeat/hb_api.c heartbeat-2.1.1/heartbeat/hb_api.c
--- heartbeat-2.1.1.orig/heartbeat/hb_api.c	2007-07-27 08:37:39.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/hb_api.c	2007-07-27 09:03:47.000000000 +0900
@@ -197,7 +197,7 @@ struct seq_snapshot{
 	seqno_t		last_seq;
 };
 
-
+extern GPtrArray*	maxdispatchdelay_array;
 
 static int
 should_msg_sendto_client(client_proc_t* client, struct ha_msg* msg)
@@ -1648,6 +1648,7 @@ G_remove_client(gpointer Client)
 {
 	client_proc_t*	client = Client;
 	const char *	reason;
+	int		i;
 
 	reason = client->removereason ? client->removereason : "?";
 	if (ANYDEBUG) {
@@ -1656,6 +1657,22 @@ G_remove_client(gpointer Client)
 		,	client->pid, reason, (unsigned long) client->gsource);
 	}
 
+	/*
+	 * Need following routine for api_signoff from clients.
+	 * Because memoried pointer is removed by api_remove_client_int().
+	 */
+	for (i=0; i < maxdispatchdelay_array->len; ++i) {
+		struct MaxDispatchDelay_Array *carray = g_ptr_array_index(
+			maxdispatchdelay_array, i);
+		if (carray != NULL
+		&&	(GCHSource*)(carray->addr) == (client->gsource)) {
+			cl_log(LOG_INFO, "Remove 0x%lx from maxdispatchdelay_array"
+			,	(unsigned long)(client->gsource));
+			g_ptr_array_remove_index_fast(maxdispatchdelay_array, i);
+			break;
+		}
+	}
+
 	api_remove_client_int(client, reason);
 	if (ANYDEBUG) {
 		cl_log(LOG_DEBUG
diff -uNrp heartbeat-2.1.1.orig/membership/ccm/ccm.c \
                heartbeat-2.1.1/membership/ccm/ccm.c
--- heartbeat-2.1.1.orig/membership/ccm/ccm.c	2007-07-24 11:25:19.000000000 +0900
+++ heartbeat-2.1.1/membership/ccm/ccm.c	2007-07-27 09:03:47.000000000 +0900
@@ -115,6 +115,9 @@ nodelist_update(ll_cluster_t* hb, ccm_in
 	return HA_OK;
 }
 
+extern ccm_info_t* ccm_info_saved;
+extern ll_cluster_t* hb_fd_saved;
+
 int
 ccm_control_process(ccm_info_t *info, ll_cluster_t * hb)
 {
@@ -151,6 +154,13 @@ ccm_control_process(ccm_info_t *info, ll
 			}
 			ha_msg_del(msg);
 			msg = newmsg;
+		} else if(strcasecmp(type, "new keepalive") == 0){
+			hb_fd_saved->llc_ops->signoff(hb_fd_saved, FALSE);
+			hb_fd_saved->llc_ops->signon(hb_fd_saved, "ccm");
+			sleep( 3 );
+
+			ccm_configure_timeout( hb_fd_saved, ccm_info_saved );
+			return TRUE;
 		} else if(strcasecmp(type, T_STATUS) == 0){
 			const char* nodetype;
 			const char* site;
diff -uNrp heartbeat-2.1.1.orig/membership/ccm/ccm.h \
                heartbeat-2.1.1/membership/ccm/ccm.h
--- heartbeat-2.1.1.orig/membership/ccm/ccm.h	2007-07-24 11:25:19.000000000 +0900
+++ heartbeat-2.1.1/membership/ccm/ccm.h	2007-07-27 09:03:47.000000000 +0900
@@ -464,6 +464,8 @@ typedef struct ccm_info_s {
 	int		has_quorum;	/* -1, not set, 0, no quorum, 1, has quorum */
 } ccm_info_t;
 
+void ccm_configure_timeout(ll_cluster_t *, ccm_info_t *);
+
 /*
  * datastructure passed to the event loop.
  * This acts a handle, and should not be interpreted
diff -uNrp heartbeat-2.1.1.orig/membership/ccm/ccm_statemachine.c \
                heartbeat-2.1.1/membership/ccm/ccm_statemachine.c
--- heartbeat-2.1.1.orig/membership/ccm/ccm_statemachine.c	2007-07-24 \
                11:25:19.000000000 +0900
+++ heartbeat-2.1.1/membership/ccm/ccm_statemachine.c	2007-07-27 09:03:47.000000000 \
+0900 @@ -200,7 +200,7 @@ static void ccm_state_new_node_wait_for_
 /* */
 /* timeout configuration function */
 /* */
-static void
+void
 ccm_configure_timeout(ll_cluster_t *hb, ccm_info_t *info)
 {
 	long keepalive = hb->llc_ops->get_keepalive(hb);


["6_send_values_to_cluster_20070727.patch" (text/x-patch)]

diff -uNrp heartbeat-2.1.1.orig/heartbeat/config.c heartbeat-2.1.1/heartbeat/config.c
--- heartbeat-2.1.1.orig/heartbeat/config.c	2007-07-27 09:07:11.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/config.c	2007-07-27 09:07:39.000000000 +0900
@@ -1119,6 +1119,8 @@ light_parse_config(const char * cfgfile)
 
 	apply_new_timeout_value(mode, new_val);
 
+	if (mode != 0x0UL) send_modified_timeout_value(mode);
+
 	new_timeout_vals_free(new_val);
 
 	return 0;
diff -uNrp heartbeat-2.1.1.orig/heartbeat/hb_config.h heartbeat-2.1.1/heartbeat/hb_config.h
--- heartbeat-2.1.1.orig/heartbeat/hb_config.h	2007-07-27 09:03:35.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/hb_config.h	2007-07-27 09:08:04.000000000 +0900
@@ -37,6 +37,7 @@ int		light_parse_config(const char * cfg
 void		apply_new_timeout_value(long mode, struct new_timeout_vals *new_val);
 void		modify_keepalive_value(long new_keepalive_ms, char * new_keepalive_string);
 void		modify_deadtime_value(long new_deadtime_ms, char * new_deadtime_string);
+int		send_modified_timeout_value(long mode);
 void		new_timeout_vals_free(struct new_timeout_vals *new_val);
 int		StringToBaud(const char * baudstr);
 const char *	GetParameterValue(const char * name);
diff -uNrp heartbeat-2.1.1.orig/heartbeat/heartbeat.c heartbeat-2.1.1/heartbeat/heartbeat.c
--- heartbeat-2.1.1.orig/heartbeat/heartbeat.c	2007-07-27 09:03:35.000000000 +0900
+++ heartbeat-2.1.1/heartbeat/heartbeat.c	2007-07-27 09:07:24.000000000 +0900
@@ -375,6 +375,7 @@ static
 const char*	ManagedChildName(ProcTrack* p);
 static void	check_for_timeouts(void);
 static void	check_comm_isup(void);
+int		timeout_add_msg(struct ha_msg *m, long timeout_val, const char *type);
 static int	send_local_status(void);
 static int	set_local_status(const char * status);
 static void	check_rexmit_reqs(void);
@@ -430,6 +431,8 @@ static void HBDoMsg_T_STATUS(const char 
 ,	TIME_T msgtime, seqno_t seqno, const char * iface, struct ha_msg * msg);
 static void HBDoMsg_T_QCSTATUS(const char * type, struct node_info * fromnode
 ,	TIME_T msgtime, seqno_t seqno, const char * iface, struct ha_msg * msg);
+static void HBDoMsg_T_CHTOVAL(const char * type, struct node_info * fromnode
+,	TIME_T msgtime, seqno_t seqno, const char * iface, struct ha_msg * msg);
 
 static void (*comm_up_callback)(void) = NULL;
 static gboolean set_init_deadtime_passed_flag(gpointer p);
@@ -3011,6 +3014,48 @@ HBDoMsg_T_REXMIT(const char * type, stru
 	}
 }
 
+static void
+HBDoMsg_T_CHTOVAL(const char * type, struct node_info * fromnode
+,	TIME_T msgtime, seqno_t seqno, const char * iface, struct ha_msg * msg)
+{
+	int				i;
+	long				mode = 0x0UL;
+	const char *			timeout;
+	char				string[64];
+	const char *	timeout_type[TMOUTNUMS] = {F_KEEPALIVE
+			,	F_DEADTIME, F_WARNTIME, F_DEADPING};
+	unsigned long	ow_mode[TMOUTNUMS] = {OW_KEEPALIVE, OW_DEADTIME
+			,	OW_WARNTIME, OW_DEADPING};
+
+	struct new_timeout_vals *	new_val;
+
+	cl_log(LOG_INFO, "%s: Received signal to apply modified timeout value"
+		" from %s", __FUNCTION__, fromnode->nodename);
+
+	if (fromnode == curnode) return;
+
+	new_val = (struct new_timeout_vals *)
+		cl_malloc(sizeof(struct new_timeout_vals)*TMOUTNUMS);
+
+	for (i=0; i < TMOUTNUMS; ++i) {
+		timeout = ha_msg_value(msg, timeout_type[i]);
+		if (timeout == NULL) {
+			new_val[i].string = NULL;
+			continue;
+		}
+		sscanf(timeout, "%lx", (unsigned long*)&(new_val[i].timeout));
+		snprintf(string, sizeof(string), "%ldms", new_val[i].timeout);
+		new_val[i].string = cl_strdup(string);
+		mode |= ow_mode[i];
+	}
+
+	apply_new_timeout_value(mode, new_val);
+
+	new_timeout_vals_free(new_val);
+
+	return;
+}
+
 /* Process status update (i.e., "heartbeat") message? */
 static void
 HBDoMsg_T_STATUS(const char * type, struct node_info * fromnode
@@ -4401,8 +4446,76 @@ send_cluster_msg(struct ha_msg* msg)
 	return rc;
 }
 
+int
+timeout_add_msg(struct ha_msg *m, long timeout_val, const char *type)
+{
+	int		rc;
+	char		timeout[64];
 
+	cl_log(LOG_INFO, "%s: type = %s, timeout_val = %ld", __FUNCTION__
+	,	type, timeout_val );
+	snprintf(timeout, sizeof(timeout), "%lx", timeout_val);
+	rc = ha_msg_add(m, type, timeout);
+	if (rc != HA_OK) {
+		cl_log(LOG_ERR, "%s: Adding modified timeout value (%s) failed"
+		,	__FUNCTION__, type); 
+	}
 
+	return rc;
+}
+
+int
+send_modified_timeout_value(long mode)
+{
+	struct ha_msg *	m;
+	int		rc;
+	int		i;
+
+	struct OW_Mode {
+		unsigned long	mode;
+		long		timeout;
+		const char *	string;
+	} ow_modes[] =
+	{ {OW_KEEPALIVE, config->heartbeat_ms, F_KEEPALIVE}
+	, {OW_DEADTIME, config->deadtime_ms, F_DEADTIME}
+	, {OW_WARNTIME, config->warntime_ms, F_WARNTIME}
+	, {OW_DEADPING, config->deadping_ms, F_DEADPING}
+	};
+
+	if ((m=ha_msg_new(0)) == NULL) {
+		cl_log(LOG_ERR, "Cannot send modified timeout value.");
+		return HA_FAIL;
+	}
+
+	if (ha_msg_add(m, F_TYPE, T_CHTOVAL) != HA_OK
+	||	ha_msg_add(m, F_ORIG, curnode->nodename) != HA_OK) {
+		cl_log(LOG_ERR, "%s: Cannnot create modified timeout msg"
+		,	__FUNCTION__ );
+		rc = HA_FAIL;
+		ha_msg_del(m);
+		return rc;
+	}
+
+	for (i=0; i < TMOUTNUMS; ++i) {
+		if (mode&ow_modes[i].mode) {
+			rc = timeout_add_msg(m, ow_modes[i].timeout
+			,	ow_modes[i].string);
+			if (rc != HA_OK) {
+				ha_msg_del(m);
+				return rc;
+			}
+		}
+	}
+
+	cl_log(LOG_INFO, "%s: sending modified timeout value", __FUNCTION__ );
+	rc = send_cluster_msg(m);
+	if (rc != HA_OK) {
+		cl_log(LOG_ERR, "%s: sending modified timeout value is failed"
+		,	__FUNCTION__);
+	}
+
+	return rc;
+}
 
 /* Send our local status out to the cluster */
 static int
@@ -4780,6 +4893,7 @@ main(int argc, char * argv[], char **env
 	hb_register_msg_callback(T_DELNODE,	HBDoMsg_T_DELNODE);
 	hb_register_msg_callback(T_REQNODES,    HBDoMsg_T_REQNODES);
 	hb_register_msg_callback(T_REPNODES, 	HBDoMsg_T_REPNODES);
+	hb_register_msg_callback(T_CHTOVAL, 	HBDoMsg_T_CHTOVAL);
 
 	if (init_set_proc_title(argc, argv, envp) < 0) {
 		cl_log(LOG_ERR, "Allocation of proc title failed.");
diff -uNrp heartbeat-2.1.1.orig/include/ha_msg.h heartbeat-2.1.1/include/ha_msg.h
--- heartbeat-2.1.1.orig/include/ha_msg.h	2007-07-24 11:25:17.000000000 +0900
+++ heartbeat-2.1.1/include/ha_msg.h	2007-07-27 09:07:24.000000000 +0900
@@ -181,7 +181,9 @@ extern struct fieldtypefuncs_s fieldtype
 #define F_PNAME		"pname"		/* Parameter name */
 #define F_PVALUE	"pvalue"	/* Parameter name */
 #define F_DEADTIME	"deadtime"	/* Dead time interval in ms. */
+#define F_DEADPING	"deadping"	/* Dead ping interval in ms. */
 #define F_KEEPALIVE	"keepalive"	/* Keep alive time interval in ms. */
+#define F_WARNTIME	"warntime"	/* Warn time interlva in ms. */
 #define F_LOGFACILITY	"logfacility"	/* Suggested cluster syslog facility */
 #define F_NODETYPE	"nodetype"	/* Type of node */
 #define F_NUMNODES	"numnodes"	/* num of total nodes(excluding ping nodes*/
@@ -237,6 +239,8 @@ extern struct fieldtypefuncs_s fieldtype
 #define T_STONITH_NOTCONFGD	"n_stnth" /* no stonith device configured */
 #define T_STONITH_UNNEEDED	"unneeded" /* STONITH not required */
 
+#define T_CHTOVAL		"change_timeout_value"	/* transmit modified timeout value */
+
 /* Set up message statistics area */
 
 int	netstring_extra(int);


_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic