looks good for commit break out the main.c change separately as a patch
thanks On Tue, 2010-03-30 at 13:28 +1100, Angus Salkeld wrote: > Add a test service to CTS. > > This enables us to test sync behaviour better. > > -Angus > > Signed-off-by: Angus Salkeld <[email protected]> > --- > conf/lenses/corosync.aug | 8 +- > cts/agents/Makefile.am | 47 +++++++ > cts/agents/syncv2.c | 309 > +++++++++++++++++++++++++++++++++++++++++++ > cts/corosync.py | 2 + > cts/corotests.py | 81 +++++++++++- > exec/main.c | 4 +- > include/corosync/corodefs.h | 4 +- > 7 files changed, 450 insertions(+), 5 deletions(-) > create mode 100644 cts/agents/syncv2.c > > diff --git a/conf/lenses/corosync.aug b/conf/lenses/corosync.aug > index 52c613b..e9eff2b 100644 > --- a/conf/lenses/corosync.aug > +++ b/conf/lenses/corosync.aug > @@ -122,6 +122,12 @@ let quorum = > qstr /provider/ in > section "quorum" setting > > -let lns = (comment|empty|compatibility|totem|quorum|logging|amf)* > +(* The quorum section *) > +let service = > + let setting = > + qstr /name|ver/ in > + section "service" setting > + > +let lns = (comment|empty|compatibility|totem|quorum|logging|amf|service)* > > let xfm = transform lns (incl "/etc/corosync/corosync.conf") > diff --git a/cts/agents/Makefile.am b/cts/agents/Makefile.am > index 5c5c211..01dd2ce 100644 > --- a/cts/agents/Makefile.am > +++ b/cts/agents/Makefile.am > @@ -32,15 +32,24 @@ > MAINTAINERCLEANFILES = Makefile.in > INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include > > +SOURCES = > TEST_AGENTS = cpg_test_agent confdb_test_agent > > if INSTALL_TESTAGENTS > agentdir = $(datadir)/$(PACKAGE)/tests > bin_PROGRAMS = $(TEST_AGENTS) > dist_agent_SCRIPTS = mem_leak_test.sh net_breaker.sh > + > +AM_CFLAGS = -fPIC > +SERVICE_LCRSO = syncv2 > +SOURCES += $(SERVICE_LCRSO:%=%.c) > +EXTRA_DIST = $(SOURCES) > +LCRSO = $(SERVICE_LCRSO:%=service_%.lcrso) > +LCRSO_OBJS = $(SOURCES:%.c=%.o) > else > noinst_PROGRAMS = $(TEST_AGENTS) > noinst_SCRIPTS = mem_leak_test.sh net_breaker.sh > +LCRSO = > endif > > noinst_HEADERS = common_test_agent.h > @@ -53,6 +62,44 @@ confdb_test_agent_SOURCES = confdb_test_agent.c > common_test_agent.c > confdb_test_agent_LDADD = -lconfdb -lcoroipcc ../../exec/coropoll.o > confdb_test_agent_LDFLAGS = -L../../lib > > + > +if BUILD_DARWIN > + > +service_%.lcrso: %.o > + $(CC) $(CFLAGS) -L$(top_builddir)/exec -llogsys -bundle -bundle_loader > $(top_builddir)/exec/corosync $^ -o $@ > + > +else > +if BUILD_SOLARIS > + > +service_%.lcrso: %.o > + $(LD) $(LDFLAGS) -G $^ -o $@ > + > +else > + > +service_%.lcrso: %.o > + $(CC) $(CFLAGS) $(COVERAGE_LCRSO_EXTRA_LDFLAGS) -shared -Wl,-soname=$@ > $^ -o $@ > +endif > +endif > + > + > + > +if INSTALL_TESTAGENTS > +all-local: $(LCRSO_OBJS) $(LCRSO) > + @echo Built Service Engines > + > +install-exec-local: > + $(INSTALL) -d $(DESTDIR)/$(LCRSODIR) > + $(INSTALL) -m 755 $(LCRSO) $(DESTDIR)/$(LCRSODIR) > + > +uninstall-local: > + cd $(DESTDIR)/$(LCRSODIR) && \ > + rm -f $(LCRSO) > + > +endif > + > +clean-local: > + rm -f *.o *.a *.so* *.da *.bb *.bbg *.lcrso > + > lint: > -splint $(LINT_FLAGS) $(CFLAGS) *.c > > diff --git a/cts/agents/syncv2.c b/cts/agents/syncv2.c > new file mode 100644 > index 0000000..e5645a4 > --- /dev/null > +++ b/cts/agents/syncv2.c > @@ -0,0 +1,309 @@ > +/* > + * Copyright (c) 2010 Red Hat, Inc. > + * > + * All rights reserved. > + * > + * Author: Angus Salkeld <[email protected]> > + * > + * This software licensed under BSD license, the text of which follows: > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions are > met: > + * > + * - Redistributions of source code must retain the above copyright notice, > + * this list of conditions and the following disclaimer. > + * - Redistributions in binary form must reproduce the above copyright > notice, > + * this list of conditions and the following disclaimer in the > documentation > + * and/or other materials provided with the distribution. > + * - Neither the name of the MontaVista Software, Inc. nor the names of its > + * contributors may be used to endorse or promote products derived from > this > + * software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > + * THE POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include <config.h> > + > +#include <sys/types.h> > +#include <sys/socket.h> > +#include <sys/un.h> > +#include <sys/time.h> > +#include <sys/ioctl.h> > +#include <netinet/in.h> > +#include <sys/uio.h> > +#include <unistd.h> > +#include <fcntl.h> > +#include <stdlib.h> > +#include <stdio.h> > +#include <errno.h> > +#include <time.h> > +#include <netinet/in.h> > +#include <arpa/inet.h> > +#include <string.h> > + > +#include <corosync/swab.h> > +#include <corosync/corotypes.h> > +#include <corosync/coroipc_types.h> > +#include <corosync/corodefs.h> > +#include <corosync/lcr/lcr_comp.h> > +#include <corosync/mar_gen.h> > +#include <corosync/engine/coroapi.h> > +#include <corosync/list.h> > +#include <corosync/engine/logsys.h> > + > +#include "../exec/tlist.h" > + > +LOGSYS_DECLARE_SUBSYS ("TST2"); > + > +/* > + * Service Interfaces required by service_message_handler struct > + */ > +static int tst_sv2_exec_init_fn ( > + struct corosync_api_v1 *corosync_api); > + > +static void tst_sv2_confchg_fn ( > + enum totem_configuration_type configuration_type, > + const unsigned int *member_list, size_t member_list_entries, > + const unsigned int *left_list, size_t left_list_entries, > + const unsigned int *joined_list, size_t joined_list_entries, > + const struct memb_ring_id *ring_id); > + > +static int tst_sv2_lib_init_fn (void *conn); > +static int tst_sv2_lib_exit_fn (void *conn); > +static struct corosync_api_v1 *api; > + > +static void tst_sv2_sync_init_v2 ( > + const unsigned int *member_list, > + size_t member_list_entries, > + const struct memb_ring_id *ring_id); > + > +static int tst_sv2_sync_process (void); > + > +static void tst_sv2_sync_activate (void); > + > +static void tst_sv2_sync_abort (void); > + > +struct corosync_service_engine tst_sv2_service_engine = { > + .name = "corosync test synv2 service", > + .id = TST_SV2_SERVICE, > + .priority = 1, > + .private_data_size = 0, > + .flow_control = CS_LIB_FLOW_CONTROL_NOT_REQUIRED, > + .lib_init_fn = tst_sv2_lib_init_fn, > + .lib_exit_fn = tst_sv2_lib_exit_fn, > + .lib_engine = NULL, > + .lib_engine_count = 0, > + .exec_engine = NULL, > + .exec_engine_count = 0, > + .confchg_fn = tst_sv2_confchg_fn, > + .exec_init_fn = tst_sv2_exec_init_fn, > + .exec_dump_fn = NULL, > + .sync_mode = CS_SYNC_V2, > + .sync_init = tst_sv2_sync_init_v2, > + .sync_process = tst_sv2_sync_process, > + .sync_activate = tst_sv2_sync_activate, > + .sync_abort = tst_sv2_sync_abort > +}; > + > +static unsigned int my_member_list[PROCESSOR_COUNT_MAX]; > + > +static unsigned int my_member_list_entries; > + > +static unsigned int my_old_member_list[PROCESSOR_COUNT_MAX]; > + > +static unsigned int my_old_member_list_entries = 0; > +static int num_sync_processes = 0; > + > +static DECLARE_LIST_INIT (confchg_notify); > + > +/* > + * Dynamic loading descriptor > + */ > + > +static struct corosync_service_engine *tst_sv2_get_service_engine_ver0 > (void); > + > +static struct corosync_service_engine_iface_ver0 > tst_sv2_service_engine_iface = { > + .corosync_get_service_engine_ver0 = > tst_sv2_get_service_engine_ver0 > +}; > + > +static struct lcr_iface corosync_tst_sv2_ver0[1] = { > + { > + .name = "corosync_tst_sv2", > + .version = 0, > + .versions_replace = 0, > + .versions_replace_count = 0, > + .dependencies = 0, > + .dependency_count = 0, > + .constructor = NULL, > + .destructor = NULL, > + .interfaces = NULL, > + } > +}; > + > +static struct lcr_comp tst_sv2_comp_ver0 = { > + .iface_count = 1, > + .ifaces = corosync_tst_sv2_ver0 > +}; > + > +static struct corosync_service_engine *tst_sv2_get_service_engine_ver0 (void) > +{ > + return (&tst_sv2_service_engine); > +} > + > +#ifdef COROSYNC_SOLARIS > +void corosync_lcr_component_register (void); > + > +void corosync_lcr_component_register (void) { > +#else > +__attribute__ ((constructor)) static void corosync_lcr_component_register > (void) { > +#endif > + lcr_interfaces_set (&corosync_tst_sv2_ver0[0], > &tst_sv2_service_engine_iface); > + > + lcr_component_register (&tst_sv2_comp_ver0); > +} > + > +static int tst_sv2_exec_init_fn ( > + struct corosync_api_v1 *corosync_api) > +{ > +#ifdef COROSYNC_SOLARIS > + logsys_subsys_init(); > +#endif > + api = corosync_api; > + > + return 0; > +} > + > +static void tst_sv2_confchg_fn ( > + enum totem_configuration_type configuration_type, > + const unsigned int *member_list, size_t member_list_entries, > + const unsigned int *left_list, size_t left_list_entries, > + const unsigned int *joined_list, size_t joined_list_entries, > + const struct memb_ring_id *ring_id) > +{ > + int j; > + for (j = 0; j < left_list_entries; j++) { > + log_printf (LOGSYS_LEVEL_INFO, > + "Member left: %s", api->totem_ifaces_print > (left_list[j])); > + } > + for (j = 0; j < joined_list_entries; j++) { > + log_printf (LOGSYS_LEVEL_INFO, > + "Member joined: %s", api->totem_ifaces_print > (joined_list[j])); > + } > +} > + > +static int tst_sv2_lib_init_fn (void *conn) > +{ > + return (0); > +} > + > +static int tst_sv2_lib_exit_fn (void *conn) > +{ > + return (0); > +} > + > + > +static void tst_sv2_sync_init_v2 ( > + const unsigned int *member_list, > + size_t member_list_entries, > + const struct memb_ring_id *ring_id) > +{ > + unsigned int lowest_nodeid = 0xffffffff; > + int i, j; > + int found; > + > + num_sync_processes = 0; > + > + memcpy (my_member_list, member_list, member_list_entries * > + sizeof (unsigned int)); > + my_member_list_entries = member_list_entries; > + > + for (i = 0; i < my_member_list_entries; i++) { > + if (my_member_list[i] < lowest_nodeid) { > + lowest_nodeid = my_member_list[i]; > + } > + } > + > + log_printf (LOGSYS_LEVEL_INFO, > + "tst_sv2_sync_init_v2 %s", > + api->totem_ifaces_print (lowest_nodeid)); > + > + /* look for new (joined) nodes */ > + for (j = 0; j < member_list_entries; j++) { > + found = 0; > + for (i = 0; i < my_old_member_list_entries; i++) { > + if (my_old_member_list[i] == member_list[j]) { > + found = 1; > + break; > + } > + } > + if (found == 0) { > + log_printf (LOGSYS_LEVEL_INFO, > + "sync: node joined %s", > + api->totem_ifaces_print (member_list[j])); > + } > + } > + /* look for old (left) nodes */ > + for (i = 0; i < my_old_member_list_entries; i++) { > + found = 0; > + for (j = 0; j < member_list_entries; j++) { > + if (my_old_member_list[i] == member_list[j]) { > + found = 1; > + break; > + } > + } > + if (found == 0) { > + log_printf (LOGSYS_LEVEL_INFO, > + "sync: node left %s", > + api->totem_ifaces_print (my_old_member_list[i])); > + } > + } > + > +} > + > +static int tst_sv2_sync_process (void) > +{ > + num_sync_processes++; > + > + log_printf (LOGSYS_LEVEL_INFO, "sync: process %d", num_sync_processes); > + > + if (num_sync_processes > 3) { > + return 0; > + } else { > + return 1; > + } > +} > + > +static void tst_sv2_sync_activate (void) > +{ > + memcpy (my_old_member_list, my_member_list, > + my_member_list_entries * sizeof (unsigned int)); > + my_old_member_list_entries = my_member_list_entries; > + > + if (num_sync_processes <= 3) { > + log_printf (LOGSYS_LEVEL_ERROR, > + "sync: activate called before process is done %d", > + num_sync_processes); > + } else { > + log_printf (LOGSYS_LEVEL_INFO, > + "sync: activate correctly %d", > + num_sync_processes); > + } > + > + num_sync_processes = 0; > +} > + > +static void tst_sv2_sync_abort (void) > +{ > + log_printf (LOGSYS_LEVEL_INFO, "sync: abort"); > +} > + > diff --git a/cts/corosync.py b/cts/corosync.py > index f54af4d..6962f39 100644 > --- a/cts/corosync.py > +++ b/cts/corosync.py > @@ -141,6 +141,8 @@ class corosync_flatiron(ClusterManager): > self.node_to_ip = {} > > self.new_config = {} > + self.new_config['service[0]/name'] = 'corosync_tst_sv2' > + self.new_config['service[0]/ver'] = '0' > self.applied_config = {} > for n in self.Env["nodes"]: > ip = socket.gethostbyname(n) > diff --git a/cts/corotests.py b/cts/corotests.py > index 95bef01..1d80722 100644 > --- a/cts/corotests.py > +++ b/cts/corotests.py > @@ -179,6 +179,83 @@ class CpgCfgChgOnNodeLeave(CpgConfigChangeBase): > return self.wait_for_config_change() > > ################################################################### > +class CpgCfgChgOnLowestNodeJoin(CTSTest): > + ''' > + 1) stop all nodes > + 2) start all but the node with the smallest ip address > + 3) start recording events > + 4) start the last node > + ''' > + def __init__(self, cm): > + CTSTest.__init__(self, cm) > + self.name="CpgCfgChgOnLowestNodeJoin" > + self.start = StartTest(cm) > + self.stop = StopTest(cm) > + self.config = {} > + self.config['compatibility'] = 'none' > + > + def lowest_ip_set(self): > + self.lowest = None > + for n in self.CM.Env["nodes"]: > + if self.lowest is None: > + self.lowest = n > + > + self.CM.log("lowest node is " + self.lowest) > + > + def setup(self, node): > + # stop all nodes > + for n in self.CM.Env["nodes"]: > + self.CM.StopaCM(n) > + > + self.lowest_ip_set() > + > + # copy over any new config > + for c in self.config: > + self.CM.new_config[c] = self.config[c] > + > + # install the config > + self.CM.install_all_config() > + > + # start all but lowest > + self.listener = None > + for n in self.CM.Env["nodes"]: > + if n is not self.lowest: > + if self.listener is None: > + self.listener = n > + self.incr("started") > + self.CM.log("starting " + n) > + self.start(n) > + self.CM.cpg_agent[n].clean_start() > + self.CM.cpg_agent[n].cpg_join(self.name) > + > + # start recording events > + pats = [] > + pats.append("%s .*sync: node joined.*" % self.listener) > + pats.append("%s .*sync: activate correctly.*" % self.listener) > + self.sync_log = self.create_watch(pats, 60) > + self.sync_log.setwatch() > + > + self.CM.log("setup done") > + > + return CTSTest.setup(self, node) > + > + > + def __call__(self, node): > + self.incr("calls") > + > + self.start(self.lowest) > + self.CM.cpg_agent[self.lowest].clean_start() > + self.CM.cpg_agent[self.lowest].cpg_join(self.name) > + self.wobbly_id = self.CM.cpg_agent[self.lowest].cpg_local_get() > + > + self.CM.log("waiting for sync events") > + if not self.sync_log.lookforall(): > + return self.failure("Patterns not found: " + > repr(self.sync_log.unmatched)) > + else: > + return self.success() > + > + > +################################################################### > class CpgCfgChgOnExecCrash(CpgConfigChangeBase): > > def __init__(self, cm): > @@ -495,6 +572,7 @@ GenTestClasses.append(CpgCfgChgOnExecCrash) > GenTestClasses.append(CpgCfgChgOnGroupLeave) > GenTestClasses.append(CpgCfgChgOnNodeLeave) > GenTestClasses.append(CpgCfgChgOnNodeIsolate) > +GenTestClasses.append(CpgCfgChgOnLowestNodeJoin) > > AllTestClasses = [] > AllTestClasses.append(ConfdbReplaceTest) > @@ -585,7 +663,8 @@ def CoroTestList(cm, audits): > bound_test = testclass(cm) > if bound_test.is_applicable(): > bound_test.Audits = audits > - bound_test.config = cfg > + for c in cfg: > + bound_test.config[c] = cfg[c] > bound_test.name = bound_test.name + '_' + str(num) > result.append(bound_test) > num = num + 1 > diff --git a/exec/main.c b/exec/main.c > index 0b7982a..f109606 100644 > --- a/exec/main.c > +++ b/exec/main.c > @@ -428,12 +428,12 @@ static void confchg_fn ( > memcpy (&corosync_ring_id, ring_id, sizeof (struct memb_ring_id)); > > for (i = 0; i < left_list_entries; i++) { > - log_printf (LOGSYS_LEVEL_INFO, > + log_printf (LOGSYS_LEVEL_DEBUG, > "Member left: %s\n", api->totem_ifaces_print > (left_list[i])); > member_object_left (left_list[i]); > } > for (i = 0; i < joined_list_entries; i++) { > - log_printf (LOGSYS_LEVEL_INFO, > + log_printf (LOGSYS_LEVEL_DEBUG, > "Member joined: %s\n", api->totem_ifaces_print > (joined_list[i])); > member_object_joined (joined_list[i]); > } > diff --git a/include/corosync/corodefs.h b/include/corosync/corodefs.h > index 4af7c8a..57923e2 100644 > --- a/include/corosync/corodefs.h > +++ b/include/corosync/corodefs.h > @@ -57,7 +57,9 @@ enum corosync_service_types { > TMR_SERVICE = 14, > VOTEQUORUM_SERVICE = 15, > NTF_SERVICE = 16, > - AMF_V2_SERVICE = 17 > + AMF_V2_SERVICE = 17, > + TST_SV1_SERVICE = 18, > + TST_SV2_SERVICE = 19 > }; > > #ifdef HAVE_SMALL_MEMORY_FOOTPRINT _______________________________________________ Openais mailing list [email protected] https://lists.linux-foundation.org/mailman/listinfo/openais
