[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