diff options
-rw-r--r-- | sys-cluster/openais/ChangeLog | 11 | ||||
-rw-r--r-- | sys-cluster/openais/files/openais-0.80.3-Makefile-VARS.patch | 99 | ||||
-rw-r--r-- | sys-cluster/openais/files/openais-0.80.3-Makefile.inc-VARS.patch | 20 | ||||
-rw-r--r-- | sys-cluster/openais/files/openais-0.80.3-r1661.patch | 6310 | ||||
-rw-r--r-- | sys-cluster/openais/openais-0.80.3-r1.ebuild (renamed from sys-cluster/openais/openais-0.80.3.ebuild) | 12 |
5 files changed, 6450 insertions, 2 deletions
diff --git a/sys-cluster/openais/ChangeLog b/sys-cluster/openais/ChangeLog index c33849861376..cb59fc372d18 100644 --- a/sys-cluster/openais/ChangeLog +++ b/sys-cluster/openais/ChangeLog @@ -1,6 +1,15 @@ # ChangeLog for sys-cluster/openais # Copyright 1999-2008 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/sys-cluster/openais/ChangeLog,v 1.3 2008/03/17 16:02:41 xmerlin Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-cluster/openais/ChangeLog,v 1.4 2008/11/21 22:55:48 xmerlin Exp $ + +*openais-0.80.3-r1 (21 Nov 2008) + + 21 Nov 2008; Christian Zoffoli <xmerlin@gentoo.org> + +files/openais-0.80.3-Makefile.inc-VARS.patch, + +files/openais-0.80.3-Makefile-VARS.patch, + +files/openais-0.80.3-r1661.patch, -openais-0.80.3.ebuild, + +openais-0.80.3-r1.ebuild: + openais whitetank updated to r1661. *openais-0.80.3 (17 Mar 2008) diff --git a/sys-cluster/openais/files/openais-0.80.3-Makefile-VARS.patch b/sys-cluster/openais/files/openais-0.80.3-Makefile-VARS.patch new file mode 100644 index 000000000000..4b00b2c8eff2 --- /dev/null +++ b/sys-cluster/openais/files/openais-0.80.3-Makefile-VARS.patch @@ -0,0 +1,99 @@ +--- openais-0.80.3/Makefile.orig 2008-11-18 19:38:46.000000000 +0100 ++++ openais-0.80.3/Makefile 2008-11-18 19:42:08.000000000 +0100 +@@ -29,30 +29,30 @@ + # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + # THE POSSIBILITY OF SUCH DAMAGE. + +-DESTDIR=/usr/local +-SBINDIR=/usr/sbin +-INCLUDEDIR=/usr/include/openais +-INCLUDEDIR_TOTEM=/usr/include/openais/totem +-INCLUDEDIR_LCR=/usr/include/openais/lcr +-INCLUDEDIR_SERVICE=/usr/include/openais/service +-MANDIR=/usr/share/man ++include Makefile.inc ++ ++SBINDIR=$(PREFIX)/sbin ++INCLUDEDIR=$(PREFIX)/include/openais ++INCLUDEDIR_TOTEM=$(PREFIX)/include/openais/totem ++INCLUDEDIR_LCR=$(PREFIX)/include/openais/lcr ++INCLUDEDIR_SERVICE=$(PREFIX)/include/openais/service ++MANDIR=$(PREFIX)/share/man + ETCDIR=/etc/ais +-LCRSODIR=/usr/libexec/lcrso + ARCH=$(shell uname -m) + + ifeq (,$(findstring 64,$(ARCH))) +-LIBDIR=/usr/lib/openais ++LIBDIR=$(PREFIX)/lib/openais + else +-LIBDIR=/usr/lib64/openais ++LIBDIR=$(PREFIX)/lib64/openais + endif + ifeq (s390,$(ARCH)) +-LIBDIR=/usr/lib/openais ++LIBDIR=$(PREFIX)/lib/openais + endif + ifeq (s390x,$(ARCH)) +-LIBDIR=/usr/lib64/openais ++LIBDIR=$(PREFIX)/lib64/openais + endif + ifeq (ia64,$(ARCH)) +-LIBDIR=/usr/lib/openais ++LIBDIR=$(PREFIX)/lib/openais + endif + + all: +@@ -105,29 +105,29 @@ + ln -sf libcfg.so.2.0.0 lib/libcfg.so.2 + ln -sf libtotem_pg.so.2.0.0 exec/libtotem_pg.so.2 + +- cp -a lib/libais.so $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaAmf.so $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaClm.so $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaCkpt.so $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaEvt.so $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaLck.so $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaMsg.so $(DESTDIR)$(LIBDIR) +- cp -a lib/libevs.so $(DESTDIR)$(LIBDIR) +- cp -a lib/libcpg.so $(DESTDIR)$(LIBDIR) +- cp -a lib/libcfg.so $(DESTDIR)$(LIBDIR) +- cp -a exec/libtotem_pg.so $(DESTDIR)$(LIBDIR) +- +- cp -a lib/libais.so.2 $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaAmf.so.2 $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaClm.so.2 $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaCkpt.so.2 $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaEvt.so.2 $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaLck.so.2 $(DESTDIR)$(LIBDIR) +- cp -a lib/libSaMsg.so.2 $(DESTDIR)$(LIBDIR) +- cp -a lib/libevs.so.2 $(DESTDIR)$(LIBDIR) +- cp -a lib/libcpg.so.2 $(DESTDIR)$(LIBDIR) +- cp -a lib/libcfg.so.2 $(DESTDIR)$(LIBDIR) +- cp -a exec/libtotem_pg.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libais.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaAmf.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaClm.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaCkpt.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaEvt.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaLck.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaMsg.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libevs.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libcpg.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libcfg.so $(DESTDIR)$(LIBDIR) ++ $(CP) -a exec/libtotem_pg.so $(DESTDIR)$(LIBDIR) ++ ++ $(CP) -a lib/libais.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaAmf.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaClm.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaCkpt.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaEvt.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaLck.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libSaMsg.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libevs.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libcpg.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a lib/libcfg.so.2 $(DESTDIR)$(LIBDIR) ++ $(CP) -a exec/libtotem_pg.so.2 $(DESTDIR)$(LIBDIR) + + install -m 755 lib/libais.so.2.* $(DESTDIR)$(LIBDIR) + install -m 755 lib/libSaAmf.so.2.* $(DESTDIR)$(LIBDIR) diff --git a/sys-cluster/openais/files/openais-0.80.3-Makefile.inc-VARS.patch b/sys-cluster/openais/files/openais-0.80.3-Makefile.inc-VARS.patch new file mode 100644 index 000000000000..e5c3e4d51251 --- /dev/null +++ b/sys-cluster/openais/files/openais-0.80.3-Makefile.inc-VARS.patch @@ -0,0 +1,20 @@ +--- openais-0.80.3/Makefile.inc.orig 2008-11-18 19:31:13.000000000 +0100 ++++ openais-0.80.3/Makefile.inc 2008-11-18 19:32:11.000000000 +0100 +@@ -29,12 +29,17 @@ + # THE POSSIBILITY OF SUCH DAMAGE. + # Basic OS detection + # ++CP=cp ++DESTDIR= ++PREFIX=/usr + UNAME=$(shell uname) ++LCRSODIR=$(PREFIX)/libexec/lcrso + + ifeq "$(UNAME)" "Linux" + OPENAIS_COMPAT=LINUX + endif + ifeq "$(UNAME)" "Darwin" ++ CP=rsync + OPENAIS_COMPAT=DARWIN + endif + ifneq "" "$(findstring BSD,$(UNAME))" diff --git a/sys-cluster/openais/files/openais-0.80.3-r1661.patch b/sys-cluster/openais/files/openais-0.80.3-r1661.patch new file mode 100644 index 000000000000..9aef9687f96e --- /dev/null +++ b/sys-cluster/openais/files/openais-0.80.3-r1661.patch @@ -0,0 +1,6310 @@ +diff -uNr openais-0.80.3/CHANGELOG openais-0.80.3-r1661/CHANGELOG +--- openais-0.80.3/CHANGELOG 2007-06-26 13:36:38.000000000 +0200 ++++ openais-0.80.3-r1661/CHANGELOG 2008-11-17 15:54:04.030604165 +0100 +@@ -1,555 +1,4 @@ + ------------------------------------------------------------------------ +-r1400 | sdake | 2007-06-26 03:13:19 -0700 (Tue, 26 Jun 2007) | 2 lines +- +-Fix compile warning/error on some platforms. +- +------------------------------------------------------------------------- +-r1396 | sdake | 2007-06-25 01:42:58 -0700 (Mon, 25 Jun 2007) | 2 lines +- +-Update testckpt program to properly test the checkpoint system. +- +------------------------------------------------------------------------- +-r1395 | sdake | 2007-06-25 01:40:45 -0700 (Mon, 25 Jun 2007) | 3 lines +- +-Fix problem where sometimes when a checkpoint section is expired the timer +-also fires at the same time resulting in a warning. +- +------------------------------------------------------------------------- +-r1394 | sdake | 2007-06-24 20:11:10 -0700 (Sun, 24 Jun 2007) | 2 lines +- +-Add cpg_context_get and cpg_context_set man pages. +- +------------------------------------------------------------------------- +-r1393 | sdake | 2007-06-24 20:09:31 -0700 (Sun, 24 Jun 2007) | 2 lines +- +-Add cpg_context_get and cpg_context_set api calls. +- +------------------------------------------------------------------------- +-r1392 | sdake | 2007-06-24 20:07:30 -0700 (Sun, 24 Jun 2007) | 2 lines +- +-install timer.h file for external service handlers. +- +------------------------------------------------------------------------- +-r1390 | sdake | 2007-06-24 19:52:58 -0700 (Sun, 24 Jun 2007) | 2 lines +- +-Tests cpg_local_get functionality. +- +------------------------------------------------------------------------- +-r1389 | sdake | 2007-06-24 19:22:54 -0700 (Sun, 24 Jun 2007) | 3 lines +- +-Track timers based upon nanoseconds since epoch and add absolute and relative +-timers. +- +------------------------------------------------------------------------- +-r1387 | sdake | 2007-06-23 23:33:09 -0700 (Sat, 23 Jun 2007) | 2 lines +- +-Update all copyright and email addresses in source tree. +- +------------------------------------------------------------------------- +-r1382 | sdake | 2007-06-12 10:43:15 -0700 (Tue, 12 Jun 2007) | 2 lines +- +-Add cpg_local_get to get the local node id. +- +------------------------------------------------------------------------- +-r1372 | sdake | 2007-05-17 13:37:43 -0700 (Thu, 17 May 2007) | 3 lines +- +-on 32 bit platforms, the message source conn info could have uninitialized +-values. +- +------------------------------------------------------------------------- +-r1369 | sdake | 2007-04-24 16:11:56 -0700 (Tue, 24 Apr 2007) | 4 lines +- +-This bug was posted via bugzilla and a patch was attached. Essentially +-the checkpoint retention duration was being verified on a checkpoint +-open which should be ignored. +- +------------------------------------------------------------------------- +-r1368 | sdake | 2007-04-24 16:11:08 -0700 (Tue, 24 Apr 2007) | 2 lines +- +-Fix section iteration size comparison +- +------------------------------------------------------------------------- +-r1364 | sdake | 2007-04-24 16:05:56 -0700 (Tue, 24 Apr 2007) | 2 lines +- +-Have totemsrp use the proper ring id file. +- +------------------------------------------------------------------------- +-r1363 | sdake | 2007-04-24 16:05:38 -0700 (Tue, 24 Apr 2007) | 2 lines +- +-Fix references to evs_initialize in cpg_initialize man pages +- +------------------------------------------------------------------------- +-r1357 | sdake | 2007-03-21 13:07:58 -0700 (Wed, 21 Mar 2007) | 2 lines +- +-Fix some type errors within the AMF service. +- +------------------------------------------------------------------------- +-r1356 | sdake | 2007-03-21 13:07:25 -0700 (Wed, 21 Mar 2007) | 2 lines +- +-Patch to fix some documentation errors relating to CPG service. +- +------------------------------------------------------------------------- +-r1344 | sdake | 2006-12-18 09:08:02 -0700 (Mon, 18 Dec 2006) | 2 lines +- +-Fix compile warnings about unused variables. +- +------------------------------------------------------------------------- +-r1340 | sdake | 2006-12-18 08:02:48 -0700 (Mon, 18 Dec 2006) | 2 lines +- +-Fix unaligned access in totem ip on IA64 architecture. +- +------------------------------------------------------------------------- +-r1339 | sdake | 2006-12-12 11:54:51 -0700 (Tue, 12 Dec 2006) | 2 lines +- +-Convert some spaces to tabs. +- +------------------------------------------------------------------------- +-r1338 | sdake | 2006-12-12 11:54:25 -0700 (Tue, 12 Dec 2006) | 2 lines +- +-Destroy mutex after it is done being used instead of before it is done being used. +- +------------------------------------------------------------------------- +-r1337 | sdake | 2006-12-12 11:45:25 -0700 (Tue, 12 Dec 2006) | 2 lines +- +-Remove return and use pthread_exit instead. +- +------------------------------------------------------------------------- +-r1334 | sdake | 2006-12-12 11:38:51 -0700 (Tue, 12 Dec 2006) | 2 lines +- +-Backport comparison of 0 and NULL. +- +------------------------------------------------------------------------- +-r1330 | sdake | 2006-12-12 11:13:54 -0700 (Tue, 12 Dec 2006) | 2 lines +- +-Fix argument off by one in instiation of AMF components. +- +------------------------------------------------------------------------- +-r1329 | sdake | 2006-12-12 11:11:07 -0700 (Tue, 12 Dec 2006) | 2 lines +- +-Remove unnecessary strdup. +- +------------------------------------------------------------------------- +-r1325 | sdake | 2006-12-12 10:56:17 -0700 (Tue, 12 Dec 2006) | 2 lines +- +-Change rundir to /var/lib/openais. +- +------------------------------------------------------------------------- +-r1323 | pcaulfie | 2006-12-12 10:45:50 -0700 (Tue, 12 Dec 2006) | 2 lines +- +-Fix ordering of CPG join messages. +- +------------------------------------------------------------------------- +-r1319 | sdake | 2006-12-05 09:34:10 -0700 (Tue, 05 Dec 2006) | 2 lines +- +-Increase size of default outbound message queue. +- +------------------------------------------------------------------------- +-r1316 | sdake | 2006-11-29 14:30:58 -0700 (Wed, 29 Nov 2006) | 2 lines +- +-Improvements on segfault logging. +- +------------------------------------------------------------------------- +-r1315 | sdake | 2006-11-29 13:56:17 -0700 (Wed, 29 Nov 2006) | 2 lines +- +-Fix compile error in libcpg +- +------------------------------------------------------------------------- +-r1314 | sdake | 2006-11-29 13:47:40 -0700 (Wed, 29 Nov 2006) | 2 lines +- +-Change rundir to /var/openais otherwise core files and ringid file is deleted +- +------------------------------------------------------------------------- +-r1313 | sdake | 2006-11-29 13:35:32 -0700 (Wed, 29 Nov 2006) | 2 lines +- +-Flow control fixes for the CPG service. +- +------------------------------------------------------------------------- +-r1312 | fthomas | 2006-11-23 02:10:19 -0700 (Thu, 23 Nov 2006) | 1 line +- +-correct incorrect commit that must use SA_AIS_ERR_LIBRARY instead of ERR_LIBRARY +------------------------------------------------------------------------- +-r1311 | fthomas | 2006-11-23 01:49:21 -0700 (Thu, 23 Nov 2006) | 1 line +- +-handle case where POLLHUP or POLLERR are not supported by OS +------------------------------------------------------------------------- +-r1309 | fthomas | 2006-11-16 10:36:52 -0700 (Thu, 16 Nov 2006) | 1 line +- +-set default downcheck value to 1000ms +------------------------------------------------------------------------- +-r1308 | fthomas | 2006-11-16 10:34:44 -0700 (Thu, 16 Nov 2006) | 1 line +- +-remove invalid code / warnings detected by Intel compiler +------------------------------------------------------------------------- +-r1307 | sdake | 2006-11-15 00:23:10 -0700 (Wed, 15 Nov 2006) | 2 lines +- +-Remove flow control compile warning. +- +------------------------------------------------------------------------- +-r1306 | sdake | 2006-11-15 00:21:02 -0700 (Wed, 15 Nov 2006) | 2 lines +- +-Make clean for makefiles improvement to actually remove all files. +- +------------------------------------------------------------------------- +-r1305 | sdake | 2006-11-15 00:19:37 -0700 (Wed, 15 Nov 2006) | 2 lines +- +-Set scheduler SCHED_RR to max priority available in the system. +- +------------------------------------------------------------------------- +-r1300 | sdake | 2006-11-13 10:38:13 -0700 (Mon, 13 Nov 2006) | 2 lines +- +-Improve behavior of flow control of CPG service during configuration changes. +- +------------------------------------------------------------------------- +-r1296 | sdake | 2006-11-09 05:34:08 -0700 (Thu, 09 Nov 2006) | 2 lines +- +-Remove compile warnings. +- +------------------------------------------------------------------------- +-r1295 | sdake | 2006-11-09 05:26:56 -0700 (Thu, 09 Nov 2006) | 5 lines +- +-the totem membership protocol was changed to match specificatoins. The sending +-join messages now use the local seq id of he ring instead of the maximum seqidsrreceived. This resuls in running of the mp5 test for several hours. Also +-the consensus timeout was increased to allow for the membership protocol to +-form a proper membership in network overload situations. +- +------------------------------------------------------------------------- +-r1294 | sdake | 2006-11-08 18:33:06 -0700 (Wed, 08 Nov 2006) | 3 lines +- +-Modify location of ringid file and create and chdir to +-/var/run/openais directory so cores are saved there. +- +------------------------------------------------------------------------- +-r1293 | sdake | 2006-11-08 14:48:20 -0700 (Wed, 08 Nov 2006) | 2 lines +- +-Flush output of debug messages on exit or segv. +- +------------------------------------------------------------------------- +-r1288 | sdake | 2006-11-04 15:22:02 -0700 (Sat, 04 Nov 2006) | 2 lines +- +-Ported revision 1287 - updated README.devmap +- +------------------------------------------------------------------------- +-r1286 | sdake | 2006-11-03 16:48:53 -0700 (Fri, 03 Nov 2006) | 3 lines +- +-Fix problem where checkpoints can't be written afer an unlink opeation occurs +-and a new node is started. +- +------------------------------------------------------------------------- +-r1284 | sdake | 2006-10-24 13:31:15 -0700 (Tue, 24 Oct 2006) | 3 lines +- +-Checkpoint section variables were not properly initialized resulting in +-segfaults. +- +------------------------------------------------------------------------- +-r1283 | sdake | 2006-10-24 08:39:45 -0700 (Tue, 24 Oct 2006) | 2 lines +- +-Fix memory leaks. +- +------------------------------------------------------------------------- +-r1282 | sdake | 2006-10-24 04:28:18 -0700 (Tue, 24 Oct 2006) | 2 lines +- +-New generation checkpoint synchronization state machine. +- +------------------------------------------------------------------------- +-r1279 | sdake | 2006-10-23 21:08:57 -0700 (Mon, 23 Oct 2006) | 2 lines +- +-Call abort in synchronization service when processing is interrupted. +- +------------------------------------------------------------------------- +-r1278 | sdake | 2006-10-23 20:48:41 -0700 (Mon, 23 Oct 2006) | 2 lines +- +-Patch testckpt to use proper section id size. +- +------------------------------------------------------------------------- +-r1277 | sdake | 2006-10-23 20:36:40 -0700 (Mon, 23 Oct 2006) | 2 lines +- +-Replace spaces with tabs on two lines. +- +------------------------------------------------------------------------- +-r1276 | sdake | 2006-10-23 20:29:12 -0700 (Mon, 23 Oct 2006) | 2 lines +- +-remove makefile debug added accidentally in last patch +- +------------------------------------------------------------------------- +-r1275 | sdake | 2006-10-23 20:28:26 -0700 (Mon, 23 Oct 2006) | 2 lines +- +-pthread_mutex_destroy cleanup patch from Fabien +- +------------------------------------------------------------------------- +-r1271 | sdake | 2006-10-19 13:38:22 -0700 (Thu, 19 Oct 2006) | 2 lines +- +-Fix errors in ia64 alignment. +- +------------------------------------------------------------------------- +-r1270 | sdake | 2006-10-19 10:43:39 -0700 (Thu, 19 Oct 2006) | 2 lines +- +-Resolve IPC segfault. +- +------------------------------------------------------------------------- +-r1269 | sdake | 2006-10-18 16:10:34 -0700 (Wed, 18 Oct 2006) | 2 lines +- +-Specific stack size for ia64 architectures required. +- +------------------------------------------------------------------------- +-r1268 | sdake | 2006-10-18 16:09:59 -0700 (Wed, 18 Oct 2006) | 3 lines +- +-Align totem deliveries on 4 byte boudnaries to avoid segfaults and warnings +-on sparc and ia64 architectures. +- +------------------------------------------------------------------------- +-r1267 | sdake | 2006-10-16 09:07:01 -0700 (Mon, 16 Oct 2006) | 2 lines +- +-Rework of the checkpoint synchronization system. +- +------------------------------------------------------------------------- +-r1265 | sdake | 2006-10-12 15:24:36 -0700 (Thu, 12 Oct 2006) | 2 lines +- +-Only originate one regular token. +- +------------------------------------------------------------------------- +-r1264 | sdake | 2006-10-12 15:23:26 -0700 (Thu, 12 Oct 2006) | 3 lines +- +-If the failed_list has zero entries, don't add it as an iovector in join +-messages. +- +------------------------------------------------------------------------- +-r1263 | sdake | 2006-10-12 15:22:53 -0700 (Thu, 12 Oct 2006) | 3 lines +- +-Use the fullset variable instead of the local variable j to make easier code +-reading. +- +------------------------------------------------------------------------- +-r1262 | sdake | 2006-10-12 15:22:09 -0700 (Thu, 12 Oct 2006) | 2 lines +- +-Set the ring sequence number according to the totem specificatoins. +- +------------------------------------------------------------------------- +-r1261 | sdake | 2006-10-12 15:21:42 -0700 (Thu, 12 Oct 2006) | 2 lines +- +-Cleanup the way the memb_index variable is handled in the commit token +- +------------------------------------------------------------------------- +-r1260 | sdake | 2006-10-12 15:21:04 -0700 (Thu, 12 Oct 2006) | 3 lines +- +-Allocate the retransmission token in instance_initialize instead of +-totemsrp_initialize +- +------------------------------------------------------------------------- +-r1258 | sdake | 2006-10-09 00:43:45 -0700 (Mon, 09 Oct 2006) | 2 lines +- +-Accept commit token in proper cases. +- +------------------------------------------------------------------------- +-r1257 | sdake | 2006-10-09 00:43:04 -0700 (Mon, 09 Oct 2006) | 2 lines +- +-Fix subset operation to work properly. +- +------------------------------------------------------------------------- +-r1256 | sdake | 2006-10-09 00:42:36 -0700 (Mon, 09 Oct 2006) | 2 lines +- +-Remove some extra debug logging output when in DEBUG mode that is not needed. +- +------------------------------------------------------------------------- +-r1252 | sdake | 2006-10-04 21:11:40 -0700 (Wed, 04 Oct 2006) | 2 lines +- +-Print out left members properly from totemsrp. +- +------------------------------------------------------------------------- +-r1248 | sdake | 2006-09-28 11:49:00 -0700 (Thu, 28 Sep 2006) | 2 lines +- +-Set the proper size of responses to cpg_mcast messages. +- +------------------------------------------------------------------------- +-r1246 | sdake | 2006-09-27 15:57:03 -0700 (Wed, 27 Sep 2006) | 2 lines +- +-Flow control part 2 patch. +- +------------------------------------------------------------------------- +-r1245 | sdake | 2006-09-25 02:41:57 -0700 (Mon, 25 Sep 2006) | 2 lines +- +-Add cpgbench tool and group wide flow control services for the cpg service. +- +------------------------------------------------------------------------- +-r1230 | fthomas | 2006-08-28 03:12:25 -0700 (Mon, 28 Aug 2006) | 1 line +- +-add missing include for assert +------------------------------------------------------------------------- +-r1224 | sdake | 2006-08-21 21:40:26 -0700 (Mon, 21 Aug 2006) | 2 lines +- +-Fix up printing of SaNameT and mar_name_t in case it is not null terminated. +- +------------------------------------------------------------------------- +-r1223 | sdake | 2006-08-21 21:39:08 -0700 (Mon, 21 Aug 2006) | 2 lines +- +-Fix checkpoints with write size of zero to return INVALID PARAM error code +- +------------------------------------------------------------------------- +-r1217 | sdake | 2006-08-15 21:35:15 -0700 (Tue, 15 Aug 2006) | 2 lines +- +-Remove invalid commit. +- +------------------------------------------------------------------------- +-r1213 | sdake | 2006-08-15 21:22:30 -0700 (Tue, 15 Aug 2006) | 2 lines +- +-Return ERR_TIMEOUT on zero timeout parameter to saEvtEventChannelOpen. +- +------------------------------------------------------------------------- +-r1212 | sdake | 2006-08-15 18:22:40 -0700 (Tue, 15 Aug 2006) | 2 lines +- +-Return ERR_TIMEOUT if timeout parameter is zero in saEvtChannelOpen. +- +------------------------------------------------------------------------- +-r1210 | sdake | 2006-08-15 17:45:14 -0700 (Tue, 15 Aug 2006) | 2 lines +- +-Add more scalability by adding a new send_join parameter to openais. +- +------------------------------------------------------------------------- +-r1209 | sdake | 2006-08-15 17:37:54 -0700 (Tue, 15 Aug 2006) | 2 lines +- +-Remove warning about assert being undefined by including assert.h. +- +------------------------------------------------------------------------- +-r1205 | sdake | 2006-08-15 17:03:45 -0700 (Tue, 15 Aug 2006) | 2 lines +- +-Fix hash collision in cpg service. +- +------------------------------------------------------------------------- +-r1204 | sdake | 2006-08-15 16:57:44 -0700 (Tue, 15 Aug 2006) | 2 lines +- +-Install proper shared object files for clm service. +- +------------------------------------------------------------------------- +-r1203 | sdake | 2006-08-15 16:55:44 -0700 (Tue, 15 Aug 2006) | 2 lines +- +-Improve recovery state data output. +- +------------------------------------------------------------------------- +-r1202 | sdake | 2006-08-15 16:53:01 -0700 (Tue, 15 Aug 2006) | 3 lines +- +-Improve gather notifications so user knows where gather was entered from. This +-is useful for debugging. +- +------------------------------------------------------------------------- +-r1201 | sdake | 2006-08-15 16:51:56 -0700 (Tue, 15 Aug 2006) | 2 lines +- +-This cleans up some of the error reporting of the testckpt tool. +- +------------------------------------------------------------------------- +-r1198 | sdake | 2006-08-08 08:54:02 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Use braces in the totemip code. +- +------------------------------------------------------------------------- +-r1197 | sdake | 2006-08-08 08:52:49 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Ensure compile with GIVE_INFO gives proper information. +- +------------------------------------------------------------------------- +-r1196 | sdake | 2006-08-08 08:52:05 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Resend the commit token if it is lost +- +------------------------------------------------------------------------- +-r1195 | sdake | 2006-08-08 08:51:03 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Move SYNC output data to DEBUG mode. +- +------------------------------------------------------------------------- +-r1194 | sdake | 2006-08-08 08:49:31 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Give better user error messages when token is lost. +- +------------------------------------------------------------------------- +-r1193 | sdake | 2006-08-08 08:41:44 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Fix checkpoint synchronization. +- +------------------------------------------------------------------------- +-r1192 | sdake | 2006-08-08 08:41:22 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Move notice debug outputs in checkpoint service to debug outputs. +- +------------------------------------------------------------------------- +-r1191 | sdake | 2006-08-08 08:40:05 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Use GNU formatting for printf output +- +------------------------------------------------------------------------- +-r1190 | sdake | 2006-08-08 08:38:08 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Clean header includes from swab code. +- +------------------------------------------------------------------------- +-r1189 | sdake | 2006-08-08 08:35:42 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Fix endian marshalling in YKD service. +- +------------------------------------------------------------------------- +-r1188 | sdake | 2006-08-08 08:35:00 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Cleanup lcr_ifact code. +- +------------------------------------------------------------------------- +-r1187 | sdake | 2006-08-08 08:34:36 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Fix endian marshalling for eventing service. +- +------------------------------------------------------------------------- +-r1186 | sdake | 2006-08-08 08:34:10 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Add endian conversion for evs service. +- +------------------------------------------------------------------------- +-r1185 | sdake | 2006-08-08 08:33:13 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Fix marshalling with CPG service. +- +------------------------------------------------------------------------- +-r1184 | sdake | 2006-08-08 08:32:33 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Fix endian marshalling with clm service. +- +------------------------------------------------------------------------- +-r1183 | sdake | 2006-08-08 08:32:04 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Set proper socket for IPV6 membership add +- +------------------------------------------------------------------------- +-r1182 | sdake | 2006-08-08 08:30:40 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Fix processor count in EVS service so EVS service operates properly. +- +------------------------------------------------------------------------- +-r1181 | sdake | 2006-08-08 08:27:05 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-fix ckpt-rd and ckpt-wr test applications +- +------------------------------------------------------------------------- +-r1180 | sdake | 2006-08-08 08:23:33 -0700 (Tue, 08 Aug 2006) | 2 lines +- +-Use worker threads for debug output +- +------------------------------------------------------------------------- +-r1179 | sdake | 2006-08-07 15:50:58 -0700 (Mon, 07 Aug 2006) | 2 lines +- +-Unlink header prototype incorrect. +- +------------------------------------------------------------------------- +-r1173 | sdake | 2006-08-02 22:31:34 -0700 (Wed, 02 Aug 2006) | 2 lines +- +-Ensure sync_activate is only called once +- +------------------------------------------------------------------------- +-r1155 | sdake | 2006-07-24 22:18:52 -0700 (Mon, 24 Jul 2006) | 2 lines +- +-Added whitetank branch. +- +------------------------------------------------------------------------- +-r1153 | sdake | 2006-07-23 18:36:18 -0700 (Sun, 23 Jul 2006) | 2 lines +- +-Release of version 0.80 First Whitetank release +- +------------------------------------------------------------------------- + r1152 | sdake | 2006-07-23 18:34:17 -0700 (Sun, 23 Jul 2006) | 2 lines + + Allow build type of COVERAGE for code coverage analysis +diff -uNr openais-0.80.3/Makefile openais-0.80.3-r1661/Makefile +--- openais-0.80.3/Makefile 2007-06-25 05:07:30.000000000 +0200 ++++ openais-0.80.3-r1661/Makefile 2008-11-17 15:54:04.030604165 +0100 +@@ -196,4 +196,4 @@ + install -m 644 man/*.8 $(DESTDIR)$(MANDIR)/man8 + + doxygen: +- doxygen ++ mkdir -p doc/api && doxygen +diff -uNr openais-0.80.3/README.devmap openais-0.80.3-r1661/README.devmap +--- openais-0.80.3/README.devmap 2006-11-04 23:22:02.000000000 +0100 ++++ openais-0.80.3-r1661/README.devmap 2008-11-17 15:54:04.030604165 +0100 +@@ -1221,3 +1221,91 @@ + for other people. + + Have fun! ++ ++--- ++IPC state machine ++ ++lib_exit_fn may not use openais_response_send or openais_dispatch_send ++ ++state INITIALIZING ++------------------ ++receive response end of a library request ++ create conn_io data structure ++ if the connection's UID/GID is invalid ++ conn_io_disconnect ++ send response to conn_io with conn_io's address ++ set conn_io refcnt to 1 ++ ++receive dispatch end of a library connection with response end conn_io address ++ find matching connection ++ if the connection's UID/GID is invalid ++ conn_io_disconnect ++ send reponse to conn_io ++ create conn_info data structure ++ if conn_io response end is valid ++ store dispatch end of conn_io into conn_info data structure ++ store response conn_io into conn_info data structure ++ set conn_io refcnt to 1 ++ call lib_init_fn for service type ++ set conn_info refcnt to 1 ++ set state to ACTIVE ++ ++event response disconnects and conn_info not bound ++ disconnect connection ++event receive connects and response connection not found ++ disconnect dispatch ++event no dispatch connection within 5 seconds ++ disconnect dispatch ++event disconnect_request ++ set state to DISCONNECT_REQUESTED ++ decrement response conn_io refcnt by 1 ++ decrement dispatch conn_io refcnt by 1 ++ ++state ACTIVE ++------------ ++do { ++ increment conn_io refcnt by 1 ++ poll ++ if invalid poll set state internal_disconnect_request ++ dispatch library handler functions ++ flush any output that can be flushed ++ decrement conn_io refcnt by 1 ++ if state set to DISCONNECT_REQUESTED ++ execute algorithm for disconnect requested state ++} ++ ++event internal_disconnect_request ++ set state to DISCONNECT_REQUESTED ++ decrement response conn_io refcnt by 1 ++ decrement dispatch conn_io refcnt by 1 ++event openais_conn_refcnt_increment ++ increase conn_info reference count by 1 ++event openais_conn_refcnt_decrement ++ decrease conn_info reference count by 1 ++ ++state DISCONNECT_REQUESTED ++-------------------------- ++if this is the response conn_io data ++do { ++ if response conn_io refcnt is 0 ++ destroy conn_io data structure ++ decrement conn_info reference count ++ exit thread ++ sleep configurable short duration ++} ++ ++if this is the dispatch conn_io data ++do { ++ if dispatch conn_io refcnt is 0 ++ call lib_exit_fn ++ if successful ++ destroy conn_io data structure ++ decrement conn_info reference count ++ exit thread ++ sleep configurable short duration ++} ++ ++when conn_info reference count equals 0 ++ free conn_info data structure ++ ++ +diff -uNr openais-0.80.3/exec/amf.c openais-0.80.3-r1661/exec/amf.c +--- openais-0.80.3/exec/amf.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/amf.c 2008-11-17 15:54:02.390605772 +0100 +@@ -480,7 +480,7 @@ + res_lib.header.id = MESSAGE_RES_AMF_COMPONENTREGISTER; + res_lib.header.size = sizeof (struct res_lib_amf_componentregister); + res_lib.header.error = error; +- openais_conn_send_response ( ++ openais_response_send ( + comp->conn, &res_lib, sizeof (struct res_lib_amf_componentregister)); + } + } +@@ -544,7 +544,7 @@ + res_lib.header.id = MESSAGE_RES_AMF_RESPONSE; + res_lib.header.size = sizeof (struct res_lib_amf_response); + res_lib.header.error = retval; +- openais_conn_send_response (comp->conn, &res_lib, sizeof (res_lib)); ++ openais_response_send (comp->conn, &res_lib, sizeof (res_lib)); + } + } + +@@ -583,7 +583,7 @@ + res_lib.header.id = MESSAGE_RES_AMF_COMPONENTREGISTER; + res_lib.header.size = sizeof (struct res_lib_amf_componentregister); + res_lib.header.error = SA_AIS_ERR_INVALID_PARAM; +- openais_conn_send_response ( ++ openais_response_send ( + conn, &res_lib, sizeof (struct res_lib_amf_componentregister)); + } + } +@@ -658,12 +658,13 @@ + res_lib.header.id = MESSAGE_RES_AMF_HEALTHCHECKSTART; + res_lib.header.size = sizeof (res_lib); + res_lib.header.error = error; +- openais_conn_send_response (conn, &res_lib, ++ openais_response_send (conn, &res_lib, + sizeof (struct res_lib_amf_healthcheckstart)); + } + + static void message_handler_req_lib_amf_healthcheckconfirm ( +- void *conn, void *msg) ++ void *conn, ++ void *msg) + { + struct req_lib_amf_healthcheckconfirm *req_lib = msg; + struct res_lib_amf_healthcheckconfirm res_lib; +@@ -683,7 +684,7 @@ + res_lib.header.id = MESSAGE_RES_AMF_HEALTHCHECKCONFIRM; + res_lib.header.size = sizeof (res_lib); + res_lib.header.error = error; +- openais_conn_send_response (conn, &res_lib, sizeof (res_lib)); ++ openais_response_send (conn, &res_lib, sizeof (res_lib)); + } + + static void message_handler_req_lib_amf_healthcheckstop ( +@@ -706,7 +707,7 @@ + res_lib.header.id = MESSAGE_RES_AMF_HEALTHCHECKSTOP; + res_lib.header.size = sizeof (res_lib); + res_lib.header.error = error; +- openais_conn_send_response (conn, &res_lib, sizeof (res_lib)); ++ openais_response_send (conn, &res_lib, sizeof (res_lib)); + } + + static void message_handler_req_lib_amf_hastateget (void *conn, void *msg) +@@ -732,7 +733,7 @@ + res_lib.header.size = sizeof (struct res_lib_amf_hastateget); + res_lib.header.error = error; + +- openais_conn_send_response (conn, &res_lib, ++ openais_response_send (conn, &res_lib, + sizeof (struct res_lib_amf_hastateget)); + } + +@@ -788,7 +789,7 @@ + if (amfProtectionGroup) { + res_lib_amf_protectiongrouptrack.header.error = SA_AIS_OK; + } +- openais_conn_send_response (conn, &res_lib_amf_protectiongrouptrack, ++ openais_response_send (conn, &res_lib_amf_protectiongrouptrack, + sizeof (struct res_lib_amf_protectiongrouptrack)); + + if (amfProtectionGroup && +@@ -848,7 +849,7 @@ + if (track) { + res_lib_amf_protectiongrouptrackstop.header.error = SA_AIS_OK; + } +- openais_conn_send_response (conn, &res_lib_amf_protectiongrouptrackstop, ++ openais_response_send (conn, &res_lib_amf_protectiongrouptrackstop, + sizeof (struct res_lib_amf_protectiongrouptrackstop)); + + #endif +@@ -896,7 +897,7 @@ + res_lib.header.size = sizeof (struct res_lib_amf_componenterrorreport); + res_lib.header.id = MESSAGE_RES_AMF_COMPONENTERRORREPORT; + res_lib.header.error = SA_AIS_ERR_NOT_EXIST; +- openais_conn_send_response (conn, &res_lib, ++ openais_response_send (conn, &res_lib, + sizeof (struct res_lib_amf_componenterrorreport)); + } + } +@@ -963,7 +964,7 @@ + res_lib.header.id = MESSAGE_RES_AMF_RESPONSE; + res_lib.header.size = sizeof (struct res_lib_amf_response); + res_lib.header.error = retval; +- openais_conn_send_response (conn, &res_lib, sizeof (res_lib)); ++ openais_response_send (conn, &res_lib, sizeof (res_lib)); + } + } + +diff -uNr openais-0.80.3/exec/amfcomp.c openais-0.80.3-r1661/exec/amfcomp.c +--- openais-0.80.3/exec/amfcomp.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/amfcomp.c 2008-11-17 15:54:02.380604445 +0100 +@@ -547,8 +547,8 @@ + AMF_RESPONSE_COMPONENTTERMINATECALLBACK, + component_terminate_callback_data); + +- openais_conn_send_response ( +- openais_conn_partner_get (comp->conn), ++ openais_dispatch_send ( ++ comp->conn, + &res_lib, + sizeof (struct res_lib_amf_componentterminatecallback)); + +@@ -817,8 +817,8 @@ + + res_lib_amf_csiremovecallback.csiFlags = 0; + +- openais_conn_send_response ( +- openais_conn_partner_get (comp->conn), ++ openais_dispatch_send ( ++ comp->conn, + &res_lib_amf_csiremovecallback, + sizeof (struct res_lib_amf_csiremovecallback)); + } +@@ -1011,8 +1011,8 @@ + + TRACE8 ("sending healthcheck request to component %s", + res_lib.compName.value); +- openais_conn_send_response ( +- openais_conn_partner_get (healthcheck->comp->conn), ++ openais_dispatch_send ( ++ healthcheck->comp->conn, + &res_lib, sizeof (struct res_lib_amf_healthcheckcallback)); + } + +@@ -1117,8 +1117,7 @@ + res_lib->invocation = + invocation_create (AMF_RESPONSE_CSISETCALLBACK, csi_assignment); + +- openais_conn_send_response ( +- openais_conn_partner_get (comp->conn), res_lib, res_lib->header.size); ++ openais_dispatch_send (comp->conn, res_lib, res_lib->header.size); + + free(p); + } +@@ -1129,11 +1128,14 @@ + + if (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_RESTARTING) { + comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATED); +- } else if (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_INSTANTIATING) { ++ } else ++ if (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_INSTANTIATING) { + amf_comp_operational_state_set (comp, SA_AMF_OPERATIONAL_ENABLED); + comp_presence_state_set (comp, SA_AMF_PRESENCE_INSTANTIATED); +- } +- else { ++ } else ++ if (comp->saAmfCompPresenceState == SA_AMF_PRESENCE_UNINSTANTIATED) { ++ return SA_AIS_ERR_INVALID_PARAM; ++ } else { + assert (0); + } + +@@ -1151,7 +1153,7 @@ + res_lib.header.size = sizeof (struct res_lib_amf_componenterrorreport); + res_lib.header.id = MESSAGE_RES_AMF_COMPONENTERRORREPORT; + res_lib.header.error = SA_AIS_OK; +- openais_conn_send_response (comp->conn, &res_lib, sizeof (res_lib)); ++ openais_dispatch_send (comp->conn, &res_lib, sizeof (res_lib)); + } + + /* report to SU and let it handle the problem */ +diff -uNr openais-0.80.3/exec/cfg.c openais-0.80.3-r1661/exec/cfg.c +--- openais-0.80.3/exec/cfg.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/cfg.c 2008-11-17 15:54:02.370604375 +0100 +@@ -268,7 +268,7 @@ + res_lib_cfg_ringreenable.header.id = MESSAGE_RES_CFG_RINGREENABLE; + res_lib_cfg_ringreenable.header.size = sizeof (struct res_lib_cfg_ringreenable); + res_lib_cfg_ringreenable.header.error = SA_AIS_OK; +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_cfg_ringreenable->source.conn, + &res_lib_cfg_ringreenable, + sizeof (struct res_lib_cfg_ringreenable)); +@@ -298,7 +298,7 @@ + res_lib_cfg_ringstatusget.header.error = SA_AIS_OK; + + totempg_ifaces_get ( +- this_ip->nodeid, ++ totempg_my_nodeid_get(), + interfaces, + &status, + &iface_count); +@@ -312,7 +312,7 @@ + strcpy ((char *)&res_lib_cfg_ringstatusget.interface_name[i], + totem_ip_string); + } +- openais_conn_send_response ( ++ openais_response_send ( + conn, + &res_lib_cfg_ringstatusget, + sizeof (struct res_lib_cfg_ringstatusget)); +diff -uNr openais-0.80.3/exec/ckpt.c openais-0.80.3-r1661/exec/ckpt.c +--- openais-0.80.3/exec/ckpt.c 2007-06-26 13:16:50.000000000 +0200 ++++ openais-0.80.3-r1661/exec/ckpt.c 2008-11-17 15:54:02.390605772 +0100 +@@ -1,6 +1,6 @@ + /* + * Copyright (c) 2003-2006 MontaVista Software, Inc. +- * Copyright (c) 2006-2007 Red Hat, Inc. ++ * Copyright (c) 2006-2008 Red Hat, Inc. + * + * All rights reserved. + * +@@ -65,6 +65,8 @@ + #include "totempg.h" + #include "print.h" + ++#define GLOBALID_CHECKPOINT_NAME "global_checkpoint_name_do_not_use_in_an_application" ++ + #define CKPT_MAX_SECTION_DATA_SEND (1024*400) + + enum ckpt_message_req_types { +@@ -92,6 +94,9 @@ + }; + + enum sync_state { ++ SYNC_STATE_NOT_STARTED, ++ SYNC_STATE_STARTED, ++ SYNC_STATE_GLOBALID, + SYNC_STATE_CHECKPOINT, + SYNC_STATE_REFCOUNT + }; +@@ -156,6 +161,7 @@ + + struct checkpoint { + struct list_head list; ++ struct list_head expiry_list; + mar_name_t name; + mar_uint32_t ckpt_id; + mar_ckpt_checkpoint_creation_attributes_t checkpoint_creation_attributes; +@@ -367,21 +373,27 @@ + + DECLARE_LIST_INIT(checkpoint_recovery_list_head); + ++DECLARE_LIST_INIT(my_checkpoint_expiry_list_head); ++ + static mar_uint32_t global_ckpt_id = 0; + +-static enum sync_state my_sync_state; ++static enum sync_state my_sync_state = SYNC_STATE_NOT_STARTED; + + static enum iteration_state my_iteration_state; + +-static struct list_head *my_iteration_state_checkpoint; ++static struct list_head *my_iteration_state_checkpoint_list; ++ ++static struct list_head *my_iteration_state_section_list; + +-static struct list_head *my_iteration_state_section; ++static unsigned int my_old_member_list[PROCESSOR_COUNT_MAX]; + +-static unsigned int my_member_list[PROCESSOR_COUNT_MAX]; ++static unsigned int my_old_member_list_entries = 0; + +-static unsigned int my_member_list_entries = 0; ++static unsigned int my_should_sync = 0; + +-static unsigned int my_lowest_nodeid = 0; ++static unsigned int my_token_callback_active = 0; ++ ++static void * my_token_callback_handle; + + struct checkpoint_cleanup { + struct list_head list; +@@ -756,51 +768,11 @@ + mar_refcount_set_t refcount_set[PROCESSOR_COUNT_MAX] __attribute__((aligned(8))); + }; + ++static int first_configuration = 1; ++ + /* + * Implementation + */ +- +-void clean_checkpoint_list(struct list_head *head) +-{ +- struct list_head *checkpoint_list; +- struct checkpoint *checkpoint; +- +- if (list_empty(head)) { +- log_printf (LOG_LEVEL_DEBUG, "clean_checkpoint_list: List is empty \n"); +- return; +- } +- +- checkpoint_list = head->next; +- while (checkpoint_list != head) { +- checkpoint = list_entry (checkpoint_list, +- struct checkpoint, list); +- assert (checkpoint > 0); +- +- /* +- * If checkpoint has been unlinked and this is the last reference, delete it +- */ +- if (checkpoint->unlinked && checkpoint->reference_count == 0) { +- log_printf (LOG_LEVEL_DEBUG,"clean_checkpoint_list: deallocating checkpoint %s.\n", +- checkpoint->name.value); +- checkpoint_list = checkpoint_list->next; +- checkpoint_release (checkpoint); +- continue; +- +- } +- else if (checkpoint->reference_count == 0) { +- log_printf (LOG_LEVEL_DEBUG, "clean_checkpoint_list: Starting timer to release checkpoint %s.\n", +- checkpoint->name.value); +- openais_timer_delete (checkpoint->retention_timer); +- openais_timer_add_duration ( +- checkpoint->checkpoint_creation_attributes.retention_duration, +- checkpoint, +- timer_function_retention, +- &checkpoint->retention_timer); +- } +- checkpoint_list = checkpoint_list->next; +- } +-} +- + static void ckpt_confchg_fn ( + enum totem_configuration_type configuration_type, + unsigned int *member_list, int member_list_entries, +@@ -809,40 +781,45 @@ + struct memb_ring_id *ring_id) + { + unsigned int i, j; ++ unsigned int lowest_nodeid; ++ ++ memcpy (&my_saved_ring_id, ring_id, ++ sizeof (struct memb_ring_id)); ++ if (configuration_type != TOTEM_CONFIGURATION_REGULAR) { ++ return; ++ } ++ if (my_sync_state != SYNC_STATE_NOT_STARTED) { ++ return; ++ } ++ ++ my_sync_state = SYNC_STATE_STARTED; ++ ++ my_should_sync = 0; + + /* +- * Determine lowest nodeid in old regular configuration for the +- * purpose of executing the synchronization algorithm ++ * Handle regular configuration + */ +- if (configuration_type == TOTEM_CONFIGURATION_TRANSITIONAL) { +- for (i = 0; i < left_list_entries; i++) { +- for (j = 0; j < my_member_list_entries; j++) { +- if (left_list[i] == my_member_list[j]) { +- my_member_list[j] = 0; ++ lowest_nodeid = 0xffffffff; ++ ++ for (i = 0; i < my_old_member_list_entries; i++) { ++ for (j = 0; j < member_list_entries; j++) { ++ if (my_old_member_list[i] == member_list[j]) { ++ if (lowest_nodeid > member_list[j]) { ++ lowest_nodeid = member_list[j]; + } + } +- } +- } +- +- my_lowest_nodeid = 0xffffffff; +- for (i = 0; i < my_member_list_entries; i++) { +- if ((my_member_list[i] != 0) && +- (my_member_list[i] < my_lowest_nodeid)) { +- +- my_lowest_nodeid = my_member_list[i]; + } + } ++ memcpy (my_old_member_list, member_list, ++ sizeof (unsigned int) * member_list_entries); ++ my_old_member_list_entries = member_list_entries; + +- /* +- * Handle regular configuration +- */ +- if (configuration_type == TOTEM_CONFIGURATION_REGULAR) { +- memcpy (my_member_list, member_list, +- sizeof (unsigned int) * member_list_entries); +- my_member_list_entries = member_list_entries; +- memcpy (&my_saved_ring_id, ring_id, +- sizeof (struct memb_ring_id)); ++ if ((first_configuration) || ++ (lowest_nodeid == totempg_my_nodeid_get())) { ++ ++ my_should_sync = 1; + } ++ first_configuration = 0; + } + + static struct checkpoint *checkpoint_find ( +@@ -1057,9 +1034,7 @@ + iovec.iov_base = (char *)&req_exec_ckpt_checkpointclose; + iovec.iov_len = sizeof (req_exec_ckpt_checkpointclose); + +- assert (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0); +- +- return (-1); ++ return (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED)); + } + + static int ckpt_exec_init_fn (struct objdb_iface_ver0 *objdb) +@@ -1301,6 +1276,7 @@ + checkpoint->unlinked = 0; + list_init (&checkpoint->list); + list_init (&checkpoint->sections_list_head); ++ list_init (&checkpoint->expiry_list); + list_add (&checkpoint->list, &checkpoint_list_head); + checkpoint->reference_count = 1; + checkpoint->retention_timer = 0; +@@ -1401,12 +1377,12 @@ + res_lib_ckpt_checkpointopenasync.ckpt_id = checkpoint->ckpt_id; + } + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_checkpointopen->source.conn, + &res_lib_ckpt_checkpointopenasync, + sizeof (struct res_lib_ckpt_checkpointopenasync)); +- openais_conn_send_response ( +- openais_conn_partner_get (req_exec_ckpt_checkpointopen->source.conn), ++ openais_dispatch_send ( ++ req_exec_ckpt_checkpointopen->source.conn, + &res_lib_ckpt_checkpointopenasync, + sizeof (struct res_lib_ckpt_checkpointopenasync)); + } else { +@@ -1420,7 +1396,7 @@ + } + res_lib_ckpt_checkpointopen.header.error = error; + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_checkpointopen->source.conn, + &res_lib_ckpt_checkpointopen, + sizeof (struct res_lib_ckpt_checkpointopen)); +@@ -1513,29 +1489,67 @@ + + } + +-void timer_function_retention (void *data) ++int callback_expiry (enum totem_callback_token_type type, void *data) + { + struct checkpoint *checkpoint = (struct checkpoint *)data; +- struct req_exec_ckpt_checkpointretentiondurationexpire req_exec_ckpt_checkpointretentiondurationexpire; ++ struct req_exec_ckpt_checkpointunlink req_exec_ckpt_checkpointunlink; + struct iovec iovec; ++ unsigned int res; ++ struct list_head *list; + +- checkpoint->retention_timer = 0; +- req_exec_ckpt_checkpointretentiondurationexpire.header.size = +- sizeof (struct req_exec_ckpt_checkpointretentiondurationexpire); +- req_exec_ckpt_checkpointretentiondurationexpire.header.id = +- SERVICE_ID_MAKE (CKPT_SERVICE, +- MESSAGE_REQ_EXEC_CKPT_CHECKPOINTRETENTIONDURATIONEXPIRE); ++ list = my_checkpoint_expiry_list_head.next; ++ while (!list_empty(&my_checkpoint_expiry_list_head)) { ++ checkpoint = list_entry (list, ++ struct checkpoint, expiry_list); + +- memcpy (&req_exec_ckpt_checkpointretentiondurationexpire.checkpoint_name, +- &checkpoint->name, +- sizeof (mar_name_t)); +- req_exec_ckpt_checkpointretentiondurationexpire.ckpt_id = +- checkpoint->ckpt_id; ++ if (checkpoint->reference_count == 0) { ++ req_exec_ckpt_checkpointunlink.header.size = ++ sizeof (struct req_exec_ckpt_checkpointunlink); ++ req_exec_ckpt_checkpointunlink.header.id = ++ SERVICE_ID_MAKE (CKPT_SERVICE, ++ MESSAGE_REQ_EXEC_CKPT_CHECKPOINTUNLINK); ++ ++ req_exec_ckpt_checkpointunlink.source.conn = 0; ++ req_exec_ckpt_checkpointunlink.source.nodeid = 0; ++ ++ memcpy (&req_exec_ckpt_checkpointunlink.checkpoint_name, ++ &checkpoint->name, ++ sizeof (mar_name_t)); ++ ++ iovec.iov_base = (char *)&req_exec_ckpt_checkpointunlink; ++ iovec.iov_len = sizeof (req_exec_ckpt_checkpointunlink); ++ ++ res = totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED); ++ if (res == -1) { ++ return (-1); ++ } ++ log_printf (LOG_LEVEL_DEBUG, ++ "Expiring checkpoint %s\n", ++ get_mar_name_t (&checkpoint->name)); ++ } + +- iovec.iov_base = (char *)&req_exec_ckpt_checkpointretentiondurationexpire; +- iovec.iov_len = sizeof (req_exec_ckpt_checkpointretentiondurationexpire); ++ list_del (&checkpoint->expiry_list); ++ list = my_checkpoint_expiry_list_head.next; ++ } ++ my_token_callback_active = 0; ++ return (0); ++} + +- assert (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED) == 0); ++void timer_function_retention (void *data) ++{ ++ struct checkpoint *checkpoint = (struct checkpoint *)data; ++ checkpoint->retention_timer = 0; ++ list_add (&checkpoint->expiry_list, &my_checkpoint_expiry_list_head); ++ ++ if (my_token_callback_active == 0) { ++ totempg_callback_token_create ( ++ &my_token_callback_handle, ++ TOTEM_CALLBACK_TOKEN_SENT, ++ 1, ++ callback_expiry, ++ NULL); ++ my_token_callback_active = 1; ++ } + } + + static void message_handler_req_exec_ckpt_checkpointclose ( +@@ -1593,8 +1607,10 @@ + res_lib_ckpt_checkpointclose.header.size = sizeof (struct res_lib_ckpt_checkpointclose); + res_lib_ckpt_checkpointclose.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTCLOSE; + res_lib_ckpt_checkpointclose.header.error = error; +- openais_conn_send_response (req_exec_ckpt_checkpointclose->source.conn, +- &res_lib_ckpt_checkpointclose, sizeof (struct res_lib_ckpt_checkpointclose)); ++ openais_response_send ( ++ req_exec_ckpt_checkpointclose->source.conn, ++ &res_lib_ckpt_checkpointclose, ++ sizeof (struct res_lib_ckpt_checkpointclose)); + } + + /* +@@ -1646,7 +1662,7 @@ + res_lib_ckpt_checkpointunlink.header.size = sizeof (struct res_lib_ckpt_checkpointunlink); + res_lib_ckpt_checkpointunlink.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTUNLINK; + res_lib_ckpt_checkpointunlink.header.error = error; +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_checkpointunlink->source.conn, + &res_lib_ckpt_checkpointunlink, + sizeof (struct res_lib_ckpt_checkpointunlink)); +@@ -1694,7 +1710,7 @@ + res_lib_ckpt_checkpointretentiondurationset.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTRETENTIONDURATIONSET; + res_lib_ckpt_checkpointretentiondurationset.header.error = error; + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_checkpointretentiondurationset->source.conn, + &res_lib_ckpt_checkpointretentiondurationset, + sizeof (struct res_lib_ckpt_checkpointretentiondurationset)); +@@ -1900,7 +1916,8 @@ + res_lib_ckpt_sectioncreate.header.id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONCREATE; + res_lib_ckpt_sectioncreate.header.error = error; + +- openais_conn_send_response (req_exec_ckpt_sectioncreate->source.conn, ++ openais_response_send ( ++ req_exec_ckpt_sectioncreate->source.conn, + &res_lib_ckpt_sectioncreate, + sizeof (struct res_lib_ckpt_sectioncreate)); + } +@@ -1965,7 +1982,7 @@ + res_lib_ckpt_sectiondelete.header.id = MESSAGE_RES_CKPT_CHECKPOINT_SECTIONDELETE; + res_lib_ckpt_sectiondelete.header.error = error; + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_sectiondelete->source.conn, + &res_lib_ckpt_sectiondelete, + sizeof (struct res_lib_ckpt_sectiondelete)); +@@ -2058,7 +2075,7 @@ + MESSAGE_RES_CKPT_CHECKPOINT_SECTIONEXPIRATIONTIMESET; + res_lib_ckpt_sectionexpirationtimeset.header.error = error; + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_sectionexpirationtimeset->source.conn, + &res_lib_ckpt_sectionexpirationtimeset, + sizeof (struct res_lib_ckpt_sectionexpirationtimeset)); +@@ -2168,7 +2185,7 @@ + MESSAGE_RES_CKPT_CHECKPOINT_SECTIONWRITE; + res_lib_ckpt_sectionwrite.header.error = error; + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_sectionwrite->source.conn, + &res_lib_ckpt_sectionwrite, + sizeof (struct res_lib_ckpt_sectionwrite)); +@@ -2265,7 +2282,7 @@ + MESSAGE_RES_CKPT_CHECKPOINT_SECTIONOVERWRITE; + res_lib_ckpt_sectionoverwrite.header.error = error; + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_sectionoverwrite->source.conn, + &res_lib_ckpt_sectionoverwrite, + sizeof (struct res_lib_ckpt_sectionoverwrite)); +@@ -2358,7 +2375,7 @@ + res_lib_ckpt_sectionread.data_read = section_size; + } + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_sectionread->source.conn, + &res_lib_ckpt_sectionread, + sizeof (struct res_lib_ckpt_sectionread)); +@@ -2369,7 +2386,7 @@ + if (error == SA_AIS_OK) { + char *sd; + sd = (char *)checkpoint_section->section_data; +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_ckpt_sectionread->source.conn, + &sd[req_exec_ckpt_sectionread->data_offset], + section_size); +@@ -2394,6 +2411,7 @@ + struct checkpoint_cleanup *checkpoint_cleanup; + struct list_head *list; + struct ckpt_pd *ckpt_pd = (struct ckpt_pd *)openais_conn_private_data_get (conn); ++ unsigned int res; + + log_printf (LOG_LEVEL_DEBUG, "checkpoint exit conn %p\n", conn); + +@@ -2407,9 +2425,16 @@ + struct checkpoint_cleanup, list); + + assert (checkpoint_cleanup->checkpoint_name.length != 0); +- ckpt_checkpoint_close ( ++ res = ckpt_checkpoint_close ( + &checkpoint_cleanup->checkpoint_name, + checkpoint_cleanup->ckpt_id); ++ /* ++ * If checkpoint_close fails because of full totem queue ++ * return -1 ande try again later ++ */ ++ if (res == -1) { ++ return (-1); ++ } + + list_del (&checkpoint_cleanup->list); + free (checkpoint_cleanup); +@@ -2578,7 +2603,7 @@ + res_lib_ckpt_activereplicaset.header.id = MESSAGE_RES_CKPT_ACTIVEREPLICASET; + res_lib_ckpt_activereplicaset.header.error = error; + +- openais_conn_send_response ( ++ openais_response_send ( + conn, + &res_lib_ckpt_activereplicaset, + sizeof (struct res_lib_ckpt_activereplicaset)); +@@ -2641,7 +2666,7 @@ + res_lib_ckpt_checkpointstatusget.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSTATUSGET; + res_lib_ckpt_checkpointstatusget.header.error = SA_AIS_ERR_NOT_EXIST; + } +- openais_conn_send_response ( ++ openais_response_send ( + conn, + &res_lib_ckpt_checkpointstatusget, + sizeof (struct res_lib_ckpt_checkpointstatusget)); +@@ -2655,8 +2680,6 @@ + struct req_exec_ckpt_sectioncreate req_exec_ckpt_sectioncreate; + struct iovec iovecs[2]; + +- log_printf (LOG_LEVEL_DEBUG, "Section create from conn %p\n", conn); +- + req_exec_ckpt_sectioncreate.header.id = + SERVICE_ID_MAKE (CKPT_SERVICE, + MESSAGE_REQ_EXEC_CKPT_SECTIONCREATE); +@@ -2692,7 +2715,6 @@ + } + + if (iovecs[1].iov_len > 0) { +- log_printf (LOG_LEVEL_DEBUG, "IOV_BASE is %p\n", iovecs[1].iov_base); + assert (totempg_groups_mcast_joined (openais_group_handle, iovecs, 2, TOTEMPG_AGREED) == 0); + } else { + assert (totempg_groups_mcast_joined (openais_group_handle, iovecs, 1, TOTEMPG_AGREED) == 0); +@@ -2967,7 +2989,7 @@ + res_lib_ckpt_checkpointsynchronize.header.size = sizeof (struct res_lib_ckpt_checkpointsynchronize); + res_lib_ckpt_checkpointsynchronize.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZE; + +- openais_conn_send_response ( ++ openais_response_send ( + conn, + &res_lib_ckpt_checkpointsynchronize, + sizeof (struct res_lib_ckpt_checkpointsynchronize)); +@@ -2998,13 +3020,13 @@ + res_lib_ckpt_checkpointsynchronizeasync.header.id = MESSAGE_RES_CKPT_CHECKPOINT_CHECKPOINTSYNCHRONIZEASYNC; + res_lib_ckpt_checkpointsynchronizeasync.invocation = req_lib_ckpt_checkpointsynchronizeasync->invocation; + +- openais_conn_send_response ( ++ openais_response_send ( + conn, + &res_lib_ckpt_checkpointsynchronizeasync, + sizeof (struct res_lib_ckpt_checkpointsynchronizeasync)); + +- openais_conn_send_response ( +- openais_conn_partner_get (conn), ++ openais_dispatch_send ( ++ conn, + &res_lib_ckpt_checkpointsynchronizeasync, + sizeof (struct res_lib_ckpt_checkpointsynchronizeasync)); + } +@@ -3133,7 +3155,7 @@ + res_lib_ckpt_sectioniterationinitialize.max_section_id_size = + checkpoint->checkpoint_creation_attributes.max_section_id_size; + +- openais_conn_send_response ( ++ openais_response_send ( + conn, + &res_lib_ckpt_sectioniterationinitialize, + sizeof (struct res_lib_ckpt_sectioniterationinitialize)); +@@ -3174,7 +3196,7 @@ + res_lib_ckpt_sectioniterationfinalize.header.id = MESSAGE_RES_CKPT_SECTIONITERATIONFINALIZE; + res_lib_ckpt_sectioniterationfinalize.header.error = error; + +- openais_conn_send_response ( ++ openais_response_send ( + conn, + &res_lib_ckpt_sectioniterationfinalize, + sizeof (struct res_lib_ckpt_sectioniterationfinalize)); +@@ -3262,13 +3284,13 @@ + res_lib_ckpt_sectioniterationnext.header.id = MESSAGE_RES_CKPT_SECTIONITERATIONNEXT; + res_lib_ckpt_sectioniterationnext.header.error = error; + +- openais_conn_send_response ( ++ openais_response_send ( + conn, + &res_lib_ckpt_sectioniterationnext, + sizeof (struct res_lib_ckpt_sectioniterationnext)); + + if (error == SA_AIS_OK) { +- openais_conn_send_response ( ++ openais_response_send ( + conn, + checkpoint_section->section_descriptor.section_id.id, + checkpoint_section->section_descriptor.section_id.id_len); +@@ -3366,19 +3388,29 @@ + list_init (ckpt_list_head); + } + +-static inline void sync_checkpoints_enter (void) ++static inline void sync_gloalid_enter (void) + { + struct checkpoint *checkpoint; + + ENTER(); + +- my_sync_state = SYNC_STATE_CHECKPOINT; +- my_iteration_state = ITERATION_STATE_CHECKPOINT; +- my_iteration_state_checkpoint = checkpoint_list_head.next; ++ my_sync_state = SYNC_STATE_GLOBALID; ++ ++ my_iteration_state_checkpoint_list = checkpoint_list_head.next; + + checkpoint = list_entry (checkpoint_list_head.next, struct checkpoint, + list); +- my_iteration_state_section = checkpoint->sections_list_head.next; ++ my_iteration_state_section_list = checkpoint->sections_list_head.next; ++ ++ LEAVE(); ++} ++ ++static inline void sync_checkpoints_enter (void) ++{ ++ ENTER(); ++ ++ my_sync_state = SYNC_STATE_CHECKPOINT; ++ my_iteration_state = ITERATION_STATE_CHECKPOINT; + + LEAVE(); + } +@@ -3386,13 +3418,15 @@ + static inline void sync_refcounts_enter (void) + { + my_sync_state = SYNC_STATE_REFCOUNT; ++ ++ my_iteration_state_checkpoint_list = checkpoint_list_head.next; + } + + static void ckpt_sync_init (void) + { + ENTER(); + +- sync_checkpoints_enter(); ++ sync_gloalid_enter(); + + LEAVE(); + } +@@ -3432,6 +3466,19 @@ + return (totempg_groups_mcast_joined (openais_group_handle, &iovec, 1, TOTEMPG_AGREED)); + } + ++static int sync_checkpoint_globalid_transmit (void) ++{ ++ struct checkpoint checkpoint; ++ ++ strcpy ((char *)checkpoint.name.value, GLOBALID_CHECKPOINT_NAME); ++ ++ checkpoint.name.length = strlen (GLOBALID_CHECKPOINT_NAME); ++ checkpoint.ckpt_id = global_ckpt_id; ++ ++ return (sync_checkpoint_transmit(&checkpoint)); ++} ++ ++ + static int sync_checkpoint_section_transmit ( + struct checkpoint *checkpoint, + struct checkpoint_section *checkpoint_section) +@@ -3521,25 +3568,62 @@ + struct list_head *section_list; + unsigned int res = 0; + +- for (checkpoint_list = checkpoint_list_head.next; ++ /* ++ * iterate through all checkpoints or sections ++ * from the last successfully transmitted checkpoint or sectoin ++ */ ++ for (checkpoint_list = my_iteration_state_checkpoint_list; + checkpoint_list != &checkpoint_list_head; + checkpoint_list = checkpoint_list->next) { + + checkpoint = list_entry (checkpoint_list, struct checkpoint, list); + +- res = sync_checkpoint_transmit (checkpoint); +- if (res != 0) { +- break; ++ /* ++ * Synchronize a checkpoint if there is room in the totem ++ * buffers and we didn't previously synchronize a checkpoint ++ */ ++ if (my_iteration_state == ITERATION_STATE_CHECKPOINT) { ++ res = sync_checkpoint_transmit (checkpoint); ++ if (res != 0) { ++ /* ++ * Couldn't sync this checkpoint keep processing ++ */ ++ return (-1); ++ } ++ my_iteration_state_section_list = checkpoint->sections_list_head.next; ++ my_iteration_state = ITERATION_STATE_SECTION; + } +- for (section_list = checkpoint->sections_list_head.next; ++ ++ /* ++ * Synchronize a checkpoint section if there is room in the ++ * totem buffers ++ */ ++ for (section_list = my_iteration_state_section_list; + section_list != &checkpoint->sections_list_head; + section_list = section_list->next) { + + checkpoint_section = list_entry (section_list, struct checkpoint_section, list); + res = sync_checkpoint_section_transmit (checkpoint, checkpoint_section); ++ if (res != 0) { ++ /* ++ * Couldn't sync this section keep processing ++ */ ++ return (-1); ++ } ++ my_iteration_state_section_list = section_list->next; + } ++ ++ /* ++ * Continue to iterating checkpoints ++ */ ++ my_iteration_state = ITERATION_STATE_CHECKPOINT; ++ my_iteration_state_checkpoint_list = checkpoint_list->next; + } +- return (res); ++ ++ /* ++ * all checkpoints and sections iterated ++ */ ++ return (0); + } + + unsigned int sync_refcounts_iterate (void) +@@ -3548,7 +3632,7 @@ + struct list_head *list; + unsigned int res = 0; + +- for (list = checkpoint_list_head.next; ++ for (list = my_iteration_state_checkpoint_list; + list != &checkpoint_list_head; + list = list->next) { + +@@ -3558,48 +3642,68 @@ + if (res != 0) { + break; + } ++ my_iteration_state_checkpoint_list = list->next; + } + return (res); + } + + static int ckpt_sync_process (void) + { +- unsigned int done_queueing = 1; +- unsigned int continue_processing = 0; ++ unsigned int done_queueing; ++ unsigned int continue_processing; + unsigned int res; + + ENTER(); + ++ continue_processing = 0; ++ + switch (my_sync_state) { ++ case SYNC_STATE_GLOBALID: ++ done_queueing = 1; ++ continue_processing = 1; ++ if (my_should_sync) { ++ res = sync_checkpoint_globalid_transmit (); ++ if (res != 0) { ++ done_queueing = 0; ++ } ++ } ++ if (done_queueing) { ++ sync_checkpoints_enter (); ++ } ++ break; ++ + case SYNC_STATE_CHECKPOINT: +- if (my_lowest_nodeid == this_ip->nodeid) { ++ done_queueing = 1; ++ continue_processing = 1; ++ ++ if (my_should_sync) { + TRACE1 ("should transmit checkpoints because lowest member in old configuration.\n"); + res = sync_checkpoints_iterate (); + +- if (res == 0) { +- done_queueing = 1; ++ /* ++ * Not done iterating checkpoints ++ */ ++ if (res != 0) { ++ done_queueing = 0; + } + } + if (done_queueing) { + sync_refcounts_enter (); + } +- +- /* +- * TODO recover current iteration state +- */ +- continue_processing = 1; + break; + + case SYNC_STATE_REFCOUNT: +- done_queueing = 1; +- if (my_lowest_nodeid == this_ip->nodeid) { ++ if (my_should_sync) { + TRACE1 ("transmit refcounts because this processor is the lowest member in old configuration.\n"); + res = sync_refcounts_iterate (); +- } +- if (done_queueing) { +- continue_processing = 0; ++ if (res != 0) { ++ continue_processing = 1; ++ } + } + break; ++ ++ default: ++ assert (0); + } + + LEAVE(); +@@ -3620,7 +3724,7 @@ + + list_init (&sync_checkpoint_list_head); + +- my_sync_state = SYNC_STATE_CHECKPOINT; ++ my_sync_state = SYNC_STATE_NOT_STARTED; + + LEAVE(); + } +@@ -3648,6 +3752,22 @@ + return; + } + ++ /* ++ * Discard checkpoints that are used to synchronize the global_ckpt_id ++ * also setting the global ckpt_id as well. ++ */ ++ if (memcmp (&req_exec_ckpt_sync_checkpoint->checkpoint_name.value, ++ GLOBALID_CHECKPOINT_NAME, ++ req_exec_ckpt_sync_checkpoint->checkpoint_name.length) == 0) { ++ ++ if (req_exec_ckpt_sync_checkpoint->ckpt_id >= global_ckpt_id) { ++ global_ckpt_id = req_exec_ckpt_sync_checkpoint->ckpt_id + 1; ++ } ++ ++ LEAVE(); ++ return; ++ } ++ + checkpoint = checkpoint_find_specific ( + &sync_checkpoint_list_head, + &req_exec_ckpt_sync_checkpoint->checkpoint_name, +diff -uNr openais-0.80.3/exec/clm.c openais-0.80.3-r1661/exec/clm.c +--- openais-0.80.3/exec/clm.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/clm.c 2008-11-17 15:54:02.380604445 +0100 +@@ -262,24 +262,29 @@ + mar_clm_cluster_node_t cluster_node __attribute__((aligned(8))); + }; + +-static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb) ++static void my_cluster_node_load (void) + { +- log_init ("CLM"); ++ struct totem_ip_address interfaces[INTERFACE_MAX]; ++ unsigned int iface_count; ++ char **status; ++ const char *iface_string; ++ ++ totempg_ifaces_get ( ++ totempg_my_nodeid_get (), ++ interfaces, ++ &status, ++ &iface_count); + +- memset (cluster_node_entries, 0, +- sizeof (mar_clm_cluster_node_t) * PROCESSOR_COUNT_MAX); ++ iface_string = totemip_print (&interfaces[0]); + +- /* +- * Build local cluster node data structure +- */ + sprintf ((char *)my_cluster_node.node_address.value, "%s", +- totemip_print (this_ip)); ++ iface_string); + my_cluster_node.node_address.length = + strlen ((char *)my_cluster_node.node_address.value); +- if (this_ip->family == AF_INET) { ++ if (totempg_my_family_get () == AF_INET) { + my_cluster_node.node_address.family = SA_CLM_AF_INET; + } else +- if (this_ip->family == AF_INET6) { ++ if (totempg_my_family_get () == AF_INET6) { + my_cluster_node.node_address.family = SA_CLM_AF_INET6; + } else { + assert (0); +@@ -289,8 +294,20 @@ + (char *)my_cluster_node.node_address.value); + my_cluster_node.node_name.length = + my_cluster_node.node_address.length; +- my_cluster_node.node_id = this_ip->nodeid; ++ my_cluster_node.node_id = totempg_my_nodeid_get (); + my_cluster_node.member = 1; ++ ++ memcpy (&cluster_node_entries[0], &my_cluster_node, ++ sizeof (mar_clm_cluster_node_t)); ++} ++ ++static int clm_exec_init_fn (struct objdb_iface_ver0 *objdb) ++{ ++ log_init ("CLM"); ++ ++ memset (cluster_node_entries, 0, ++ sizeof (mar_clm_cluster_node_t) * PROCESSOR_COUNT_MAX); ++ + { + #if defined(OPENAIS_LINUX) + struct sysinfo s_info; +@@ -313,7 +330,6 @@ + #endif + } + +- memcpy (&cluster_node_entries[0], &my_cluster_node, sizeof (mar_clm_cluster_node_t)); + cluster_node_count = 1; + + main_clm_get_by_nodeid = clm_get_by_nodeid; +@@ -391,7 +407,7 @@ + /* + * Send notifications to all CLM listeners + */ +- openais_conn_send_response ( ++ openais_dispatch_send ( + clm_pd->conn, + &res_lib_clm_clustertrack, + sizeof (struct res_lib_clm_clustertrack)); +@@ -519,20 +535,7 @@ + * Load the my_cluster_node data structure in case we are + * transitioning to network interface up or down + */ +- sprintf ((char *)my_cluster_node.node_address.value, "%s", totemip_print (this_ip)); +- my_cluster_node.node_address.length = strlen ((char *)my_cluster_node.node_address.value); +- if (this_ip->family == AF_INET) { +- my_cluster_node.node_address.family = SA_CLM_AF_INET; +- } else +- if (this_ip->family == AF_INET6) { +- my_cluster_node.node_address.family = SA_CLM_AF_INET6; +- } else { +- assert (0); +- } +- strcpy ((char *)my_cluster_node.node_name.value, +- (char *)my_cluster_node.node_address.value); +- my_cluster_node.node_name.length = my_cluster_node.node_address.length; +- my_cluster_node.node_id = this_ip->nodeid; ++ my_cluster_node_load (); + } + + /* +@@ -664,14 +667,16 @@ + list_add (&clm_pd->list, &library_notification_send_listhead); + } + +- openais_conn_send_response (conn, &res_lib_clm_clustertrack, ++ openais_response_send ( ++ conn, ++ &res_lib_clm_clustertrack, + sizeof (struct res_lib_clm_clustertrack)); + + if (req_lib_clm_clustertrack->return_in_callback) { + res_lib_clm_clustertrack.header.id = MESSAGE_RES_CLM_TRACKCALLBACK; + +- openais_conn_send_response ( +- openais_conn_partner_get (conn), ++ openais_dispatch_send ( ++ conn, + &res_lib_clm_clustertrack, + sizeof (struct res_lib_clm_clustertrack)); + } +@@ -696,7 +701,9 @@ + list_del (&clm_pd->list); + list_init (&clm_pd->list); + +- openais_conn_send_response (conn, &res_lib_clm_trackstop, ++ openais_response_send ( ++ conn, ++ &res_lib_clm_trackstop, + sizeof (struct res_lib_clm_trackstop)); + } + +@@ -732,7 +739,11 @@ + if (valid) { + memcpy (&res_clm_nodeget.cluster_node, cluster_node, sizeof (mar_clm_cluster_node_t)); + } +- openais_conn_send_response (conn, &res_clm_nodeget, sizeof (struct res_clm_nodeget)); ++ ++ openais_response_send ( ++ conn, ++ &res_clm_nodeget, ++ sizeof (struct res_clm_nodeget)); + } + + static void message_handler_req_lib_clm_nodegetasync (void *conn, void *msg) +@@ -767,7 +778,9 @@ + res_clm_nodegetasync.header.id = MESSAGE_RES_CLM_NODEGETASYNC; + res_clm_nodegetasync.header.error = SA_AIS_OK; + +- openais_conn_send_response (conn, &res_clm_nodegetasync, ++ openais_response_send ( ++ conn, ++ &res_clm_nodegetasync, + sizeof (struct res_clm_nodegetasync)); + + /* +@@ -781,7 +794,8 @@ + memcpy (&res_clm_nodegetcallback.cluster_node, cluster_node, + sizeof (mar_clm_cluster_node_t)); + } +- openais_conn_send_response (openais_conn_partner_get (conn), ++ openais_dispatch_send ( ++ conn, + &res_clm_nodegetcallback, + sizeof (struct res_clm_nodegetcallback)); + } +diff -uNr openais-0.80.3/exec/cpg.c openais-0.80.3-r1661/exec/cpg.c +--- openais-0.80.3/exec/cpg.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/cpg.c 2008-11-17 15:54:02.380604445 +0100 +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 2006-2007 Red Hat, Inc. ++ * Copyright (c) 2006 Red Hat, Inc. + * Copyright (c) 2006 Sun Microsystems, Inc. + * + * All rights reserved. +@@ -32,6 +32,9 @@ + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ ++#ifndef OPENAIS_BSD ++#include <alloca.h> ++#endif + #include <sys/types.h> + #include <sys/socket.h> + #include <sys/un.h> +@@ -60,8 +63,11 @@ + #include "totempg.h" + #include "totemip.h" + #include "main.h" ++#include "flow.h" ++#include "tlist.h" + #include "ipc.h" + #include "mempool.h" ++#include "objdb.h" + #include "service.h" + #include "jhash.h" + #include "swab.h" +@@ -255,7 +261,7 @@ + }; + + struct openais_service_handler cpg_service_handler = { +- .name = (unsigned char*)"openais cluster closed process group service v1.01", ++ .name = (unsigned char *)"openais cluster closed process group service v1.01", + .id = CPG_SERVICE, + .private_data_size = sizeof (struct process_info), + .flow_control = OPENAIS_FLOW_CONTROL_REQUIRED, +@@ -434,14 +440,14 @@ + } + + if (conn) { +- openais_conn_send_response(conn, buf, size); ++ openais_dispatch_send(conn, buf, size); + } + else { + /* Send it to all listeners */ + for (iter = gi->members.next, tmp=iter->next; iter != &gi->members; iter = tmp, tmp=iter->next) { + struct process_info *pi = list_entry(iter, struct process_info, list); + if (pi->trackerconn && (pi->flags & PI_FLAG_MEMBER)) { +- if (openais_conn_send_response(pi->trackerconn, buf, size) == -1) { ++ if (openais_dispatch_send(pi->trackerconn, buf, size) == -1) { + // Error ?? + } + } +@@ -477,14 +483,17 @@ + struct group_info *gi = pi->group; + mar_cpg_address_t notify_info; + +- log_printf(LOG_LEVEL_DEBUG, "exit_fn for conn=%p\n", conn); +- + if (gi) { + notify_info.pid = pi->pid; +- notify_info.nodeid = this_ip->nodeid; ++ notify_info.nodeid = totempg_my_nodeid_get(); + notify_info.reason = CONFCHG_CPG_REASON_PROCDOWN; + cpg_node_joinleave_send(gi, pi, MESSAGE_REQ_EXEC_CPG_PROCLEAVE, CONFCHG_CPG_REASON_PROCDOWN); + list_del(&pi->list); ++ openais_ipc_flow_control_destroy ( ++ conn, ++ CPG_SERVICE, ++ (unsigned char *)gi->group_name.value, ++ (unsigned int)gi->group_name.length); + } + return (0); + } +@@ -531,7 +540,7 @@ + req_exec_cpg_procjoin.header.size = sizeof(req_exec_cpg_procjoin); + req_exec_cpg_procjoin.header.id = SERVICE_ID_MAKE(CPG_SERVICE, fn); + +- req_exec_cpg_iovec.iov_base = &req_exec_cpg_procjoin; ++ req_exec_cpg_iovec.iov_base = (char *)&req_exec_cpg_procjoin; + req_exec_cpg_iovec.iov_len = sizeof(req_exec_cpg_procjoin); + + result = totempg_groups_mcast_joined (openais_group_handle, &req_exec_cpg_iovec, 1, TOTEMPG_AGREED); +@@ -544,15 +553,17 @@ + struct list_head *remlist) + { + int i; +- struct list_head *iter, *iter2, *tmp; ++ struct list_head *iter, *iter2; + struct process_info *pi; + struct group_info *gi; + + for (i=0; i < GROUP_HASH_SIZE; i++) { +- for (iter = group_lists[i].next; iter != &group_lists[i]; iter = iter->next) { ++ for (iter = group_lists[i].next; iter != &group_lists[i];) { + gi = list_entry(iter, struct group_info, list); +- for (iter2 = gi->members.next, tmp = iter2->next; iter2 != &gi->members; iter2 = tmp, tmp = iter2->next) { ++ iter = iter->next; ++ for (iter2 = gi->members.next; iter2 != &gi->members;) { + pi = list_entry(iter2, struct process_info, list); ++ iter2 = iter2->next; + + if (pi->nodeid == nodeid) { + +@@ -627,8 +638,8 @@ + lowest_nodeid = member_list[i]; + } + +- log_printf(LOG_LEVEL_DEBUG, "confchg, low nodeid=%d, us = %d\n", lowest_nodeid, this_ip->nodeid); +- if (lowest_nodeid == this_ip->nodeid) { ++ log_printf(LOG_LEVEL_DEBUG, "confchg, low nodeid=%d, us = %d\n", lowest_nodeid, totempg_my_nodeid_get()); ++ if (lowest_nodeid == totempg_my_nodeid_get()) { + + req_exec_cpg_downlist.header.id = SERVICE_ID_MAKE(CPG_SERVICE, MESSAGE_REQ_EXEC_CPG_DOWNLIST); + req_exec_cpg_downlist.header.size = sizeof(struct req_exec_cpg_downlist); +@@ -643,7 +654,7 @@ + + /* Don't send this message until we get the final configuration message */ + if (configuration_type == TOTEM_CONFIGURATION_REGULAR && req_exec_cpg_downlist.left_nodes) { +- req_exec_cpg_iovec.iov_base = &req_exec_cpg_downlist; ++ req_exec_cpg_iovec.iov_base = (char *)&req_exec_cpg_downlist; + req_exec_cpg_iovec.iov_len = req_exec_cpg_downlist.header.size; + + totempg_groups_mcast_joined (openais_group_handle, &req_exec_cpg_iovec, 1, TOTEMPG_AGREED); +@@ -688,10 +699,16 @@ + static void exec_cpg_downlist_endian_convert (void *msg) + { + struct req_exec_cpg_downlist *req_exec_cpg_downlist = (struct req_exec_cpg_downlist *)msg; ++ unsigned int i; + + req_exec_cpg_downlist->left_nodes = swab32(req_exec_cpg_downlist->left_nodes); ++ ++ for (i = 0; i < req_exec_cpg_downlist->left_nodes; i++) { ++ req_exec_cpg_downlist->nodeids[i] = swab32(req_exec_cpg_downlist->nodeids[i]); ++ } + } + ++ + static void exec_cpg_mcast_endian_convert (void *msg) + { + struct req_exec_cpg_mcast *req_exec_cpg_mcast = (struct req_exec_cpg_mcast *)msg; +@@ -723,7 +740,7 @@ + if (pi->pid == pid && pi->nodeid == nodeid) { + + /* It could be a local join message */ +- if ((nodeid == this_ip->nodeid) && ++ if ((nodeid == totempg_my_nodeid_get()) && + (!pi->flags & PI_FLAG_MEMBER)) { + goto local_join; + } else { +@@ -810,7 +827,7 @@ + struct req_exec_cpg_procjoin *req_exec_cpg_procjoin = (struct req_exec_cpg_procjoin *)message; + struct group_info *gi; + struct process_info *pi; +- struct list_head *iter; ++ volatile struct list_head *iter; + mar_cpg_address_t notify_info; + + log_printf(LOG_LEVEL_DEBUG, "got procleave message from cluster node %d\n", nodeid); +@@ -827,19 +844,28 @@ + 1, ¬ify_info, + MESSAGE_RES_CPG_CONFCHG_CALLBACK); + +- /* Find the node/PID to remove */ +- for (iter = gi->members.next; iter != &gi->members; iter = iter->next) { ++ /* ++ * Find the node/PID to remove ++ */ ++ for (iter = gi->members.next; iter != &gi->members;) { + pi = list_entry(iter, struct process_info, list); ++ ++ iter = iter->next; ++ + if (pi->pid == req_exec_cpg_procjoin->pid && + pi->nodeid == nodeid) { + +- list_del(&pi->list); +- if (!pi->conn) +- free(pi); +- + if (list_empty(&gi->members)) { + remove_group(gi); + } ++ ++ list_del(&pi->list); ++ if (pi->conn) { ++ openais_conn_info_refcnt_dec(pi->conn); ++ } else { ++ free(pi); ++ } ++ + break; + } + } +@@ -858,7 +884,7 @@ + nodeid); + + /* Ignore our own messages */ +- if (nodeid == this_ip->nodeid) { ++ if (nodeid == totempg_my_nodeid_get()) { + return; + } + +@@ -898,6 +924,7 @@ + openais_ipc_flow_control_local_decrement (req_exec_cpg_mcast->source.conn); + process_info = (struct process_info *)openais_conn_private_data_get (req_exec_cpg_mcast->source.conn); + res_lib_cpg_mcast->flow_control_state = process_info->flow_control_state; ++ openais_conn_info_refcnt_dec (req_exec_cpg_mcast->source.conn); + } + memcpy(&res_lib_cpg_mcast->group_name, &gi->group_name, + sizeof(mar_cpg_name_t)); +@@ -907,8 +934,8 @@ + /* Send to all interested members */ + for (iter = gi->members.next; iter != &gi->members; iter = iter->next) { + struct process_info *pi = list_entry(iter, struct process_info, list); +- if (pi->trackerconn) { +- openais_conn_send_response( ++ if (pi->trackerconn && (pi->flags & PI_FLAG_MEMBER)) { ++ openais_dispatch_send ( + pi->trackerconn, + buf, + res_lib_cpg_mcast->header.size); +@@ -937,7 +964,7 @@ + gi = list_entry(iter, struct group_info, list); + for (iter2 = gi->members.next; iter2 != &gi->members; iter2 = iter2->next) { + struct process_info *pi = list_entry(iter2, struct process_info, list); +- if (pi->pid && pi->nodeid == this_ip->nodeid) { ++ if (pi->pid && pi->nodeid == totempg_my_nodeid_get()) { + count++; + } + } +@@ -964,7 +991,7 @@ + for (iter2 = gi->members.next; iter2 != &gi->members; iter2 = iter2->next) { + + struct process_info *pi = list_entry(iter2, struct process_info, list); +- if (pi->pid && pi->nodeid == this_ip->nodeid) { ++ if (pi->pid && pi->nodeid == totempg_my_nodeid_get()) { + memcpy(&jle->group_name, &gi->group_name, sizeof(mar_cpg_name_t)); + jle->pid = pi->pid; + jle++; +@@ -987,6 +1014,7 @@ + struct process_info *pi = (struct process_info *)openais_conn_private_data_get (conn); + pi->conn = conn; + ++ openais_conn_info_refcnt_inc (conn); + log_printf(LOG_LEVEL_DEBUG, "lib_init_fn: conn=%p, pi=%p\n", conn, pi); + return (0); + } +@@ -1023,7 +1051,7 @@ + pi); + + /* Add a node entry for us */ +- pi->nodeid = this_ip->nodeid; ++ pi->nodeid = totempg_my_nodeid_get(); + pi->pid = req_lib_cpg_join->pid; + pi->group = gi; + list_add(&pi->list, &gi->members); +@@ -1035,7 +1063,7 @@ + res_lib_cpg_join.header.size = sizeof(res_lib_cpg_join); + res_lib_cpg_join.header.id = MESSAGE_RES_CPG_JOIN; + res_lib_cpg_join.header.error = error; +- openais_conn_send_response(conn, &res_lib_cpg_join, sizeof(res_lib_cpg_join)); ++ openais_response_send(conn, &res_lib_cpg_join, sizeof(res_lib_cpg_join)); + } + + /* Leave message from the library */ +@@ -1046,8 +1074,6 @@ + struct group_info *gi; + SaAisErrorT error = SA_AIS_OK; + +- log_printf(LOG_LEVEL_DEBUG, "got leave request on %p\n", conn); +- + if (!pi || !pi->pid || !pi->group) { + error = SA_AIS_ERR_INVALID_PARAM; + goto leave_ret; +@@ -1070,7 +1096,7 @@ + res_lib_cpg_leave.header.size = sizeof(res_lib_cpg_leave); + res_lib_cpg_leave.header.id = MESSAGE_RES_CPG_LEAVE; + res_lib_cpg_leave.header.error = error; +- openais_conn_send_response(conn, &res_lib_cpg_leave, sizeof(res_lib_cpg_leave)); ++ openais_response_send(conn, &res_lib_cpg_leave, sizeof(res_lib_cpg_leave)); + } + + /* Mcast message from the library */ +@@ -1093,7 +1119,7 @@ + res_lib_cpg_mcast.header.id = MESSAGE_RES_CPG_MCAST; + res_lib_cpg_mcast.header.error = SA_AIS_ERR_ACCESS; /* TODO Better error code ?? */ + res_lib_cpg_mcast.flow_control_state = CPG_FLOW_CONTROL_DISABLED; +- openais_conn_send_response(conn, &res_lib_cpg_mcast, ++ openais_response_send(conn, &res_lib_cpg_mcast, + sizeof(res_lib_cpg_mcast)); + return; + } +@@ -1101,15 +1127,16 @@ + req_exec_cpg_mcast.header.size = sizeof(req_exec_cpg_mcast) + msglen; + req_exec_cpg_mcast.header.id = SERVICE_ID_MAKE(CPG_SERVICE, + MESSAGE_REQ_EXEC_CPG_MCAST); ++ openais_conn_info_refcnt_inc (conn); + req_exec_cpg_mcast.pid = pi->pid; + req_exec_cpg_mcast.msglen = msglen; + message_source_set (&req_exec_cpg_mcast.source, conn); + memcpy(&req_exec_cpg_mcast.group_name, &gi->group_name, + sizeof(mar_cpg_name_t)); + +- req_exec_cpg_iovec[0].iov_base = &req_exec_cpg_mcast; ++ req_exec_cpg_iovec[0].iov_base = (char *)&req_exec_cpg_mcast; + req_exec_cpg_iovec[0].iov_len = sizeof(req_exec_cpg_mcast); +- req_exec_cpg_iovec[1].iov_base = &req_lib_cpg_mcast->message; ++ req_exec_cpg_iovec[1].iov_base = (char *)&req_lib_cpg_mcast->message; + req_exec_cpg_iovec[1].iov_len = msglen; + + // TODO: guarantee type... +@@ -1120,7 +1147,7 @@ + res_lib_cpg_mcast.header.id = MESSAGE_RES_CPG_MCAST; + res_lib_cpg_mcast.header.error = SA_AIS_OK; + res_lib_cpg_mcast.flow_control_state = pi->flow_control_state; +- openais_conn_send_response(conn, &res_lib_cpg_mcast, ++ openais_response_send(conn, &res_lib_cpg_mcast, + sizeof(res_lib_cpg_mcast)); + } + +@@ -1134,7 +1161,7 @@ + res.size = sizeof(res); + res.id = MESSAGE_RES_CPG_MEMBERSHIP; + res.error = SA_AIS_ERR_ACCESS; /* TODO Better error code */ +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_response_send(conn, &res, sizeof(res)); + return; + } + +@@ -1148,7 +1175,6 @@ + struct res_lib_cpg_trackstart res_lib_cpg_trackstart; + struct group_info *gi; + struct process_info *otherpi; +- void *otherconn; + SaAisErrorT error = SA_AIS_OK; + + log_printf(LOG_LEVEL_DEBUG, "got trackstart request on %p\n", conn); +@@ -1160,7 +1186,6 @@ + } + + /* Find the partner connection and add us to it's process_info struct */ +- otherconn = openais_conn_partner_get (conn); + otherpi = (struct process_info *)openais_conn_private_data_get (conn); + otherpi->trackerconn = conn; + +@@ -1168,7 +1193,7 @@ + res_lib_cpg_trackstart.header.size = sizeof(res_lib_cpg_trackstart); + res_lib_cpg_trackstart.header.id = MESSAGE_RES_CPG_TRACKSTART; + res_lib_cpg_trackstart.header.error = SA_AIS_OK; +- openais_conn_send_response(conn, &res_lib_cpg_trackstart, sizeof(res_lib_cpg_trackstart)); ++ openais_response_send(conn, &res_lib_cpg_trackstart, sizeof(res_lib_cpg_trackstart)); + } + + static void message_handler_req_lib_cpg_trackstop (void *conn, void *message) +@@ -1176,7 +1201,6 @@ + struct req_lib_cpg_trackstop *req_lib_cpg_trackstop = (struct req_lib_cpg_trackstop *)message; + struct res_lib_cpg_trackstop res_lib_cpg_trackstop; + struct process_info *otherpi; +- void *otherconn; + struct group_info *gi; + SaAisErrorT error = SA_AIS_OK; + +@@ -1189,7 +1213,6 @@ + } + + /* Find the partner connection and add us to it's process_info struct */ +- otherconn = openais_conn_partner_get (conn); + otherpi = (struct process_info *)openais_conn_private_data_get (conn); + otherpi->trackerconn = NULL; + +@@ -1197,7 +1220,7 @@ + res_lib_cpg_trackstop.header.size = sizeof(res_lib_cpg_trackstop); + res_lib_cpg_trackstop.header.id = MESSAGE_RES_CPG_TRACKSTOP; + res_lib_cpg_trackstop.header.error = SA_AIS_OK; +- openais_conn_send_response(conn, &res_lib_cpg_trackstop.header, sizeof(res_lib_cpg_trackstop)); ++ openais_response_send(conn, &res_lib_cpg_trackstop.header, sizeof(res_lib_cpg_trackstop)); + } + + static void message_handler_req_lib_cpg_local_get (void *conn, void *message) +@@ -1207,8 +1230,8 @@ + res_lib_cpg_local_get.header.size = sizeof(res_lib_cpg_local_get); + res_lib_cpg_local_get.header.id = MESSAGE_RES_CPG_LOCAL_GET; + res_lib_cpg_local_get.header.error = SA_AIS_OK; +- res_lib_cpg_local_get.local_nodeid = this_ip->nodeid; ++ res_lib_cpg_local_get.local_nodeid = totempg_my_nodeid_get (); + +- openais_conn_send_response(conn, &res_lib_cpg_local_get, ++ openais_response_send(conn, &res_lib_cpg_local_get, + sizeof(res_lib_cpg_local_get)); + } +diff -uNr openais-0.80.3/exec/evs.c openais-0.80.3-r1661/exec/evs.c +--- openais-0.80.3/exec/evs.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/evs.c 2008-11-17 15:54:02.380604445 +0100 +@@ -244,7 +244,8 @@ + */ + for (list = confchg_notify.next; list != &confchg_notify; list = list->next) { + evs_pd = list_entry (list, struct evs_pd, list); +- openais_conn_send_response (evs_pd->conn, ++ openais_dispatch_send ( ++ evs_pd->conn, + &res_evs_confchg_callback, + sizeof (res_evs_confchg_callback)); + } +@@ -262,7 +263,9 @@ + list_init (&evs_pd->list); + list_add (&evs_pd->list, &confchg_notify); + +- openais_conn_send_response (conn, &res_evs_confchg_callback, ++ openais_dispatch_send ( ++ conn, ++ &res_evs_confchg_callback, + sizeof (res_evs_confchg_callback)); + + return (0); +@@ -308,7 +311,9 @@ + res_lib_evs_join.header.id = MESSAGE_RES_EVS_JOIN; + res_lib_evs_join.header.error = error; + +- openais_conn_send_response (conn, &res_lib_evs_join, ++ openais_response_send ( ++ conn, ++ &res_lib_evs_join, + sizeof (struct res_lib_evs_join)); + } + +@@ -354,7 +359,9 @@ + res_lib_evs_leave.header.id = MESSAGE_RES_EVS_LEAVE; + res_lib_evs_leave.header.error = error; + +- openais_conn_send_response (conn, &res_lib_evs_leave, ++ openais_response_send ( ++ conn, ++ &res_lib_evs_leave, + sizeof (struct res_lib_evs_leave)); + } + +@@ -397,7 +404,9 @@ + res_lib_evs_mcast_joined.header.id = MESSAGE_RES_EVS_MCAST_JOINED; + res_lib_evs_mcast_joined.header.error = error; + +- openais_conn_send_response (conn, &res_lib_evs_mcast_joined, ++ openais_response_send ( ++ conn, ++ &res_lib_evs_mcast_joined, + sizeof (struct res_lib_evs_mcast_joined)); + } + +@@ -443,7 +452,9 @@ + res_lib_evs_mcast_groups.header.id = MESSAGE_RES_EVS_MCAST_GROUPS; + res_lib_evs_mcast_groups.header.error = error; + +- openais_conn_send_response (conn, &res_lib_evs_mcast_groups, ++ openais_response_send ( ++ conn, ++ &res_lib_evs_mcast_groups, + sizeof (struct res_lib_evs_mcast_groups)); + } + +@@ -454,7 +465,7 @@ + res_lib_evs_membership_get.header.size = sizeof (struct res_lib_evs_membership_get); + res_lib_evs_membership_get.header.id = MESSAGE_RES_EVS_MEMBERSHIP_GET; + res_lib_evs_membership_get.header.error = EVS_OK; +- res_lib_evs_membership_get.local_nodeid = this_ip->nodeid; ++ res_lib_evs_membership_get.local_nodeid = totempg_my_nodeid_get (); + memcpy (&res_lib_evs_membership_get.member_list, + &res_evs_confchg_callback.member_list, + sizeof (res_lib_evs_membership_get.member_list)); +@@ -462,7 +473,9 @@ + res_lib_evs_membership_get.member_list_entries = + res_evs_confchg_callback.member_list_entries; + +- openais_conn_send_response (conn, &res_lib_evs_membership_get, ++ openais_response_send ( ++ conn, ++ &res_lib_evs_membership_get, + sizeof (struct res_lib_evs_membership_get)); + } + +@@ -487,8 +500,10 @@ + int i, j; + struct evs_pd *evs_pd; + +- res_evs_deliver_callback.header.size = sizeof (struct res_evs_deliver_callback) + +- req_exec_evs_mcast->msg_len; ++ res_evs_deliver_callback.header.size = ++ sizeof (struct res_evs_deliver_callback) + ++ req_exec_evs_mcast->msg_len; ++ + res_evs_deliver_callback.header.id = MESSAGE_RES_EVS_DELIVER_CALLBACK; + res_evs_deliver_callback.header.error = SA_AIS_OK; + res_evs_deliver_callback.msglen = req_exec_evs_mcast->msg_len; +@@ -517,9 +532,13 @@ + + if (found) { + res_evs_deliver_callback.local_nodeid = nodeid; +- openais_conn_send_response (evs_pd->conn, &res_evs_deliver_callback, ++ openais_dispatch_send ( ++ evs_pd->conn, ++ &res_evs_deliver_callback, + sizeof (struct res_evs_deliver_callback)); +- openais_conn_send_response (evs_pd->conn, msg_addr, ++ openais_dispatch_send ( ++ evs_pd->conn, ++ msg_addr, + req_exec_evs_mcast->msg_len); + } + } +diff -uNr openais-0.80.3/exec/evt.c openais-0.80.3-r1661/exec/evt.c +--- openais-0.80.3/exec/evt.c 2007-06-25 04:22:54.000000000 +0200 ++++ openais-0.80.3-r1661/exec/evt.c 2008-11-17 15:54:02.390605772 +0100 +@@ -1853,8 +1853,10 @@ + res.evd_head.size = sizeof(res); + res.evd_head.id = MESSAGE_RES_EVT_AVAILABLE; + res.evd_head.error = SA_AIS_OK; +- openais_conn_send_response(openais_conn_partner_get(conn), +- &res, sizeof(res)); ++ openais_dispatch_send ( ++ conn, ++ &res, ++ sizeof(res)); + } + + } +@@ -1987,6 +1989,7 @@ + if (!ep) { + log_printf(LOG_LEVEL_WARNING, + "5Memory allocation error, can't deliver event\n"); ++ free (ed); + return; + } + ep->cel_chan_handle = eco->eco_lib_handle; +@@ -2264,7 +2267,7 @@ + res.ico_head.size = sizeof(res); + res.ico_head.id = MESSAGE_RES_EVT_OPEN_CHANNEL; + res.ico_head.error = error; +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_response_send(conn, &res, sizeof(res)); + } + + /* +@@ -2321,7 +2324,7 @@ + res.ico_head.size = sizeof(res); + res.ico_head.id = MESSAGE_RES_EVT_OPEN_CHANNEL; + res.ico_head.error = error; +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_dispatch_send(conn, &res, sizeof(res)); + } + + +@@ -2414,7 +2417,7 @@ + res.icc_head.size = sizeof(res); + res.icc_head.id = MESSAGE_RES_EVT_CLOSE_CHANNEL; + res.icc_head.error = ((ret == 0) ? SA_AIS_OK : SA_AIS_ERR_BAD_HANDLE); +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_response_send(conn, &res, sizeof(res)); + } + + /* +@@ -2486,7 +2489,7 @@ + res.iuc_head.size = sizeof(res); + res.iuc_head.id = MESSAGE_RES_EVT_UNLINK_CHANNEL; + res.iuc_head.error = error; +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_response_send(conn, &res, sizeof(res)); + } + + /* +@@ -2590,7 +2593,7 @@ + res.ics_head.size = sizeof(res); + res.ics_head.id = MESSAGE_RES_EVT_SUBSCRIBE; + res.ics_head.error = error; +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_response_send(conn, &res, sizeof(res)); + + /* + * See if an existing event with a retention time +@@ -2623,7 +2626,7 @@ + res.ics_head.size = sizeof(res); + res.ics_head.id = MESSAGE_RES_EVT_SUBSCRIBE; + res.ics_head.error = error; +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_response_send(conn, &res, sizeof(res)); + } + + /* +@@ -2690,7 +2693,7 @@ + res.icu_head.size = sizeof(res); + res.icu_head.id = MESSAGE_RES_EVT_UNSUBSCRIBE; + res.icu_head.error = error; +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_response_send(conn, &res, sizeof(res)); + } + + /* +@@ -2762,7 +2765,7 @@ + res.iep_head.id = MESSAGE_RES_EVT_PUBLISH; + res.iep_head.error = error; + res.iep_event_id = event_id; +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_response_send(conn, &res, sizeof(res)); + } + + /* +@@ -2826,7 +2829,7 @@ + res.iec_head.size = sizeof(res); + res.iec_head.id = MESSAGE_RES_EVT_CLEAR_RETENTIONTIME; + res.iec_head.error = error; +- openais_conn_send_response(conn, &res, sizeof(res)); ++ openais_response_send(conn, &res, sizeof(res)); + + } + +@@ -2865,7 +2868,7 @@ + edp->ed_event.led_head.id = MESSAGE_RES_EVT_EVENT_DATA; + edp->ed_event.led_head.error = SA_AIS_OK; + free(cel); +- openais_conn_send_response(conn, &edp->ed_event, ++ openais_response_send(conn, &edp->ed_event, + edp->ed_event.led_head.size); + free_event_data(edp); + goto data_get_done; +@@ -2875,7 +2878,7 @@ + res.led_head.size = sizeof(res.led_head); + res.led_head.id = MESSAGE_RES_EVT_EVENT_DATA; + res.led_head.error = SA_AIS_ERR_NOT_EXIST; +- openais_conn_send_response(conn, &res, res.led_head.size); ++ openais_response_send(conn, &res, res.led_head.size); + + /* + * See if there are any events that the app doesn't know about +@@ -3037,7 +3040,7 @@ + struct unlink_chan_pending *ucp; + struct retention_time_clear_pending *rtc; + struct libevt_pd *esip = +- openais_conn_private_data_get(openais_conn_partner_get(conn)); ++ openais_conn_private_data_get(conn); + + log_printf(LOG_LEVEL_DEBUG, "saEvtFinalize (Event exit request)\n"); + log_printf(LOG_LEVEL_DEBUG, "saEvtFinalize %d evts on list\n", +@@ -3430,7 +3433,7 @@ + res.ico_head.id = MESSAGE_RES_EVT_OPEN_CHANNEL; + res.ico_head.error = SA_AIS_ERR_TIMEOUT; + ocp->ocp_invocation = OPEN_TIMED_OUT; +- openais_conn_send_response(ocp->ocp_conn, &res, sizeof(res)); ++ openais_response_send(ocp->ocp_conn, &res, sizeof(res)); + } + + /* +@@ -3520,15 +3523,14 @@ + resa.ica_channel_handle = handle; + resa.ica_c_handle = ocp->ocp_c_handle; + resa.ica_invocation = ocp->ocp_invocation; +- openais_conn_send_response(openais_conn_partner_get(ocp->ocp_conn), +- &resa, sizeof(resa)); ++ openais_dispatch_send(ocp->ocp_conn, &resa, sizeof(resa)); + } else { + struct res_evt_channel_open res; + res.ico_head.size = sizeof(res); + res.ico_head.id = MESSAGE_RES_EVT_OPEN_CHANNEL; + res.ico_head.error = (ret == 0 ? SA_AIS_OK : SA_AIS_ERR_BAD_HANDLE); + res.ico_channel_handle = handle; +- openais_conn_send_response(ocp->ocp_conn, &res, sizeof(res)); ++ openais_response_send(ocp->ocp_conn, &res, sizeof(res)); + } + + if (timer_del_status == 0) { +@@ -3553,7 +3555,7 @@ + res.iuc_head.size = sizeof(res); + res.iuc_head.id = MESSAGE_RES_EVT_UNLINK_CHANNEL; + res.iuc_head.error = SA_AIS_OK; +- openais_conn_send_response(ucp->ucp_conn, &res, sizeof(res)); ++ openais_response_send(ucp->ucp_conn, &res, sizeof(res)); + + free(ucp); + } +@@ -3573,7 +3575,7 @@ + res.iec_head.size = sizeof(res); + res.iec_head.id = MESSAGE_RES_EVT_CLEAR_RETENTIONTIME; + res.iec_head.error = ret; +- openais_conn_send_response(rtc->rtc_conn, &res, sizeof(res)); ++ openais_response_send(rtc->rtc_conn, &res, sizeof(res)); + + list_del(&rtc->rtc_entry); + free(rtc); +diff -uNr openais-0.80.3/exec/ipc.c openais-0.80.3-r1661/exec/ipc.c +--- openais-0.80.3/exec/ipc.c 2007-06-25 04:22:54.000000000 +0200 ++++ openais-0.80.3-r1661/exec/ipc.c 2008-11-17 15:54:02.380604445 +0100 +@@ -1,5 +1,4 @@ + /* +- * Copyright (c) 2002-2006 MontaVista Software, Inc. + * Copyright (c) 2006-2007 Red Hat, Inc. + * + * All rights reserved. +@@ -32,6 +31,9 @@ + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE 1 ++#endif + #include <pthread.h> + #include <assert.h> + #include <pwd.h> +@@ -54,7 +56,11 @@ + #include <signal.h> + #include <sched.h> + #include <time.h> ++#if defined(HAVE_GETPEERUCRED) ++#include <ucred.h> ++#endif + ++#include "swab.h" + #include "../include/saAis.h" + #include "../include/list.h" + #include "../include/queue.h" +@@ -66,6 +72,8 @@ + #include "mainconfig.h" + #include "totemconfig.h" + #include "main.h" ++#include "flow.h" ++#include "tlist.h" + #include "ipc.h" + #include "flow.h" + #include "service.h" +@@ -79,6 +87,10 @@ + + #include "util.h" + ++#ifdef OPENAIS_SOLARIS ++#define MSG_NOSIGNAL 0 ++#endif ++ + #define SERVER_BACKLOG 5 + + /* +@@ -94,11 +106,11 @@ + + static unsigned int g_gid_valid = 0; + +-static struct totem_ip_address *my_ip; +- + static totempg_groups_handle ipc_handle; + +-DECLARE_LIST_INIT (conn_info_list_head); ++static pthread_mutex_t conn_io_list_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++DECLARE_LIST_INIT (conn_io_list_head); + + static void (*ipc_serialize_lock_fn) (void); + +@@ -109,148 +121,282 @@ + size_t mlen; + }; + +-enum conn_state { +- CONN_STATE_ACTIVE, +- CONN_STATE_SECURITY, +- CONN_STATE_REQUESTED, +- CONN_STATE_CLOSED, +- CONN_STATE_DISCONNECTED ++enum conn_io_state { ++ CONN_IO_STATE_INITIALIZING, ++ CONN_IO_STATE_AUTHENTICATED, ++ CONN_IO_STATE_INIT_FAILED + }; + +-struct conn_info { +- int fd; /* File descriptor */ +- unsigned int events; /* events polled for by file descriptor */ +- enum conn_state state; /* State of this connection */ +- pthread_t thread; /* thread identifier */ ++enum conn_info_state { ++ CONN_INFO_STATE_INITIALIZING, ++ CONN_INFO_STATE_ACTIVE, ++ CONN_INFO_STATE_DISCONNECT_REQUESTED, ++ CONN_INFO_STATE_DISCONNECTED ++}; ++ ++struct conn_info; ++ ++struct conn_io { ++ int fd; /* File descriptor */ ++ unsigned int events; /* events polled for by file descriptor */ ++ pthread_t thread; /* thread identifier */ + pthread_attr_t thread_attr; /* thread attribute */ +- char *inb; /* Input buffer for non-blocking reads */ +- int inb_nextheader; /* Next message header starts here */ +- int inb_start; /* Start location of input buffer */ +- int inb_inuse; /* Bytes currently stored in input buffer */ +- struct queue outq; /* Circular queue for outgoing requests */ +- int byte_start; /* Byte to start sending from in head of queue */ +- enum service_types service;/* Type of service so dispatch knows how to route message */ +- int authenticated; /* Is this connection authenticated? */ +- void *private_data; /* library connection private data */ +- struct conn_info *conn_info_partner; /* partner connection dispatch<->response */ ++ char *inb; /* Input buffer for non-blocking reads */ ++ int inb_nextheader; /* Next message header starts here */ ++ int inb_start; /* Start location of input buffer */ ++ int inb_inuse; /* Bytes currently stored in input buffer */ ++ struct queue outq; /* Circular queue for outgoing requests */ ++ int byte_start; /* Byte to start sending from in head of queue */ ++ unsigned int fcc; /* flow control local count */ ++ enum conn_io_state state; /* state of this conn_io connection */ ++ struct conn_info *conn_info; /* connection information combining multiple conn_io structs */ ++ unsigned int refcnt; /* reference count for conn_io data structure */ ++ pthread_mutex_t mutex; ++ unsigned int service; ++ struct list_head list; ++}; ++ ++ ++struct conn_info { ++ enum conn_info_state state; /* State of this connection */ ++ enum service_types service; /* Type of service so dispatch knows how to route message */ ++ void *private_data; /* library connection private data */ + unsigned int flow_control_handle; /* flow control identifier */ + unsigned int flow_control_enabled; /* flow control enabled bit */ +- unsigned int flow_control_local_count; /* flow control local count */ + enum openais_flow_control flow_control; /* Does this service use IPC flow control */ + pthread_mutex_t flow_control_mutex; ++ unsigned int flow_control_local_count; /* flow control local count */ + int (*lib_exit_fn) (void *conn); +- struct timerlist timerlist; + pthread_mutex_t mutex; +- pthread_mutex_t *shared_mutex; +- struct list_head list; ++ struct conn_io *conn_io_response; ++ struct conn_io *conn_io_dispatch; ++ unsigned int refcnt; + }; + +-static void *prioritized_poll_thread (void *conn); +-static int conn_info_outq_flush (struct conn_info *conn_info); +-static void libais_deliver (struct conn_info *conn_info); +-static void ipc_flow_control (struct conn_info *conn_info); ++static void *prioritized_poll_thread (void *conn_io_in); ++static int conn_io_outq_flush (struct conn_io *conn_io); ++static void conn_io_deliver (struct conn_io *conn_io); ++//static void ipc_flow_control (struct conn_info *conn_info); ++static inline void conn_info_destroy (struct conn_info *conn_info); ++static void conn_io_destroy (struct conn_io *conn_io); ++static int conn_io_send (struct conn_io *conn_io, void *msg, int mlen); ++static inline struct conn_info *conn_info_create (void); ++static int conn_io_found (struct conn_io *conn_io_to_match); ++ ++static int response_init_send (struct conn_io *conn_io, void *message); ++static int dispatch_init_send (struct conn_io *conn_io, void *message); + + /* + * IPC Initializers + */ + +-static int response_init_send_response ( +- struct conn_info *conn_info, +- void *message); +-static int dispatch_init_send_response ( +- struct conn_info *conn_info, +- void *message); +- +-static int (*ais_init_service[]) (struct conn_info *conn_info, void *message) = { +- response_init_send_response, +- dispatch_init_send_response ++static int conn_io_refcnt_value (struct conn_io *conn_io) ++{ ++ unsigned int refcnt; ++ ++ pthread_mutex_lock (&conn_io->mutex); ++ refcnt = conn_io->refcnt; ++ pthread_mutex_unlock (&conn_io->mutex); ++ ++ return (refcnt); ++} ++ ++static void conn_io_refcnt_inc (struct conn_io *conn_io) ++{ ++ pthread_mutex_lock (&conn_io->mutex); ++ conn_io->refcnt += 1; ++ pthread_mutex_unlock (&conn_io->mutex); ++} ++ ++static int conn_io_refcnt_dec (struct conn_io *conn_io) ++{ ++ unsigned int refcnt; ++ ++ pthread_mutex_lock (&conn_io->mutex); ++ conn_io->refcnt -= 1; ++ refcnt = conn_io->refcnt; ++ pthread_mutex_unlock (&conn_io->mutex); ++ ++ return (refcnt); ++} ++ ++static void conn_info_refcnt_inc (struct conn_info *conn_info) ++{ ++ /* ++ * Connection not fully initialized yet ++ */ ++ if (conn_info == NULL) { ++ return; ++ } ++ pthread_mutex_lock (&conn_info->mutex); ++ conn_info->refcnt += 1; ++ pthread_mutex_unlock (&conn_info->mutex); ++} ++ ++static void conn_info_refcnt_dec (struct conn_info *conn_info) ++{ ++ int refcnt; ++ ++ /* ++ * Connection not fully initialized yet ++ */ ++ if (conn_info == NULL) { ++ return; ++ } ++ pthread_mutex_lock (&conn_info->mutex); ++ conn_info->refcnt -= 1; ++ refcnt = conn_info->refcnt; ++ assert (refcnt >= 0); ++ pthread_mutex_unlock (&conn_info->mutex); ++ ++ if (refcnt == 0) { ++ conn_info_destroy (conn_info); ++ } ++} ++ ++void openais_conn_info_refcnt_dec (void *conn) ++{ ++ struct conn_info *conn_info = (struct conn_info *)conn; ++ ++ conn_info_refcnt_dec (conn_info); ++} ++ ++void openais_conn_info_refcnt_inc (void *conn) ++{ ++ struct conn_info *conn_info = (struct conn_info *)conn; ++ ++ conn_info_refcnt_inc (conn_info); ++} ++ ++static int (*ais_init_service[]) (struct conn_io *conn_io, void *message) = { ++ response_init_send, ++ dispatch_init_send + }; + +-static void libais_disconnect_security (struct conn_info *conn_info) ++static void disconnect_request (struct conn_info *conn_info) + { +- conn_info->state = CONN_STATE_SECURITY; +- close (conn_info->fd); ++unsigned int res; ++ /* ++ * connection not fully active yet ++ */ ++ if (conn_info == NULL) { ++ return; ++ } ++ /* ++ * We only want to decrement the reference count on these two ++ * conn_io contexts one time ++ */ ++ if (conn_info->state != CONN_INFO_STATE_ACTIVE) { ++ return; ++ } ++ res = conn_io_refcnt_dec (conn_info->conn_io_response); ++ res = conn_io_refcnt_dec (conn_info->conn_io_dispatch); ++ conn_info->state = CONN_INFO_STATE_DISCONNECT_REQUESTED; + } + +-static int response_init_send_response ( +- struct conn_info *conn_info, ++static int response_init_send ( ++ struct conn_io *conn_io, + void *message) + { + SaAisErrorT error = SA_AIS_ERR_ACCESS; +- uintptr_t cinfo = (uintptr_t)conn_info; ++ uintptr_t cinfo = (uintptr_t)conn_io; + mar_req_lib_response_init_t *req_lib_response_init = (mar_req_lib_response_init_t *)message; + mar_res_lib_response_init_t res_lib_response_init; + +- if (conn_info->authenticated) { +- conn_info->service = req_lib_response_init->resdis_header.service; ++ if (conn_io->state == CONN_IO_STATE_AUTHENTICATED) { + error = SA_AIS_OK; ++ conn_io->service = req_lib_response_init->resdis_header.service; + } + res_lib_response_init.header.size = sizeof (mar_res_lib_response_init_t); + res_lib_response_init.header.id = MESSAGE_RES_INIT; + res_lib_response_init.header.error = error; + res_lib_response_init.conn_info = (mar_uint64_t)cinfo; + +- openais_conn_send_response ( +- conn_info, ++ conn_io_send ( ++ conn_io, + &res_lib_response_init, + sizeof (res_lib_response_init)); + + if (error == SA_AIS_ERR_ACCESS) { +- libais_disconnect_security (conn_info); ++ conn_io_destroy (conn_io); + return (-1); + } ++ + return (0); + } + +-static int dispatch_init_send_response ( +- struct conn_info *conn_info, ++/* ++ * This is called iwth ipc_serialize_lock_fn() called ++ * Therefore there are no races with the destruction of the conn_io ++ * data structure ++ */ ++static int dispatch_init_send ( ++ struct conn_io *conn_io, + void *message) + { + SaAisErrorT error = SA_AIS_ERR_ACCESS; + uintptr_t cinfo; + mar_req_lib_dispatch_init_t *req_lib_dispatch_init = (mar_req_lib_dispatch_init_t *)message; + mar_res_lib_dispatch_init_t res_lib_dispatch_init; +- struct conn_info *msg_conn_info; ++ struct conn_io *msg_conn_io; ++ struct conn_info *conn_info; ++ unsigned int service; ++ ++ service = req_lib_dispatch_init->resdis_header.service; ++ cinfo = (uintptr_t)req_lib_dispatch_init->conn_info; ++ msg_conn_io = (struct conn_io *)cinfo; + +- if (conn_info->authenticated) { +- conn_info->service = req_lib_dispatch_init->resdis_header.service; +- if (!ais_service[req_lib_dispatch_init->resdis_header.service]) ++ /* ++ * The response IPC connection has disconnected already for ++ * some reason and is no longer referenceable in the system ++ */ ++ if (conn_io->state == CONN_IO_STATE_AUTHENTICATED) { ++ /* ++ * If the response conn_io isn't found, it disconnected. ++ * Hence, a full connection cannot be made and this connection ++ * should be aborted by the poll thread ++ */ ++ if (conn_io_found (msg_conn_io) == 0) { ++ error = SA_AIS_ERR_TRY_AGAIN; ++ conn_io->state = CONN_IO_STATE_INIT_FAILED; ++ } else ++ /* ++ * If no service is found for the requested library service, ++ * the proper service handler isn't loaded and this connection ++ * should be aborted by the poll thread ++ */ ++ if (ais_service[service] == NULL) { + error = SA_AIS_ERR_NOT_SUPPORTED; +- else ++ conn_io->state = CONN_IO_STATE_INIT_FAILED; ++ } else { + error = SA_AIS_OK; ++ } + +- cinfo = (uintptr_t)req_lib_dispatch_init->conn_info; +- conn_info->conn_info_partner = (struct conn_info *)cinfo; +- +- /* temporary fix for memory leak ++ /* ++ * The response and dispatch conn_io structures are available. ++ * Attempt to allocate the appropriate memory for the private ++ * data area + */ +- pthread_mutex_destroy (conn_info->conn_info_partner->shared_mutex); +- free (conn_info->conn_info_partner->shared_mutex); +- +- conn_info->conn_info_partner->shared_mutex = conn_info->shared_mutex; +- +- list_add (&conn_info_list_head, &conn_info->list); +- list_add (&conn_info_list_head, &conn_info->conn_info_partner->list); +- +- msg_conn_info = (struct conn_info *)cinfo; +- msg_conn_info->conn_info_partner = conn_info; +- + if (error == SA_AIS_OK) { + int private_data_size; + +- private_data_size = ais_service[req_lib_dispatch_init->resdis_header.service]->private_data_size; ++ conn_info = conn_info_create (); ++ private_data_size = ais_service[service]->private_data_size; + if (private_data_size) { + conn_info->private_data = malloc (private_data_size); + +- conn_info->conn_info_partner->private_data = conn_info->private_data; ++ /* ++ * No private data could be allocated so ++ * request the poll thread to abort ++ */ + if (conn_info->private_data == NULL) { ++ conn_io->state = CONN_IO_STATE_INIT_FAILED; + error = SA_AIS_ERR_NO_MEMORY; + } else { + memset (conn_info->private_data, 0, private_data_size); + } + } else { + conn_info->private_data = NULL; +- conn_info->conn_info_partner->private_data = NULL; + } + } + } +@@ -259,287 +405,203 @@ + res_lib_dispatch_init.header.id = MESSAGE_RES_INIT; + res_lib_dispatch_init.header.error = error; + +- openais_conn_send_response ( +- conn_info, +- &res_lib_dispatch_init, +- sizeof (res_lib_dispatch_init)); +- +- if (error == SA_AIS_ERR_ACCESS) { +- libais_disconnect_security (conn_info); +- return (-1); +- } + if (error != SA_AIS_OK) { ++ conn_io_send ( ++ conn_io, ++ &res_lib_dispatch_init, ++ sizeof (res_lib_dispatch_init)); ++ + return (-1); + } + +- conn_info->state = CONN_STATE_ACTIVE; +- conn_info->conn_info_partner->state = CONN_STATE_ACTIVE; +- conn_info->lib_exit_fn = ais_service[conn_info->service]->lib_exit_fn; ++ /* ++ * connect both dispatch and response conn_ios into the conn_info ++ * data structure ++ */ ++ conn_info->state = CONN_INFO_STATE_ACTIVE; ++ conn_info->lib_exit_fn = ais_service[service]->lib_exit_fn; ++ conn_info->conn_io_response = msg_conn_io; ++ conn_info->conn_io_response->conn_info = conn_info; ++ conn_info->conn_io_dispatch = conn_io; ++ conn_info->service = service; ++ conn_io->service = service; ++ conn_io->conn_info = conn_info; + ais_service[conn_info->service]->lib_init_fn (conn_info); + + conn_info->flow_control = ais_service[conn_info->service]->flow_control; +- conn_info->conn_info_partner->flow_control = ais_service[conn_info->service]->flow_control; + if (ais_service[conn_info->service]->flow_control == OPENAIS_FLOW_CONTROL_REQUIRED) { + openais_flow_control_ipc_init ( + &conn_info->flow_control_handle, + conn_info->service); + + } ++ ++ /* ++ * Tell the library the IPC connections are configured ++ */ ++ conn_io_send ( ++ conn_io, ++ &res_lib_dispatch_init, ++ sizeof (res_lib_dispatch_init)); + return (0); + } + + /* + * Create a connection data structure + */ +-static inline unsigned int conn_info_create (int fd) { ++static inline struct conn_info *conn_info_create (void) ++{ + struct conn_info *conn_info; +- int res; + + conn_info = malloc (sizeof (struct conn_info)); + if (conn_info == 0) { +- return (ENOMEM); ++ return (NULL); + } + + memset (conn_info, 0, sizeof (struct conn_info)); + +- res = queue_init (&conn_info->outq, SIZEQUEUE, ++ conn_info->refcnt = 2; ++ pthread_mutex_init (&conn_info->mutex, NULL); ++ conn_info->state = CONN_INFO_STATE_INITIALIZING; ++ ++ return (conn_info); ++} ++ ++static inline void conn_info_destroy (struct conn_info *conn_info) ++{ ++ if (conn_info->private_data) { ++ free (conn_info->private_data); ++ } ++ pthread_mutex_destroy (&conn_info->mutex); ++ free (conn_info); ++} ++ ++static int conn_io_create (int fd) ++{ ++ int res; ++ struct conn_io *conn_io; ++ ++ conn_io = malloc (sizeof (struct conn_io)); ++ if (conn_io == NULL) { ++ return (-1); ++ } ++ memset (conn_io, 0, sizeof (struct conn_io)); ++ ++ res = queue_init (&conn_io->outq, SIZEQUEUE, + sizeof (struct outq_item)); + if (res != 0) { +- free (conn_info); +- return (ENOMEM); ++ return (-1); + } +- conn_info->inb = malloc (sizeof (char) * SIZEINB); +- if (conn_info->inb == NULL) { +- queue_free (&conn_info->outq); +- free (conn_info); +- return (ENOMEM); +- } +- conn_info->shared_mutex = malloc (sizeof (pthread_mutex_t)); +- if (conn_info->shared_mutex == NULL) { +- free (conn_info->inb); +- queue_free (&conn_info->outq); +- free (conn_info); +- return (ENOMEM); ++ ++ conn_io->inb = malloc (sizeof (char) * SIZEINB); ++ if (conn_io->inb == NULL) { ++ queue_free (&conn_io->outq); ++ return (-1); + } + +- pthread_mutex_init (&conn_info->mutex, NULL); +- pthread_mutex_init (&conn_info->flow_control_mutex, NULL); +- pthread_mutex_init (conn_info->shared_mutex, NULL); ++ conn_io->fd = fd; ++ conn_io->events = POLLIN|POLLNVAL; ++ conn_io->refcnt = 1; ++ conn_io->service = SOCKET_SERVICE_INIT; ++ conn_io->state = CONN_IO_STATE_INITIALIZING; + +- list_init (&conn_info->list); +- conn_info->state = CONN_STATE_ACTIVE; +- conn_info->fd = fd; +- conn_info->events = POLLIN|POLLNVAL; +- conn_info->service = SOCKET_SERVICE_INIT; ++ pthread_attr_init (&conn_io->thread_attr); + +- pthread_attr_init (&conn_info->thread_attr); +-/* +- * IA64 needs more stack space then other arches +- */ ++ pthread_mutex_init (&conn_io->mutex, NULL); ++ ++ /* ++ * IA64 needs more stack space then other arches ++ */ + #if defined(__ia64__) +- pthread_attr_setstacksize (&conn_info->thread_attr, 400000); ++ pthread_attr_setstacksize (&conn_io->thread_attr, 400000); + #else +- pthread_attr_setstacksize (&conn_info->thread_attr, 200000); ++ pthread_attr_setstacksize (&conn_io->thread_attr, 200000); + #endif + +- pthread_attr_setdetachstate (&conn_info->thread_attr, PTHREAD_CREATE_DETACHED); +- res = pthread_create (&conn_info->thread, &conn_info->thread_attr, +- prioritized_poll_thread, conn_info); ++ pthread_attr_setdetachstate (&conn_io->thread_attr, PTHREAD_CREATE_DETACHED); ++ ++ res = pthread_create (&conn_io->thread, &conn_io->thread_attr, ++ prioritized_poll_thread, conn_io); ++ ++ list_init (&conn_io->list); ++ ++ pthread_mutex_lock (&conn_io_list_mutex); ++ list_add (&conn_io->list, &conn_io_list_head); ++ pthread_mutex_unlock (&conn_io_list_mutex); + return (res); + } + +-static void conn_info_destroy (struct conn_info *conn_info) ++static void conn_io_destroy (struct conn_io *conn_io) + { + struct outq_item *outq_item; + + /* + * Free the outq queued items + */ +- while (!queue_is_empty (&conn_info->outq)) { +- outq_item = queue_item_get (&conn_info->outq); ++ while (!queue_is_empty (&conn_io->outq)) { ++ outq_item = queue_item_get (&conn_io->outq); + free (outq_item->msg); +- queue_item_remove (&conn_info->outq); ++ queue_item_remove (&conn_io->outq); + } + +- queue_free (&conn_info->outq); +- free (conn_info->inb); +- if (conn_info->conn_info_partner) { +- conn_info->conn_info_partner->conn_info_partner = NULL; +- } ++ queue_free (&conn_io->outq); ++ free (conn_io->inb); ++ close (conn_io->fd); ++ pthread_mutex_lock (&conn_io_list_mutex); ++ list_del (&conn_io->list); ++ pthread_mutex_unlock (&conn_io_list_mutex); + +- pthread_attr_destroy (&conn_info->thread_attr); +- pthread_mutex_destroy (&conn_info->mutex); +- +- list_del (&conn_info->list); +- free (conn_info); +-} +- +-static int libais_connection_active (struct conn_info *conn_info) +-{ +- return (conn_info->state == CONN_STATE_ACTIVE); ++ pthread_attr_destroy (&conn_io->thread_attr); ++ pthread_mutex_destroy (&conn_io->mutex); ++ free (conn_io); + } + +-static void libais_disconnect_request (struct conn_info *conn_info) ++static int conn_io_found (struct conn_io *conn_io_to_match) + { +- if (conn_info->state == CONN_STATE_ACTIVE) { +- conn_info->state = CONN_STATE_REQUESTED; +- conn_info->conn_info_partner->state = CONN_STATE_REQUESTED; +- } +-} ++ struct list_head *list; ++ struct conn_io *conn_io; + +-static int libais_disconnect (struct conn_info *conn_info) +-{ +- int res = 0; +- +- assert (conn_info->state != CONN_STATE_ACTIVE); +- +- if (conn_info->state == CONN_STATE_DISCONNECTED) { +- assert (0); +- } +- +- /* +- * Close active connections +- */ +- if (conn_info->state == CONN_STATE_ACTIVE || conn_info->state == CONN_STATE_REQUESTED) { +- close (conn_info->fd); +- conn_info->state = CONN_STATE_CLOSED; +- close (conn_info->conn_info_partner->fd); +- conn_info->conn_info_partner->state = CONN_STATE_CLOSED; +- } +- +- /* +- * Note we will only call the close operation once on the first time +- * one of the connections is closed +- */ +- if (conn_info->state == CONN_STATE_CLOSED) { +- if (conn_info->lib_exit_fn) { +- res = conn_info->lib_exit_fn (conn_info); +- } +- if (res == -1) { +- return (-1); +- } +- if (conn_info->conn_info_partner->lib_exit_fn) { +- res = conn_info->conn_info_partner->lib_exit_fn (conn_info); +- } +- if (res == -1) { +- return (-1); ++ for (list = conn_io_list_head.next; list != &conn_io_list_head; ++ list = list->next) { ++ ++ conn_io = list_entry (list, struct conn_io, list); ++ if (conn_io == conn_io_to_match) { ++ return (1); + } + } +- conn_info->state = CONN_STATE_DISCONNECTED; +- conn_info->conn_info_partner->state = CONN_STATE_DISCONNECTED; +- if (conn_info->flow_control_enabled == 1) { +- openais_flow_control_disable (conn_info->flow_control_handle); +- } +- return (0); +-} + +-static inline void conn_info_mutex_lock ( +- struct conn_info *conn_info, +- unsigned int service) +-{ +- if (service == SOCKET_SERVICE_INIT) { +- pthread_mutex_lock (&conn_info->mutex); +- } else { +- pthread_mutex_lock (conn_info->shared_mutex); +- } +-} +-static inline void conn_info_mutex_unlock ( +- struct conn_info *conn_info, +- unsigned int service) +-{ +- if (service == SOCKET_SERVICE_INIT) { +- pthread_mutex_unlock (&conn_info->mutex); +- } else { +- pthread_mutex_unlock (conn_info->shared_mutex); +- } ++ return (0); + } + + /* + * This thread runs in a specific thread priority mode to handle +- * I/O requests from the library ++ * I/O requests from or to the library + */ +-static void *prioritized_poll_thread (void *conn) ++static void *prioritized_poll_thread (void *conn_io_in) + { +- struct conn_info *conn_info = (struct conn_info *)conn; ++ struct conn_io *conn_io = (struct conn_io *)conn_io_in; ++ struct conn_info *conn_info = NULL; + struct pollfd ufd; + int fds; + struct sched_param sched_param; + int res; +- pthread_mutex_t *rel_mutex; +- unsigned int service; +- struct conn_info *cinfo_partner; +- void *private_data; + +-#if defined(OPENAIS_BSD) || defined(OPENAIS_LINUX) +- res = sched_get_priority_max (SCHED_RR); +- if (res != -1) { +- sched_param.sched_priority = res; +- res = pthread_setschedparam (conn_info->thread, SCHED_RR, &sched_param); +- if (res == -1) { +- log_printf (LOG_LEVEL_WARNING, "Could not set SCHED_RR at priority %d: %s\n", +- sched_param.sched_priority, strerror (errno)); +- } +- } else +- log_printf (LOG_LEVEL_WARNING, "Could not get maximum scheduler priority: %s\n", strerror (errno)); +-#else +- log_printf(LOG_LEVEL_WARNING, "Scheduler priority left to default value (no OS support)\n"); +-#endif ++ sched_param.sched_priority = 99; ++ res = pthread_setschedparam (conn_io->thread, SCHED_RR, &sched_param); + +- ufd.fd = conn_info->fd; ++ ufd.fd = conn_io->fd; + for (;;) { + retry_poll: +- service = conn_info->service; +- ufd.events = conn_info->events; ++ conn_info = conn_io->conn_info; ++ conn_io_refcnt_inc (conn_io); ++ conn_info_refcnt_inc (conn_info); ++ ++ ufd.events = conn_io->events; + ufd.revents = 0; + fds = poll (&ufd, 1, -1); +- +- conn_info_mutex_lock (conn_info, service); +- +- switch (conn_info->state) { +- case CONN_STATE_SECURITY: +- conn_info_mutex_unlock (conn_info, service); +- pthread_mutex_destroy (conn_info->shared_mutex); +- free (conn_info->shared_mutex); +- conn_info_destroy (conn); +- pthread_exit (0); +- break; +- +- case CONN_STATE_REQUESTED: +- case CONN_STATE_CLOSED: +- res = libais_disconnect (conn); +- if (res != 0) { +- conn_info_mutex_unlock (conn_info, service); +- goto retry_poll; +- } +- break; +- +- case CONN_STATE_DISCONNECTED: +- rel_mutex = conn_info->shared_mutex; +- private_data = conn_info->private_data; +- cinfo_partner = conn_info->conn_info_partner; +- conn_info_destroy (conn); +- if (service == SOCKET_SERVICE_INIT) { +- pthread_mutex_unlock (&conn_info->mutex); +- } else { +- pthread_mutex_unlock (rel_mutex); +- } +- if (cinfo_partner == NULL) { +- pthread_mutex_destroy (rel_mutex); +- free (rel_mutex); +- free (private_data); +- } +- pthread_exit (0); +- /* +- * !! NOTE !! this is the exit point for this thread +- */ +- break; +- +- default: +- break; +- } +- + if (fds == -1) { +- conn_info_mutex_unlock (conn_info, service); ++ conn_io_refcnt_dec (conn_io); ++ conn_info_refcnt_dec (conn_info); + goto retry_poll; + } + +@@ -547,49 +609,151 @@ + + if (fds == 1 && ufd.revents) { + if (ufd.revents & (POLLERR|POLLHUP)) { ++ disconnect_request (conn_info); ++ conn_info_refcnt_dec (conn_info); ++ conn_io_refcnt_dec (conn_io); ++ /* ++ * If conn_info not set, wait for it to be set ++ * else break out of for loop ++ */ ++ if (conn_info == NULL) { ++ ipc_serialize_unlock_fn (); ++ continue; ++ } else { ++ ipc_serialize_unlock_fn (); ++ break; ++ } ++ } + +- libais_disconnect_request (conn_info); +- +- conn_info_mutex_unlock (conn_info, service); ++ if (conn_info && conn_info->state == CONN_INFO_STATE_DISCONNECT_REQUESTED) { ++ conn_info_refcnt_dec (conn_info); ++ conn_io_refcnt_dec (conn_io); + ipc_serialize_unlock_fn (); +- continue; ++ break; + } + + if (ufd.revents & POLLOUT) { +- conn_info_outq_flush (conn_info); ++ conn_io_outq_flush (conn_io); + } + + if ((ufd.revents & POLLIN) == POLLIN) { +- libais_deliver (conn_info); ++ conn_io_deliver (conn_io); + } + +- ipc_flow_control (conn_info); ++ /* ++ * IPC initializiation failed because response fd ++ * disconnected before it was linked to dispatch fd ++ */ ++ if (conn_io->state == CONN_IO_STATE_INIT_FAILED) { ++ conn_io_destroy (conn_io); ++ conn_info_refcnt_dec (conn_info); ++ ipc_serialize_unlock_fn (); ++ pthread_exit (0); ++ } ++ /* ++ * IPC initializiation failed because response fd ++ * disconnected before it was linked to dispatch fd ++ */ ++ if (conn_io->state == CONN_IO_STATE_INIT_FAILED) { ++ break; ++ } ++ ++// ipc_flow_control (conn_info); + + } + + ipc_serialize_unlock_fn (); +- conn_info_mutex_unlock (conn_info, service); ++ ++ conn_io_refcnt_dec (conn_io); ++ conn_info_refcnt_dec (conn_info); ++ } ++ ++ ipc_serialize_lock_fn (); ++ ++ /* ++ * IPC initializiation failed because response fd ++ * disconnected before it was linked to dispatch fd ++ */ ++ if (conn_io->conn_info == NULL || conn_io->state == CONN_IO_STATE_INIT_FAILED) { ++ conn_io_destroy (conn_io); ++ conn_info_refcnt_dec (conn_info); ++ ipc_serialize_unlock_fn (); ++ pthread_exit (0); + } + ++ conn_info = conn_io->conn_info; ++ ++ /* ++ * This is the response conn_io ++ */ ++ if (conn_info->conn_io_response == conn_io) { ++ for (;;) { ++ if (conn_io_refcnt_value (conn_io) == 0) { ++ conn_io->conn_info = NULL; ++ conn_io_destroy (conn_io); ++ conn_info_refcnt_dec (conn_info); ++ ipc_serialize_unlock_fn (); ++ pthread_exit (0); ++ } ++ usleep (1000); ++ printf ("sleep 1\n"); ++ } ++ } /* response conn_io */ ++ ++ /* ++ * This is the dispatch conn_io ++ */ ++ if (conn_io->conn_info->conn_io_dispatch == conn_io) { ++ ipc_serialize_unlock_fn (); ++ for (;;) { ++ ipc_serialize_lock_fn (); ++ if (conn_io_refcnt_value (conn_io) == 0) { ++ res = 0; // TODO ++ /* ++ * Execute the library exit function ++ */ ++ if (conn_io->conn_info->lib_exit_fn) { ++ res = conn_io->conn_info->lib_exit_fn (conn_info); ++ } ++ if (res == 0) { ++ if (conn_io->conn_info->flow_control_enabled == 1) { ++// openais_flow_control_disable ( ++// conn_info->flow_control_handle); ++ } ++ conn_io->conn_info = NULL; ++ conn_io_destroy (conn_io); ++ conn_info_refcnt_dec (conn_info); ++ ipc_serialize_unlock_fn (); ++ pthread_exit (0); ++ } ++ } /* refcnt == 0 */ ++ ipc_serialize_unlock_fn (); ++ usleep (1000); ++ } /* for (;;) */ ++ } /* dispatch conn_io */ ++ + /* + * This code never reached + */ + return (0); + } + +-#if defined(OPENAIS_LINUX) ++#if defined(OPENAIS_LINUX) || defined(OPENAIS_SOLARIS) + /* SUN_LEN is broken for abstract namespace + */ + #define AIS_SUN_LEN(a) sizeof(*(a)) +- +-char *socketname = "libais.socket"; + #else + #define AIS_SUN_LEN(a) SUN_LEN(a) ++#endif + ++#if defined(OPENAIS_LINUX) ++char *socketname = "libais.socket"; ++#else + char *socketname = "/var/run/libais.socket"; + #endif + + ++#ifdef COMPILOE_OUT + static void ipc_flow_control (struct conn_info *conn_info) + { + unsigned int entries_used; +@@ -647,8 +811,9 @@ + } + } + } ++#endif + +-static int conn_info_outq_flush (struct conn_info *conn_info) { ++static int conn_io_outq_flush (struct conn_io *conn_io) { + struct queue *outq; + int res = 0; + struct outq_item *queue_item; +@@ -656,46 +821,51 @@ + struct iovec iov_send; + char *msg_addr; + +- if (!libais_connection_active (conn_info)) { +- return (-1); +- } +- outq = &conn_info->outq; ++ outq = &conn_io->outq; + + msg_send.msg_iov = &iov_send; + msg_send.msg_name = 0; + msg_send.msg_namelen = 0; + msg_send.msg_iovlen = 1; ++#ifndef OPENAIS_SOLARIS + msg_send.msg_control = 0; + msg_send.msg_controllen = 0; + msg_send.msg_flags = 0; ++#else ++ msg_send.msg_accrights = 0; ++ msg_send.msg_accrightslen = 0; ++#endif + ++ pthread_mutex_lock (&conn_io->mutex); + while (!queue_is_empty (outq)) { + queue_item = queue_item_get (outq); + msg_addr = (char *)queue_item->msg; +- msg_addr = &msg_addr[conn_info->byte_start]; ++ msg_addr = &msg_addr[conn_io->byte_start]; + + iov_send.iov_base = msg_addr; +- iov_send.iov_len = queue_item->mlen - conn_info->byte_start; ++ iov_send.iov_len = queue_item->mlen - conn_io->byte_start; + + retry_sendmsg: +- res = sendmsg (conn_info->fd, &msg_send, MSG_NOSIGNAL); ++ res = sendmsg (conn_io->fd, &msg_send, MSG_NOSIGNAL); + if (res == -1 && errno == EINTR) { + goto retry_sendmsg; + } + if (res == -1 && errno == EAGAIN) { ++ pthread_mutex_unlock (&conn_io->mutex); + return (0); + } + if (res == -1 && errno == EPIPE) { +- libais_disconnect_request (conn_info); ++ disconnect_request (conn_io->conn_info); ++ pthread_mutex_unlock (&conn_io->mutex); + return (0); + } + if (res == -1) { +- printf ("ERRNO is %d\n", errno); + assert (0); /* some other unhandled error here */ + } +- if (res + conn_info->byte_start != queue_item->mlen) { +- conn_info->byte_start += res; ++ if (res + conn_io->byte_start != queue_item->mlen) { ++ conn_io->byte_start += res; + ++ pthread_mutex_unlock (&conn_io->mutex); + return (0); + } + +@@ -703,14 +873,15 @@ + * Message sent, try sending another message + */ + queue_item_remove (outq); +- conn_info->byte_start = 0; ++ conn_io->byte_start = 0; + free (queue_item->msg); + } /* while queue not empty */ + + if (queue_is_empty (outq)) { +- conn_info->events = POLLIN|POLLNVAL; ++ conn_io->events = POLLIN|POLLNVAL; + } + ++ pthread_mutex_unlock (&conn_io->mutex); + return (0); + } + +@@ -721,7 +892,7 @@ + char buf[4096]; + }; + +-static void libais_deliver (struct conn_info *conn_info) ++static void conn_io_deliver (struct conn_io *conn_io) + { + int res; + mar_req_header_t *header; +@@ -733,9 +904,6 @@ + char cmsg_cred[CMSG_SPACE (sizeof (struct ucred))]; + struct ucred *cred; + int on = 0; +-#else +- uid_t euid; +- gid_t egid; + #endif + int send_ok = 0; + int send_ok_joined = 0; +@@ -746,9 +914,10 @@ + msg_recv.msg_iovlen = 1; + msg_recv.msg_name = 0; + msg_recv.msg_namelen = 0; ++#ifndef OPENAIS_SOLARIS + msg_recv.msg_flags = 0; + +- if (conn_info->authenticated) { ++ if (conn_io->state == CONN_IO_STATE_AUTHENTICATED) { + msg_recv.msg_control = 0; + msg_recv.msg_controllen = 0; + } else { +@@ -756,25 +925,61 @@ + msg_recv.msg_control = (void *)cmsg_cred; + msg_recv.msg_controllen = sizeof (cmsg_cred); + #else +- euid = -1; egid = -1; +- if (getpeereid(conn_info->fd, &euid, &egid) != -1 && +- (euid == 0 || egid == g_gid_valid)) { +- conn_info->authenticated = 1; +- } +- if (conn_info->authenticated == 0) { +- log_printf (LOG_LEVEL_SECURITY, "Connection not authenticated because gid is %d, expecting %d\n", egid, g_gid_valid); ++ { ++ uid_t euid; ++ gid_t egid; ++ ++ euid = -1; egid = -1; ++ if (getpeereid(conn_io->fd, &euid, &egid) != -1 && ++ (euid == 0 || egid == g_gid_valid)) { ++ conn_io->state = CONN_IO_STATE_AUTHENTICATED; ++ } ++ if (conn_io->state == CONN_IO_STATE_INITIALIZING) { ++ log_printf (LOG_LEVEL_SECURITY, "Connection not authenticated because gid is %d, expecting %d\n", egid, g_gid_valid); ++ } + } + #endif + } + +- iov_recv.iov_base = &conn_info->inb[conn_info->inb_start]; +- iov_recv.iov_len = (SIZEINB) - conn_info->inb_start; +- if (conn_info->inb_inuse == SIZEINB) { ++#else /* OPENAIS_SOLARIS */ ++ msg_recv.msg_accrights = 0; ++ msg_recv.msg_accrightslen = 0; ++ ++ ++ if (! conn_info->authenticated) { ++#ifdef HAVE_GETPEERUCRED ++ ucred_t *uc; ++ uid_t euid = -1; ++ gid_t egid = -1; ++ ++ if (getpeerucred (conn_info->fd, &uc) == 0) { ++ euid = ucred_geteuid (uc); ++ egid = ucred_getegid (uc); ++ if ((euid == 0) || (egid == g_gid_valid)) { ++ conn_info->authenticated = 1; ++ } ++ ucred_free(uc); ++ } ++ if (conn_info->authenticated == 0) { ++ log_printf (LOG_LEVEL_SECURITY, "Connection not authenticated because gid is %d, expecting %d\n", (int)egid, g_gid_valid); ++ } ++ #else ++ log_printf (LOG_LEVEL_SECURITY, "Connection not authenticated " ++ "because platform does not support " ++ "authentication with sockets, continuing " ++ "with a fake authentication\n"); ++ conn_info->authenticated = 1; ++ #endif ++ } ++ #endif ++ iov_recv.iov_base = &conn_io->inb[conn_io->inb_start]; ++ iov_recv.iov_len = (SIZEINB) - conn_io->inb_start; ++ if (conn_io->inb_inuse == SIZEINB) { + return; + } + + retry_recv: +- res = recvmsg (conn_info->fd, &msg_recv, MSG_NOSIGNAL); ++ res = recvmsg (conn_io->fd, &msg_recv, MSG_NOSIGNAL); + if (res == -1 && errno == EINTR) { + goto retry_recv; + } else +@@ -786,7 +991,7 @@ + /* On many OS poll never return POLLHUP or POLLERR. + * EOF is detected when recvmsg return 0. + */ +- libais_disconnect_request (conn_info); ++ disconnect_request (conn_io); + #endif + return; + } +@@ -795,17 +1000,17 @@ + * Authenticate if this connection has not been authenticated + */ + #ifdef OPENAIS_LINUX +- if (conn_info->authenticated == 0) { ++ if (conn_io->state == CONN_IO_STATE_INITIALIZING) { + cmsg = CMSG_FIRSTHDR (&msg_recv); + assert (cmsg); + cred = (struct ucred *)CMSG_DATA (cmsg); + if (cred) { + if (cred->uid == 0 || cred->gid == g_gid_valid) { +- setsockopt(conn_info->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)); +- conn_info->authenticated = 1; ++ setsockopt(conn_io->fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)); ++ conn_io->state = CONN_IO_STATE_AUTHENTICATED; + } + } +- if (conn_info->authenticated == 0) { ++ if (conn_io->state == CONN_IO_STATE_INITIALIZING) { + log_printf (LOG_LEVEL_SECURITY, "Connection not authenticated because gid is %d, expecting %d\n", cred->gid, g_gid_valid); + } + } +@@ -814,23 +1019,23 @@ + * Dispatch all messages received in recvmsg that can be dispatched + * sizeof (mar_req_header_t) needed at minimum to do any processing + */ +- conn_info->inb_inuse += res; +- conn_info->inb_start += res; ++ conn_io->inb_inuse += res; ++ conn_io->inb_start += res; + +- while (conn_info->inb_inuse >= sizeof (mar_req_header_t) && res != -1) { +- header = (mar_req_header_t *)&conn_info->inb[conn_info->inb_start - conn_info->inb_inuse]; ++ while (conn_io->inb_inuse >= sizeof (mar_req_header_t) && res != -1) { ++ header = (mar_req_header_t *)&conn_io->inb[conn_io->inb_start - conn_io->inb_inuse]; + +- if (header->size > conn_info->inb_inuse) { ++ if (header->size > conn_io->inb_inuse) { + break; + } +- service = conn_info->service; ++ service = conn_io->service; + + /* + * If this service is in init phase, initialize service + * else handle message using service service + */ +- if (service == SOCKET_SERVICE_INIT) { +- res = ais_init_service[header->id] (conn_info, header); ++ if (conn_io->service == SOCKET_SERVICE_INIT) { ++ res = ais_init_service[header->id] (conn_io, header); + } else { + /* + * Not an init service, but a standard service +@@ -847,7 +1052,7 @@ + * to queue a message, otherwise tell the library we are busy and to + * try again later + */ +- send_ok_joined_iovec.iov_base = header; ++ send_ok_joined_iovec.iov_base = (char *)header; + send_ok_joined_iovec.iov_len = header->size; + send_ok_joined = totempg_groups_send_ok_joined (openais_group_handle, + &send_ok_joined_iovec, 1); +@@ -860,7 +1065,7 @@ + (sync_in_process() == 0))); + + if (send_ok) { +- ais_service[service]->lib_service[header->id].lib_handler_fn(conn_info, header); ++ ais_service[service]->lib_service[header->id].lib_handler_fn(conn_io->conn_info, header); + } else { + + /* +@@ -871,33 +1076,33 @@ + res_overlay.header.id = + ais_service[service]->lib_service[header->id].response_id; + res_overlay.header.error = SA_AIS_ERR_TRY_AGAIN; +- openais_conn_send_response ( +- conn_info, ++ conn_io_send ( ++ conn_io, + &res_overlay, + res_overlay.header.size); + } + } +- conn_info->inb_inuse -= header->size; ++ conn_io->inb_inuse -= header->size; + } /* while */ + +- if (conn_info->inb_inuse == 0) { +- conn_info->inb_start = 0; ++ if (conn_io->inb_inuse == 0) { ++ conn_io->inb_start = 0; + } else +-// BUG if (connections[conn_info->fd].inb_start + connections[conn_info->fd].inb_inuse >= SIZEINB) { +- if (conn_info->inb_start >= SIZEINB) { ++// BUG if (connections[conn_io->fd].inb_start + connections[conn_io->fd].inb_inuse >= SIZEINB) { ++ if (conn_io->inb_start >= SIZEINB) { + /* + * If in buffer is full, move it back to start + */ +- memmove (conn_info->inb, +- &conn_info->inb[conn_info->inb_start - conn_info->inb_inuse], +- sizeof (char) * conn_info->inb_inuse); +- conn_info->inb_start = conn_info->inb_inuse; ++ memmove (conn_io->inb, ++ &conn_io->inb[conn_io->inb_start - conn_io->inb_inuse], ++ sizeof (char) * conn_io->inb_inuse); ++ conn_io->inb_start = conn_io->inb_inuse; + } + + return; + } + +-static int poll_handler_libais_accept ( ++static int poll_handler_accept ( + poll_handle handle, + int fd, + int revent, +@@ -945,7 +1150,7 @@ + + log_printf (LOG_LEVEL_DEBUG, "connection received from libais client %d.\n", new_fd); + +- res = conn_info_create (new_fd); ++ res = conn_io_create (new_fd); + if (res != 0) { + close (new_fd); + } +@@ -961,7 +1166,7 @@ + int ret = 0; + + assert (source != NULL); +- if (source->nodeid == my_ip->nodeid) { ++ if (source->nodeid == totempg_my_nodeid_get ()) { + ret = 1; + } + return ret; +@@ -973,7 +1178,7 @@ + { + assert ((source != NULL) && (conn != NULL)); + memset (source, 0, sizeof (mar_message_source_t)); +- source->nodeid = my_ip->nodeid; ++ source->nodeid = totempg_my_nodeid_get (); + source->conn = conn; + } + +@@ -989,15 +1194,12 @@ + void openais_ipc_init ( + void (*serialize_lock_fn) (void), + void (*serialize_unlock_fn) (void), +- unsigned int gid_valid, +- struct totem_ip_address *my_ip_in) ++ unsigned int gid_valid) + { + int libais_server_fd; + struct sockaddr_un un_addr; + int res; + +- log_init ("IPC"); +- + ipc_serialize_lock_fn = serialize_lock_fn; + + ipc_serialize_unlock_fn = serialize_unlock_fn; +@@ -1011,7 +1213,7 @@ + openais_exit_error (AIS_DONE_LIBAIS_SOCKET); + }; + +- totemip_nosigpipe(libais_server_fd); ++ totemip_nosigpipe (libais_server_fd); + res = fcntl (libais_server_fd, F_SETFL, O_NONBLOCK); + if (res == -1) { + log_printf (LOG_LEVEL_ERROR, "Could not set non-blocking operation on server socket: %s\n", strerror (errno)); +@@ -1043,12 +1245,10 @@ + * Setup libais connection dispatch routine + */ + poll_dispatch_add (aisexec_poll_handle, libais_server_fd, +- POLLIN, 0, poll_handler_libais_accept); ++ POLLIN, 0, poll_handler_accept); + + g_gid_valid = gid_valid; + +- my_ip = my_ip_in; +- + /* + * Reset internal state of flow control when + * configuration change occurs +@@ -1067,33 +1267,14 @@ + { + struct conn_info *conn_info = (struct conn_info *)conn; + +- if (conn != NULL) { +- return ((void *)conn_info->private_data); +- } else { +- return NULL; +- } ++ return (conn_info->private_data); + } + +-/* +- * Get the conn info partner connection +- */ +-void *openais_conn_partner_get (void *conn) +-{ +- struct conn_info *conn_info = (struct conn_info *)conn; +- +- if (conn != NULL) { +- return ((void *)conn_info->conn_info_partner); +- } else { +- return NULL; +- } +-} +- +-int openais_conn_send_response ( +- void *conn, ++static int conn_io_send ( ++ struct conn_io *conn_io, + void *msg, + int mlen) + { +- struct queue *outq; + char *cmsg; + int res = 0; + int queue_empty; +@@ -1102,47 +1283,47 @@ + struct msghdr msg_send; + struct iovec iov_send; + char *msg_addr; +- struct conn_info *conn_info = (struct conn_info *)conn; + +- if (conn_info == NULL) { +- return -1; +- } +- +- if (!libais_connection_active (conn_info)) { +- return (-1); ++ if (conn_io == NULL) { ++ assert (0); + } + +- ipc_flow_control (conn_info); +- +- outq = &conn_info->outq; ++// ipc_flow_control (conn_info); + + msg_send.msg_iov = &iov_send; + msg_send.msg_name = 0; + msg_send.msg_namelen = 0; + msg_send.msg_iovlen = 1; ++#ifndef OPENAIS_SOLARIS + msg_send.msg_control = 0; + msg_send.msg_controllen = 0; + msg_send.msg_flags = 0; ++#else ++ msg_send.msg_accrights = 0; ++ msg_send.msg_accrightslen = 0; ++#endif + +- if (queue_is_full (outq)) { ++ pthread_mutex_lock (&conn_io->mutex); ++ if (queue_is_full (&conn_io->outq)) { + /* + * Start a disconnect if we have not already started one + * and report that the outgoing queue is full + */ + log_printf (LOG_LEVEL_ERROR, "Library queue is full, disconnecting library connection.\n"); +- libais_disconnect_request (conn_info); ++ disconnect_request (conn_io->conn_info); ++ pthread_mutex_unlock (&conn_io->mutex); + return (-1); + } +- while (!queue_is_empty (outq)) { +- queue_item = queue_item_get (outq); ++ while (!queue_is_empty (&conn_io->outq)) { ++ queue_item = queue_item_get (&conn_io->outq); + msg_addr = (char *)queue_item->msg; +- msg_addr = &msg_addr[conn_info->byte_start]; ++ msg_addr = &msg_addr[conn_io->byte_start]; + + iov_send.iov_base = msg_addr; +- iov_send.iov_len = queue_item->mlen - conn_info->byte_start; ++ iov_send.iov_len = queue_item->mlen - conn_io->byte_start; + + retry_sendmsg: +- res = sendmsg (conn_info->fd, &msg_send, MSG_NOSIGNAL); ++ res = sendmsg (conn_io->fd, &msg_send, MSG_NOSIGNAL); + if (res == -1 && errno == EINTR) { + goto retry_sendmsg; + } +@@ -1150,29 +1331,30 @@ + break; /* outgoing kernel queue full */ + } + if (res == -1 && errno == EPIPE) { +- libais_disconnect_request (conn_info); ++ disconnect_request (conn_io->conn_info); ++ pthread_mutex_unlock (&conn_io->mutex); + return (0); + } + if (res == -1) { +- assert (0); ++// assert (0); + break; /* some other error, stop trying to send message */ + } +- if (res + conn_info->byte_start != queue_item->mlen) { +- conn_info->byte_start += res; ++ if (res + conn_io->byte_start != queue_item->mlen) { ++ conn_io->byte_start += res; + break; + } + + /* + * Message sent, try sending another message + */ +- queue_item_remove (outq); +- conn_info->byte_start = 0; ++ queue_item_remove (&conn_io->outq); ++ conn_io->byte_start = 0; + free (queue_item->msg); + } /* while queue not empty */ + + res = -1; + +- queue_empty = queue_is_empty (outq); ++ queue_empty = queue_is_empty (&conn_io->outq); + /* + * Send request message + */ +@@ -1181,21 +1363,19 @@ + iov_send.iov_base = msg; + iov_send.iov_len = mlen; + retry_sendmsg_two: +- res = sendmsg (conn_info->fd, &msg_send, MSG_NOSIGNAL); ++ res = sendmsg (conn_io->fd, &msg_send, MSG_NOSIGNAL); + if (res == -1 && errno == EINTR) { + goto retry_sendmsg_two; + } + if (res == -1 && errno == EAGAIN) { +- conn_info->byte_start = 0; +- conn_info->events = POLLIN|POLLNVAL; ++ conn_io->byte_start = 0; + } + if (res != -1) { + if (res != mlen) { +- conn_info->byte_start += res; ++ conn_io->byte_start += res; + res = -1; + } else { +- conn_info->byte_start = 0; +- conn_info->events = POLLIN|POLLNVAL; ++ conn_io->byte_start = 0; + } + } + } +@@ -1207,21 +1387,26 @@ + cmsg = malloc (mlen); + if (cmsg == 0) { + log_printf (LOG_LEVEL_ERROR, "Library queue couldn't allocate a message, disconnecting library connection.\n"); +- libais_disconnect_request (conn_info); ++ disconnect_request (conn_io->conn_info); ++ pthread_mutex_unlock (&conn_io->mutex); + return (-1); + } + queue_item_out.msg = cmsg; + queue_item_out.mlen = mlen; + memcpy (cmsg, msg, mlen); +- queue_item_add (outq, &queue_item_out); ++ queue_item_add (&conn_io->outq, &queue_item_out); + + /* +- * Send a pthread_kill to interrupt the poll syscall +- * and start a new poll operation in the thread ++ * Send a pthread_kill to interrupt the blocked poll syscall ++ * and start a new poll operation in the thread if ++ * POLLOUT is not already set + */ +- conn_info->events = POLLIN|POLLOUT|POLLNVAL; +- pthread_kill (conn_info->thread, SIGUSR1); ++ if (conn_io->events != (POLLIN|POLLOUT|POLLNVAL)) { ++ conn_io->events = POLLIN|POLLOUT|POLLNVAL; ++ pthread_kill (conn_io->thread, SIGUSR1); ++ } + } ++ pthread_mutex_unlock (&conn_io->mutex); + return (0); + } + +@@ -1242,7 +1427,6 @@ + id_len, + flow_control_state_set_fn, + context); +- conn_info->conn_info_partner->flow_control_handle = conn_info->flow_control_handle; + } + + void openais_ipc_flow_control_destroy ( +@@ -1283,3 +1467,18 @@ + + pthread_mutex_unlock (&conn_info->flow_control_mutex); + } ++ ++ ++int openais_response_send (void *conn, void *msg, int mlen) ++{ ++ struct conn_info *conn_info = (struct conn_info *)conn; ++ ++ return (conn_io_send (conn_info->conn_io_response, msg, mlen)); ++} ++ ++int openais_dispatch_send (void *conn, void *msg, int mlen) ++{ ++ struct conn_info *conn_info = (struct conn_info *)conn; ++ ++ return (conn_io_send (conn_info->conn_io_dispatch, msg, mlen)); ++} +diff -uNr openais-0.80.3/exec/ipc.h openais-0.80.3-r1661/exec/ipc.h +--- openais-0.80.3/exec/ipc.h 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/ipc.h 2008-11-17 15:54:02.380604445 +0100 +@@ -42,17 +42,20 @@ + + extern int message_source_is_local (mar_message_source_t *source); + +-extern void *openais_conn_partner_get (void *conn); +- + extern void *openais_conn_private_data_get (void *conn); + +-extern int openais_conn_send_response (void *conn, void *msg, int mlen); ++extern int openais_response_send (void *conn, void *msg, int mlen); ++ ++extern int openais_dispatch_send (void *conn, void *msg, int mlen); ++ ++extern void openais_conn_info_refcnt_dec (void *conn); ++ ++extern void openais_conn_info_refcnt_inc (void *conn); + + extern void openais_ipc_init ( + void (*serialize_lock_fn) (void), + void (*serialize_unlock_fn) (void), +- unsigned int gid_valid, +- struct totem_ip_address *non_loopback_ip); ++ unsigned int gid_valid); + + extern int openais_ipc_timer_add ( + void *conn, +diff -uNr openais-0.80.3/exec/keygen.c openais-0.80.3-r1661/exec/keygen.c +--- openais-0.80.3/exec/keygen.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/keygen.c 2008-11-17 15:54:02.380604445 +0100 +@@ -73,7 +73,7 @@ + /* + * Open key + */ +- authkey_fd = open ("/etc/ais/authkey", O_CREAT|O_WRONLY); ++ authkey_fd = open ("/etc/ais/authkey", O_CREAT|O_WRONLY, 600); + if (authkey_fd == -1) { + perror ("Could not create /etc/ais/authkey"); + exit (1); +@@ -81,7 +81,7 @@ + /* + * Set security of authorization key to uid = 0 uid = 0 mode = 0400 + */ +- fchown (authkey_fd, 0, 0); ++ res = fchown (authkey_fd, 0, 0); + fchmod (authkey_fd, 0400); + + printf ("Writing openais key to /etc/ais/authkey.\n"); +diff -uNr openais-0.80.3/exec/lck.c openais-0.80.3-r1661/exec/lck.c +--- openais-0.80.3/exec/lck.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/lck.c 2008-11-17 15:54:02.390605772 +0100 +@@ -719,12 +719,12 @@ + &req_exec_lck_resourceopen->source, + sizeof (mar_message_source_t)); + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_lck_resourceopen->source.conn, + &res_lib_lck_resourceopenasync, + sizeof (struct res_lib_lck_resourceopenasync)); +- openais_conn_send_response ( +- openais_conn_partner_get (req_exec_lck_resourceopen->source.conn), ++ openais_dispatch_send ( ++ req_exec_lck_resourceopen->source.conn, + &res_lib_lck_resourceopenasync, + sizeof (struct res_lib_lck_resourceopenasync)); + } else { +@@ -738,7 +738,7 @@ + &req_exec_lck_resourceopen->source, + sizeof (mar_message_source_t)); + +- openais_conn_send_response (req_exec_lck_resourceopen->source.conn, ++ openais_response_send (req_exec_lck_resourceopen->source.conn, + &res_lib_lck_resourceopen, + sizeof (struct res_lib_lck_resourceopen)); + } +@@ -774,7 +774,7 @@ + res_lib_lck_resourceclose.header.size = sizeof (struct res_lib_lck_resourceclose); + res_lib_lck_resourceclose.header.id = MESSAGE_RES_LCK_RESOURCECLOSE; + res_lib_lck_resourceclose.header.error = error; +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_lck_resourceclose->source.conn, + &res_lib_lck_resourceclose, sizeof (struct res_lib_lck_resourceclose)); + } +@@ -801,8 +801,8 @@ + res_lib_lck_lockwaitercallback.mode_held = SA_LCK_PR_LOCK_MODE; + } + +- openais_conn_send_response ( +- openais_conn_partner_get (resource_lock->callback_source.conn), ++ openais_dispatch_send ( ++ resource_lock->callback_source.conn, + &res_lib_lck_lockwaitercallback, + sizeof (struct res_lib_lck_lockwaitercallback)); + } +@@ -837,8 +837,8 @@ + res_lib_lck_resourcelockasync.lockStatus = resource_lock->lock_status; + res_lib_lck_resourcelockasync.invocation = resource_lock->invocation; + res_lib_lck_resourcelockasync.lockId = resource_lock->lock_id; +- openais_conn_send_response ( +- openais_conn_partner_get (source->conn), ++ openais_dispatch_send ( ++ source->conn, + &res_lib_lck_resourcelockasync, + sizeof (struct res_lib_lck_resourcelockasync)); + } +@@ -861,7 +861,7 @@ + res_lib_lck_resourcelock.header.error = error; + res_lib_lck_resourcelock.resource_lock = (void *)resource_lock; + res_lib_lck_resourcelock.lockStatus = resource_lock->lock_status; +- openais_conn_send_response (source->conn, ++ openais_response_send (source->conn, + &res_lib_lck_resourcelock, + sizeof (struct res_lib_lck_resourcelock)); + } +@@ -1133,14 +1133,11 @@ + * Deliver async response to library + */ + req_exec_lck_resourcelock->source.conn = +- openais_conn_partner_get (req_exec_lck_resourcelock->source.conn); ++ req_exec_lck_resourcelock->source.conn; + resource_lock_async_deliver ( + &req_exec_lck_resourcelock->source, + resource_lock, + SA_AIS_OK); +-// TODO why is this twice ? +- req_exec_lck_resourcelock->source.conn = +- openais_conn_partner_get (req_exec_lck_resourcelock->source.conn); + } + + error_exit: +@@ -1184,11 +1181,11 @@ + res_lib_lck_resourceunlockasync.invocation = + req_exec_lck_resourceunlock->invocation; + +- openais_conn_send_response ( ++ openais_dispatch_send ( + req_exec_lck_resourceunlock->source.conn, + &res_lib_lck_resourceunlockasync, + sizeof (struct res_lib_lck_resourceunlockasync)); +- openais_conn_send_response ( ++ openais_response_send ( + resource_lock->callback_source.conn, + &res_lib_lck_resourceunlockasync, + sizeof (struct res_lib_lck_resourceunlockasync)); +@@ -1196,8 +1193,10 @@ + res_lib_lck_resourceunlock.header.size = sizeof (struct res_lib_lck_resourceunlock); + res_lib_lck_resourceunlock.header.id = MESSAGE_RES_LCK_RESOURCEUNLOCK; + res_lib_lck_resourceunlock.header.error = error; +- openais_conn_send_response (req_exec_lck_resourceunlock->source.conn, +- &res_lib_lck_resourceunlock, sizeof (struct res_lib_lck_resourceunlock)); ++ openais_response_send ( ++ req_exec_lck_resourceunlock->source.conn, ++ &res_lib_lck_resourceunlock, ++ sizeof (struct res_lib_lck_resourceunlock)); + } + } + } +@@ -1253,8 +1252,10 @@ + res_lib_lck_lockpurge.header.size = sizeof (struct res_lib_lck_lockpurge); + res_lib_lck_lockpurge.header.id = MESSAGE_RES_LCK_LOCKPURGE; + res_lib_lck_lockpurge.header.error = error; +- openais_conn_send_response (req_exec_lck_lockpurge->source.conn, +- &res_lib_lck_lockpurge, sizeof (struct res_lib_lck_lockpurge)); ++ openais_response_send ( ++ req_exec_lck_lockpurge->source.conn, ++ &res_lib_lck_lockpurge, ++ sizeof (struct res_lib_lck_lockpurge)); + } + } + +@@ -1366,7 +1367,8 @@ + res_lib_lck_resourceclose.header.id = MESSAGE_RES_LCK_RESOURCECLOSE; + res_lib_lck_resourceclose.header.error = SA_AIS_ERR_NOT_EXIST; + +- openais_conn_send_response (conn, ++ openais_response_send ( ++ conn, + &res_lib_lck_resourceclose, + sizeof (struct res_lib_lck_resourceclose)); + } +diff -uNr openais-0.80.3/exec/main.c openais-0.80.3-r1661/exec/main.c +--- openais-0.80.3/exec/main.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/main.c 2008-11-17 15:54:02.400604305 +0100 +@@ -120,8 +120,6 @@ + } + + +-struct totem_ip_address *this_ip; +-struct totem_ip_address this_non_loopback_ip; + #define LOCALHOST_IP inet_addr("127.0.0.1") + + totempg_groups_handle openais_group_handle; +@@ -175,15 +173,29 @@ + static int openais_sync_callbacks_retrieve (int sync_id, + struct sync_callbacks *callbacks) + { +- if (ais_service[sync_id] == NULL) { ++ unsigned int ais_service_index; ++ unsigned int ais_services_found = 0; ++ ++ for (ais_service_index = 0; ++ ais_service_index < SERVICE_HANDLER_MAXIMUM_COUNT; ++ ais_service_index++) { ++ ++ if (ais_service[ais_service_index] != NULL) { ++ if (ais_services_found == sync_id) { ++ break; ++ } ++ ais_services_found += 1; ++ } ++ } ++ if (ais_service_index == SERVICE_HANDLER_MAXIMUM_COUNT) { + memset (callbacks, 0, sizeof (struct sync_callbacks)); + return (-1); + } +- callbacks->name = ais_service[sync_id]->name; +- callbacks->sync_init = ais_service[sync_id]->sync_init; +- callbacks->sync_process = ais_service[sync_id]->sync_process; +- callbacks->sync_activate = ais_service[sync_id]->sync_activate; +- callbacks->sync_abort = ais_service[sync_id]->sync_abort; ++ callbacks->name = ais_service[ais_service_index]->name; ++ callbacks->sync_init = ais_service[ais_service_index]->sync_init; ++ callbacks->sync_process = ais_service[ais_service_index]->sync_process; ++ callbacks->sync_activate = ais_service[ais_service_index]->sync_activate; ++ callbacks->sync_abort = ais_service[ais_service_index]->sync_abort; + return (0); + } + +@@ -200,10 +212,6 @@ + + memcpy (&aisexec_ring_id, ring_id, sizeof (struct memb_ring_id)); + +- if (!totemip_localhost_check(this_ip)) { +- totemip_copy(&this_non_loopback_ip, this_ip); +- } +- + /* + * Call configuration change for all services + */ +@@ -262,7 +270,6 @@ + + static void aisexec_tty_detach (void) + { +-#ifndef DEBUG + /* + * Disconnect from TTY if this is not a debug run + */ +@@ -279,7 +286,6 @@ + exit (0); + break; + } +-#endif + } + + static void aisexec_setscheduler (void) +@@ -392,17 +398,31 @@ + int res; + int totem_log_service; + log_init ("MAIN"); ++ unsigned int background; ++ int ch; + +- aisexec_tty_detach (); ++ background = 1; ++ ++ while ((ch = getopt (argc, argv, "fp")) != EOF) { ++ switch (ch) { ++ case 'f': ++ background = 0; ++ break; ++ default: ++ fprintf (stderr, "Usage:\n"); ++ fprintf (stderr, " -f : Start application in forground.\n"); ++ return EXIT_FAILURE; ++ } ++ } ++ ++ if (background) { ++ aisexec_tty_detach (); ++ } + + log_printf (LOG_LEVEL_NOTICE, "AIS Executive Service RELEASE '%s'\n", RELEASE_VERSION); + log_printf (LOG_LEVEL_NOTICE, "Copyright (C) 2002-2006 MontaVista Software, Inc and contributors.\n"); + log_printf (LOG_LEVEL_NOTICE, "Copyright (C) 2006 Red Hat, Inc.\n"); + +- memset(&this_non_loopback_ip, 0, sizeof(struct totem_ip_address)); +- +- totemip_localhost(AF_INET, &this_non_loopback_ip); +- + signal (SIGINT, sigintr_handler); + signal (SIGUSR2, sigusr2_handler); + signal (SIGSEGV, sigsegv_handler); +@@ -548,8 +568,6 @@ + /* + * This must occur after totempg is initialized because "this_ip" must be set + */ +- this_ip = &totem_config.interfaces[0].boundto; +- + res = openais_service_init_all (service_count, objdb); + if (res == -1) { + log_printf (LOG_LEVEL_ERROR, "Could not init services\n"); +@@ -577,8 +595,7 @@ + openais_ipc_init ( + serialize_mutex_lock, + serialize_mutex_unlock, +- gid_valid, +- &this_non_loopback_ip); ++ gid_valid); + + /* + * Start main processing loop +diff -uNr openais-0.80.3/exec/main.h openais-0.80.3-r1661/exec/main.h +--- openais-0.80.3/exec/main.h 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/main.h 2008-11-17 15:54:02.400604305 +0100 +@@ -53,8 +53,6 @@ + + #define SIZEINB MESSAGE_SIZE_MAX + +-extern struct totem_ip_address *this_ip; +- + extern struct totempg_group openais_group; + + extern totempg_groups_handle openais_group_handle; +diff -uNr openais-0.80.3/exec/msg.c openais-0.80.3-r1661/exec/msg.c +--- openais-0.80.3/exec/msg.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/msg.c 2008-11-17 15:54:02.400604305 +0100 +@@ -675,9 +675,6 @@ + /* + * Initialize the saved ring ID. + */ +-// saved_ring_id.seq = 0; +-// saved_ring_id.rep.s_addr = this_ip->sin_addr.s_addr; +- + return (0); + } + +@@ -810,12 +807,12 @@ + &req_exec_msg_queueopen->source, + sizeof (mar_message_source_t)); + +- openais_conn_send_response ( ++ openais_response_send ( + req_exec_msg_queueopen->source.conn, + &res_lib_msg_queueopenasync, + sizeof (struct res_lib_msg_queueopenasync)); +- openais_conn_send_response ( +- openais_conn_partner_get (req_exec_msg_queueopen->source.conn), ++ openais_dispatch_send ( ++ req_exec_msg_queueopen->source.conn, + &res_lib_msg_queueopenasync, + sizeof (struct res_lib_msg_queueopenasync)); + } else { +@@ -829,7 +826,7 @@ + &req_exec_msg_queueopen->source, + sizeof (mar_message_source_t)); + +- openais_conn_send_response ( ++ openais_dispatch_send ( + req_exec_msg_queueopen->source.conn, + &res_lib_msg_queueopen, + sizeof (struct res_lib_msg_queueopen)); +@@ -868,8 +865,10 @@ + res_lib_msg_queueclose.header.size = sizeof (struct res_lib_msg_queueclose); + res_lib_msg_queueclose.header.id = MESSAGE_RES_MSG_QUEUECLOSE; + res_lib_msg_queueclose.header.error = error; +- openais_conn_send_response (req_exec_msg_queueclose->source.conn, +- &res_lib_msg_queueclose, sizeof (struct res_lib_msg_queueclose)); ++ openais_dispatch_send ( ++ req_exec_msg_queueclose->source.conn, ++ &res_lib_msg_queueclose, ++ sizeof (struct res_lib_msg_queueclose)); + } + } + +@@ -930,7 +929,7 @@ + res_lib_msg_queuegroupcreate.header.id = MESSAGE_RES_MSG_QUEUEGROUPCREATE; + res_lib_msg_queuegroupcreate.header.error = error; + +- openais_conn_send_response ( ++ openais_dispatch_send ( + req_exec_msg_queuegroupcreate->source.conn, + &res_lib_msg_queuegroupcreate, + sizeof (struct res_lib_msg_queuegroupcreate)); +@@ -977,7 +976,7 @@ + res_lib_msg_queuegroupinsert.header.id = MESSAGE_RES_MSG_QUEUEGROUPCREATE; + res_lib_msg_queuegroupinsert.header.error = error; + +- openais_conn_send_response ( ++ openais_dispatch_send ( + req_exec_msg_queuegroupinsert->source.conn, + &res_lib_msg_queuegroupinsert, + sizeof (struct res_lib_msg_queuegroupinsert)); +@@ -1021,7 +1020,7 @@ + res_lib_msg_queuegroupremove.header.id = MESSAGE_RES_MSG_QUEUEGROUPCREATE; + res_lib_msg_queuegroupremove.header.error = error; + +- openais_conn_send_response ( ++ openais_dispatch_send ( + req_exec_msg_queuegroupremove->source.conn, + &res_lib_msg_queuegroupremove, + sizeof (struct res_lib_msg_queuegroupremove)); +@@ -1052,7 +1051,7 @@ + res_lib_msg_queuegroupdelete.header.id = MESSAGE_RES_MSG_QUEUEGROUPCREATE; + res_lib_msg_queuegroupdelete.header.error = error; + +- openais_conn_send_response ( ++ openais_dispatch_send ( + req_exec_msg_queuegroupdelete->source.conn, + &res_lib_msg_queuegroupdelete, + sizeof (struct res_lib_msg_queuegroupdelete)); +diff -uNr openais-0.80.3/exec/service.c openais-0.80.3-r1661/exec/service.c +--- openais-0.80.3/exec/service.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/service.c 2008-11-17 15:54:02.380604445 +0100 +@@ -87,7 +87,7 @@ + } + }; + +-struct openais_service_handler *ais_service[128]; ++struct openais_service_handler *ais_service[SERVICE_HANDLER_MAXIMUM_COUNT]; + + /* + * Adds a service handler to the object database +diff -uNr openais-0.80.3/exec/service.h openais-0.80.3-r1661/exec/service.h +--- openais-0.80.3/exec/service.h 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/service.h 2008-11-17 15:54:02.380604445 +0100 +@@ -44,6 +44,7 @@ + #endif + + #define SERVICE_ID_MAKE(a,b) ( ((a)<<16) | (b) ) ++#define SERVICE_HANDLER_MAXIMUM_COUNT 64 + + enum openais_flow_control { + OPENAIS_FLOW_CONTROL_REQUIRED = 1, +diff -uNr openais-0.80.3/exec/sync.c openais-0.80.3-r1661/exec/sync.c +--- openais-0.80.3/exec/sync.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/sync.c 2008-11-17 15:54:02.390605772 +0100 +@@ -198,9 +198,10 @@ + { + int res; + +-// TODO rewrite this to get rid of the for (;;) + for (;;) { +- res = sync_callbacks_retrieve (sync_recovery_index, &sync_callbacks); ++ res = sync_callbacks_retrieve (sync_recovery_index, ++ &sync_callbacks); ++ + /* + * No more service handlers have sync callbacks at this time + ` */ +@@ -418,7 +419,6 @@ + log_printf (LOG_LEVEL_DEBUG, + "Committing synchronization for (%s)\n", + sync_callbacks.name); +- + } + + /* +@@ -452,8 +452,12 @@ + { + sync_ring_id = ring_id; + ++ if (configuration_type != TOTEM_CONFIGURATION_REGULAR) { ++ return; ++ } + if (sync_processing && sync_callbacks.sync_abort != NULL) { + sync_callbacks.sync_abort (); ++ sync_callbacks.sync_activate = NULL; + } + /* + * If no virtual synchrony filter configured, then start +diff -uNr openais-0.80.3/exec/timer.c openais-0.80.3-r1661/exec/timer.c +--- openais-0.80.3/exec/timer.c 2007-06-25 04:22:54.000000000 +0200 ++++ openais-0.80.3-r1661/exec/timer.c 2008-11-17 15:54:02.400604305 +0100 +@@ -126,13 +126,13 @@ + if (fds == -1) { + goto retry_poll; + } +- pthread_mutex_lock (&timer_mutex); + timer_serialize_lock_fn (); ++ pthread_mutex_lock (&timer_mutex); + + timerlist_expire (&timers_timerlist); + +- timer_serialize_unlock_fn (); + pthread_mutex_unlock (&timer_mutex); ++ timer_serialize_unlock_fn (); + } + + pthread_exit (0); +@@ -177,7 +177,7 @@ + int res; + int unlock; + +- if (pthread_equal (pthread_self(), expiry_thread) == 0) { ++ if (pthread_equal (pthread_self(), expiry_thread) != 0) { + unlock = 0; + } else { + unlock = 1; +@@ -209,7 +209,7 @@ + int res; + int unlock; + +- if (pthread_equal (pthread_self(), expiry_thread) == 0) { ++ if (pthread_equal (pthread_self(), expiry_thread) != 0) { + unlock = 0; + } else { + unlock = 1; +@@ -241,7 +241,7 @@ + return; + } + +- if (pthread_equal (pthread_self(), expiry_thread) == 0) { ++ if (pthread_equal (pthread_self(), expiry_thread) != 0) { + unlock = 0; + } else { + unlock = 1; +diff -uNr openais-0.80.3/exec/totem.h openais-0.80.3-r1661/exec/totem.h +--- openais-0.80.3/exec/totem.h 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/totem.h 2008-11-17 15:54:02.400604305 +0100 +@@ -89,6 +89,7 @@ + struct totem_interface *interfaces; + int interface_count; + unsigned int node_id; ++ unsigned int clear_node_high_bit; + + /* + * key information +diff -uNr openais-0.80.3/exec/totemconfig.c openais-0.80.3-r1661/exec/totemconfig.c +--- openais-0.80.3/exec/totemconfig.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/totemconfig.c 2008-11-17 15:54:02.400604305 +0100 +@@ -174,6 +174,13 @@ + */ + objdb_get_int (objdb, object_totem_handle, "nodeid", &totem_config->node_id); + ++ totem_config->clear_node_high_bit = 0; ++ if (!objdb_get_string (objdb,object_totem_handle, "clear_node_high_bit", &str)) { ++ if (strcmp (str, "yes") == 0) { ++ totem_config->clear_node_high_bit = 1; ++ } ++ } ++ + objdb_get_int (objdb,object_totem_handle, "threads", &totem_config->threads); + + +diff -uNr openais-0.80.3/exec/totemmrp.c openais-0.80.3-r1661/exec/totemmrp.c +--- openais-0.80.3/exec/totemmrp.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/totemmrp.c 2008-11-17 15:54:02.390605772 +0100 +@@ -191,6 +191,16 @@ + return (res); + } + ++int totemmrp_my_nodeid_get (void) ++{ ++ return (totemsrp_my_nodeid_get (totemsrp_handle_in)); ++} ++ ++int totemmrp_my_family_get (void) ++{ ++ return (totemsrp_my_family_get (totemsrp_handle_in)); ++} ++ + extern int totemmrp_ring_reenable (void) + { + int res; +diff -uNr openais-0.80.3/exec/totemmrp.h openais-0.80.3-r1661/exec/totemmrp.h +--- openais-0.80.3/exec/totemmrp.h 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/totemmrp.h 2008-11-17 15:54:02.390605772 +0100 +@@ -105,6 +105,10 @@ + char ***status, + unsigned int *iface_count); + ++extern int totemmrp_my_nodeid_get (void); ++ ++extern int totemmrp_my_family_get (void); ++ + extern int totemmrp_ring_reenable (void); + + #endif /* TOTEMMRP_H_DEFINED */ +diff -uNr openais-0.80.3/exec/totemnet.c openais-0.80.3-r1661/exec/totemnet.c +--- openais-0.80.3/exec/totemnet.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/totemnet.c 2008-11-17 15:54:02.370604375 +0100 +@@ -1227,6 +1227,15 @@ + + instance->totemnet_poll_handle = poll_handle; + ++ if(instance->totem_config->node_id == 0) { ++ int32_t nodeid = 0; ++ memcpy (&nodeid, instance->totem_interface->bindnet.addr, sizeof (int32_t)); ++ if(nodeid < 0 && instance->totem_config->clear_node_high_bit) { ++ nodeid = 0 - nodeid; ++ } ++ instance->totem_config->node_id = nodeid; ++ } ++ + instance->totem_interface->bindnet.nodeid = instance->totem_config->node_id; + + instance->context = context; +diff -uNr openais-0.80.3/exec/totempg.c openais-0.80.3-r1661/exec/totempg.c +--- openais-0.80.3/exec/totempg.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/totempg.c 2008-11-17 15:54:02.380604445 +0100 +@@ -720,14 +720,16 @@ + * Multicast a message + */ + static int mcast_msg ( +- struct iovec *iovec, ++ struct iovec *iovec_in, + int iov_len, + int guarantee) + { + int res = 0; + struct totempg_mcast mcast; + struct iovec iovecs[3]; ++ struct iovec iovec[64]; + int i; ++ int dest, src; + int max_packet_size = 0; + int copy_len = 0; + int copy_base = 0; +@@ -736,6 +738,18 @@ + pthread_mutex_lock (&mcast_msg_mutex); + totemmrp_new_msg_signal (); + ++ /* ++ * Remove zero length iovectors from the list ++ */ ++ assert (iov_len < 64); ++ for (dest = 0, src = 0; src < iov_len; src++) { ++ if (iovec_in[src].iov_len) { ++ memcpy (&iovec[dest++], &iovec_in[src], ++ sizeof (struct iovec)); ++ } ++ } ++ iov_len = dest; ++ + max_packet_size = TOTEMPG_PACKET_SIZE - + (sizeof (unsigned short) * (mcast_packed_msg_count + 1)); + +@@ -870,13 +884,14 @@ + /* + * Determine if a message of msg_size could be queued + */ ++#define FUZZY_AVAIL_SUBTRACT 5 + static int send_ok ( + int msg_size) + { + int avail = 0; + int total; + +- avail = totemmrp_avail (); ++ avail = totemmrp_avail () - FUZZY_AVAIL_SUBTRACT; + + /* + * msg size less then totempg_totem_config->net_mtu - 25 will take up +@@ -1241,3 +1256,12 @@ + return (iface_string); + } + ++int totempg_my_nodeid_get (void) ++{ ++ return (totemmrp_my_nodeid_get()); ++} ++ ++int totempg_my_family_get (void) ++{ ++ return (totemmrp_my_family_get()); ++} +diff -uNr openais-0.80.3/exec/totempg.h openais-0.80.3-r1661/exec/totempg.h +--- openais-0.80.3/exec/totempg.h 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/totempg.h 2008-11-17 15:54:02.380604445 +0100 +@@ -137,8 +137,12 @@ + char ***status, + unsigned int *iface_count); + +-extern int totempg_ring_reenable (void); +- + extern char *totempg_ifaces_print (unsigned int nodeid); + ++extern int totempg_my_nodeid_get (void); ++ ++extern int totempg_my_family_get (void); ++ ++extern int totempg_ring_reenable (void); ++ + #endif /* TOTEMPG_H_DEFINED */ +diff -uNr openais-0.80.3/exec/totemsrp.c openais-0.80.3-r1661/exec/totemsrp.c +--- openais-0.80.3/exec/totemsrp.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/totemsrp.c 2008-11-17 15:54:02.400604305 +0100 +@@ -138,6 +138,11 @@ + MESSAGE_TYPE_TOKEN_HOLD_CANCEL = 5, /* cancel the holding of the token */ + }; + ++enum encapsulation_type { ++ MESSAGE_ENCAPSULATED = 1, ++ MESSAGE_NOT_ENCAPSULATED = 2 ++}; ++ + /* + * New membership algorithm local variables + */ +@@ -393,8 +398,6 @@ + + unsigned int my_token_seq; + +- unsigned int my_commit_token_seq; +- + /* + * Timers + */ +@@ -551,7 +554,8 @@ + int fcc_mcasts_allowed); + static void messages_free (struct totemsrp_instance *instance, unsigned int token_aru); + +-static void memb_ring_id_store (struct totemsrp_instance *instance); ++static void memb_ring_id_set_and_store (struct totemsrp_instance *instance, ++ struct memb_ring_id *ring_id); + static void memb_state_commit_token_update (struct totemsrp_instance *instance, struct memb_commit_token *commit_token); + static void memb_state_commit_token_target_set (struct totemsrp_instance *instance, struct memb_commit_token *commit_token); + static int memb_state_commit_token_send (struct totemsrp_instance *instance, struct memb_commit_token *memb_commit_token); +@@ -615,12 +619,10 @@ + + list_init (&instance->token_callback_sent_listhead); + +- instance->my_received_flg = 0; ++ instance->my_received_flg = 1; + + instance->my_token_seq = SEQNO_START_TOKEN - 1; + +- instance->my_commit_token_seq = SEQNO_START_TOKEN - 1; +- + instance->memb_state = MEMB_STATE_OPERATIONAL; + + instance->set_aru = -1; +@@ -903,6 +905,43 @@ + return (res); + } + ++int totemsrp_my_nodeid_get ( ++ totemsrp_handle handle) ++{ ++ struct totemsrp_instance *instance; ++ int res; ++ ++ res = hdb_handle_get (&totemsrp_instance_database, handle, ++ (void *)&instance); ++ if (res != 0) { ++ return (0); ++ } ++ ++ res = instance->totem_config->interfaces[0].boundto.nodeid; ++ ++ hdb_handle_put (&totemsrp_instance_database, handle); ++ return (res); ++} ++ ++int totemsrp_my_family_get ( ++ totemsrp_handle handle) ++{ ++ struct totemsrp_instance *instance; ++ int res; ++ ++ res = hdb_handle_get (&totemsrp_instance_database, handle, ++ (void *)&instance); ++ if (res != 0) { ++ return (0); ++ } ++ ++ res = instance->totem_config->interfaces[0].boundto.family; ++ ++ hdb_handle_put (&totemsrp_instance_database, handle); ++ return (res); ++} ++ ++ + int totemsrp_ring_reenable ( + totemsrp_handle handle) + { +@@ -1552,6 +1591,8 @@ + unsigned int new_memb_list_totemip[PROCESSOR_COUNT_MAX]; + unsigned int left_list[PROCESSOR_COUNT_MAX]; + ++ memb_consensus_reset (instance); ++ + old_ring_state_reset (instance); + ring_reset (instance); + deliver_messages_from_recovery_to_regular (instance); +@@ -1637,7 +1678,7 @@ + "entering OPERATIONAL state.\n"); + instance->memb_state = MEMB_STATE_OPERATIONAL; + +- instance->my_received_flg = 0; ++ instance->my_received_flg = 1; + + return; + } +@@ -1646,8 +1687,6 @@ + struct totemsrp_instance *instance, + int gather_from) + { +- instance->my_commit_token_seq = SEQNO_START_TOKEN - 1; +- + memb_set_merge ( + &instance->my_id, 1, + instance->my_proc_list, &instance->my_proc_list_entries); +@@ -1711,10 +1750,10 @@ + + memb_state_commit_token_target_set (instance, commit_token); + ++ memb_ring_id_set_and_store (instance, &commit_token->ring_id); ++ + memb_state_commit_token_send (instance, commit_token); + +- memcpy (&instance->my_ring_id, &commit_token->ring_id, +- sizeof (struct memb_ring_id)); + instance->token_ring_id_seq = instance->my_ring_id.seq; + + poll_timer_delete (instance->totemsrp_poll_handle, instance->memb_timer_state_gather_join_timeout); +@@ -1733,8 +1772,6 @@ + + instance->memb_state = MEMB_STATE_COMMIT; + +- instance->my_commit_token_seq = SEQNO_START_TOKEN - 1; +- + /* + * reset all flow control variables since we are starting a new ring + */ +@@ -1779,15 +1816,10 @@ + /* + * Build regular configuration + */ +- instance->my_new_memb_entries = commit_token->addr_entries; +- + totemrrp_processor_count_set ( + instance->totemrrp_handle, + commit_token->addr_entries); + +- memcpy (instance->my_new_memb_list, addr, +- sizeof (struct srp_addr) * instance->my_new_memb_entries); +- + /* + * Build transitional configuration + */ +@@ -1892,13 +1924,14 @@ + // TODO LEAK + message_item.mcast = malloc (sizeof (struct mcast)); + assert (message_item.mcast); +- memcpy (message_item.mcast, sort_queue_item->iovec[0].iov_base, +- sizeof (struct mcast)); +- memcpy (&message_item.mcast->ring_id, &instance->my_ring_id, +- sizeof (struct memb_ring_id)); +- message_item.mcast->header.encapsulated = 1; ++ message_item.mcast->header.type = MESSAGE_TYPE_MCAST; ++ srp_addr_copy (&message_item.mcast->system_from, &instance->my_id); ++ message_item.mcast->header.encapsulated = MESSAGE_ENCAPSULATED; + message_item.mcast->header.nodeid = instance->my_id.addr[0].nodeid; + assert (message_item.mcast->header.nodeid); ++ message_item.mcast->header.endian_detector = ENDIAN_LOCAL; ++ memcpy (&message_item.mcast->ring_id, &instance->my_ring_id, ++ sizeof (struct memb_ring_id)); + message_item.iov_len = sort_queue_item->iov_len; + memcpy (&message_item.iovec, &sort_queue_item->iovec, + sizeof (struct iovec) * sort_queue_item->iov_len); +@@ -1926,7 +1959,6 @@ + + reset_token_timeout (instance); // REVIEWED + reset_token_retransmit_timeout (instance); // REVIEWED +- memb_ring_id_store (instance); + + instance->memb_state = MEMB_STATE_RECOVERY; + return; +@@ -1993,7 +2025,7 @@ + */ + message_item.mcast->header.type = MESSAGE_TYPE_MCAST; + message_item.mcast->header.endian_detector = ENDIAN_LOCAL; +- message_item.mcast->header.encapsulated = 2; ++ message_item.mcast->header.encapsulated = MESSAGE_NOT_ENCAPSULATED; + message_item.mcast->header.nodeid = instance->my_id.addr[0].nodeid; + assert (message_item.mcast->header.nodeid); + +@@ -2278,13 +2310,13 @@ + * Delete item from pending queue + */ + queue_item_remove (mcast_queue); ++ ++ /* ++ * If messages mcasted, deliver any new messages to totempg ++ */ ++ instance->my_high_seq_received = token->seq; + } + +- /* +- * If messages mcasted, deliver any new messages to totempg +- */ +- instance->my_high_seq_received = token->seq; +- + update_aru (instance); + + /* +@@ -2564,14 +2596,14 @@ + orf_token.token_seq = SEQNO_START_TOKEN; + orf_token.retrans_flg = 1; + instance->my_set_retrans_flg = 1; +-/* ++ + if (queue_is_empty (&instance->retrans_message_queue) == 1) { + orf_token.retrans_flg = 0; ++ instance->my_set_retrans_flg = 0; + } else { + orf_token.retrans_flg = 1; + instance->my_set_retrans_flg = 1; + } +-*/ + + orf_token.aru = 0; + orf_token.aru = SEQNO_START_MSG - 1; +@@ -2594,10 +2626,17 @@ + { + struct srp_addr *addr; + struct memb_commit_token_memb_entry *memb_list; ++ unsigned int high_aru; ++ unsigned int i; + + addr = (struct srp_addr *)commit_token->end_of_commit_token; + memb_list = (struct memb_commit_token_memb_entry *)(addr + commit_token->addr_entries); + ++ memcpy (instance->my_new_memb_list, addr, ++ sizeof (struct srp_addr) * commit_token->addr_entries); ++ ++ instance->my_new_memb_entries = commit_token->addr_entries; ++ + memcpy (&memb_list[commit_token->memb_index].ring_id, + &instance->my_old_ring_id, sizeof (struct memb_ring_id)); + assert (!totemip_zero_check(&instance->my_old_ring_id.rep)); +@@ -2607,9 +2646,43 @@ + * TODO high delivered is really instance->my_aru, but with safe this + * could change? + */ +- memb_list[commit_token->memb_index].high_delivered = instance->my_high_delivered; ++ instance->my_received_flg = ++ (instance->my_aru == instance->my_high_seq_received); ++ + memb_list[commit_token->memb_index].received_flg = instance->my_received_flg; + ++ memb_list[commit_token->memb_index].high_delivered = instance->my_high_delivered; ++ /* ++ * find high aru up to current memb_index for all matching ring ids ++ * if any ring id matching memb_index has aru less then high aru set ++ * received flag for that entry to false ++ */ ++ high_aru = memb_list[commit_token->memb_index].aru; ++ for (i = 0; i <= commit_token->memb_index; i++) { ++ if (memcmp (&memb_list[commit_token->memb_index].ring_id, ++ &memb_list[i].ring_id, ++ sizeof (struct memb_ring_id)) == 0) { ++ ++ if (sq_lt_compare (high_aru, memb_list[i].aru)) { ++ high_aru = memb_list[i].aru; ++ } ++ } ++ } ++ ++ for (i = 0; i <= commit_token->memb_index; i++) { ++ if (memcmp (&memb_list[commit_token->memb_index].ring_id, ++ &memb_list[i].ring_id, ++ sizeof (struct memb_ring_id)) == 0) { ++ ++ if (sq_lt_compare (memb_list[i].aru, high_aru)) { ++ memb_list[i].received_flg = 0; ++ if (i == commit_token->memb_index) { ++ instance->my_received_flg = 0; ++ } ++ } ++ } ++ } ++ + commit_token->header.nodeid = instance->my_id.addr[0].nodeid; + commit_token->memb_index += 1; + assert (commit_token->memb_index <= commit_token->addr_entries); +@@ -2773,7 +2846,7 @@ + iovs = 2; + } else { + iovs = 3; +- iovec[2].iov_base = &instance->my_failed_list; ++ iovec[2].iov_base = instance->my_failed_list; + iovec[2].iov_len = instance->my_failed_list_entries * + sizeof (struct srp_addr); + } +@@ -2846,13 +2919,16 @@ + instance->token_ring_id_seq = memb_ring_id->seq; + } + +-static void memb_ring_id_store ( +- struct totemsrp_instance *instance) ++static void memb_ring_id_set_and_store ( ++ struct totemsrp_instance *instance, ++ struct memb_ring_id *ring_id) + { + char filename[256]; + int fd; + int res; + ++ memcpy (&instance->my_ring_id, ring_id, sizeof (struct memb_ring_id)); ++ + sprintf (filename, "%s/ringid_%s", + rundir, totemip_print (&instance->my_id.addr[0])); + +@@ -3085,7 +3161,6 @@ + unsigned int mcasted_retransmit; + unsigned int mcasted_regular; + unsigned int last_aru; +- unsigned int low_water; + + #ifdef GIVEINFO + struct timeval tv_current; +@@ -3279,13 +3354,7 @@ + * has recovered all messages it can recover + * (ie: its retrans queue is empty) + */ +- low_water = instance->my_aru; +- if (sq_lt_compare (last_aru, low_water)) { +- low_water = last_aru; +- } +-// TODO is this code right +- if (queue_is_empty (&instance->retrans_message_queue) == 0 || +- low_water != instance->my_high_seq_received) { ++ if (queue_is_empty (&instance->retrans_message_queue) == 0) { + + if (token->retrans_flg == 0) { + token->retrans_flg = 1; +@@ -3296,10 +3365,10 @@ + token->retrans_flg = 0; + } + log_printf (instance->totemsrp_log_level_debug, +- "token retrans flag is %d my set retrans flag%d retrans queue empty %d count %d, low_water %x aru %x\n", ++ "token retrans flag is %d my set retrans flag%d retrans queue empty %d count %d, aru %x\n", + token->retrans_flg, instance->my_set_retrans_flg, + queue_is_empty (&instance->retrans_message_queue), +- instance->my_retrans_flg_count, low_water, token->aru); ++ instance->my_retrans_flg_count, token->aru); + if (token->retrans_flg == 0) { + instance->my_retrans_flg_count += 1; + } else { +@@ -3311,13 +3380,16 @@ + log_printf (instance->totemsrp_log_level_debug, + "install seq %x aru %x high seq received %x\n", + instance->my_install_seq, instance->my_aru, instance->my_high_seq_received); +- if (instance->my_retrans_flg_count >= 2 && instance->my_aru >= instance->my_install_seq && instance->my_received_flg == 0) { ++ if (instance->my_retrans_flg_count >= 2 && ++ instance->my_received_flg == 0 && ++ sq_lte_compare (instance->my_install_seq, instance->my_aru)) { + instance->my_received_flg = 1; + instance->my_deliver_memb_entries = instance->my_trans_memb_entries; + memcpy (instance->my_deliver_memb_list, instance->my_trans_memb_list, + sizeof (struct totem_ip_address) * instance->my_trans_memb_entries); + } +- if (instance->my_retrans_flg_count >= 3 && token->aru >= instance->my_install_seq) { ++ if (instance->my_retrans_flg_count >= 3 && ++ sq_lte_compare (instance->my_install_seq, token->aru)) { + instance->my_rotation_counter += 1; + } else { + instance->my_rotation_counter = 0; +@@ -3386,9 +3458,10 @@ + struct sort_queue_item *sort_queue_item_p; + unsigned int i; + int res; +- struct mcast *mcast; ++ struct mcast *mcast_in; ++ struct mcast mcast_header; + unsigned int range = 0; +- int endian_conversion_required = 0 ; ++ int endian_conversion_required; + unsigned int my_high_delivered_stored = 0; + + +@@ -3436,18 +3509,27 @@ + + sort_queue_item_p = ptr; + +- mcast = sort_queue_item_p->iovec[0].iov_base; +- assert (mcast != (struct mcast *)0xdeadbeef); ++ mcast_in = sort_queue_item_p->iovec[0].iov_base; ++ assert (mcast_in != (struct mcast *)0xdeadbeef); ++ ++ endian_conversion_required = 0; ++ if (mcast_in->header.endian_detector != ENDIAN_LOCAL) { ++ endian_conversion_required = 1; ++ mcast_endian_convert (mcast_in, &mcast_header); ++ } else { ++ memcpy (&mcast_header, mcast_in, sizeof (struct mcast)); ++ } + + /* + * Skip messages not originated in instance->my_deliver_memb + */ + if (skip && +- memb_set_subset (&mcast->system_from, ++ memb_set_subset (&mcast_header.system_from, + 1, + instance->my_deliver_memb_list, + instance->my_deliver_memb_entries) == 0) { +- instance->my_high_delivered = my_high_delivered_stored + i; ++ ++ instance->my_high_delivered = my_high_delivered_stored + i; + + continue; + } +@@ -3457,12 +3539,7 @@ + */ + log_printf (instance->totemsrp_log_level_debug, + "Delivering MCAST message with seq %x to pending delivery queue\n", +- mcast->seq); +- +- if (mcast->header.endian_detector != ENDIAN_LOCAL) { +- endian_conversion_required = 1; +- mcast_endian_convert (mcast, mcast); +- } ++ mcast_header.seq); + + /* + * Message is locally originated multicast +@@ -3470,7 +3547,7 @@ + if (sort_queue_item_p->iov_len > 1 && + sort_queue_item_p->iovec[0].iov_len == sizeof (struct mcast)) { + instance->totemsrp_deliver_fn ( +- mcast->header.nodeid, ++ mcast_header.header.nodeid, + &sort_queue_item_p->iovec[1], + sort_queue_item_p->iov_len - 1, + endian_conversion_required); +@@ -3479,7 +3556,7 @@ + sort_queue_item_p->iovec[0].iov_base += sizeof (struct mcast); + + instance->totemsrp_deliver_fn ( +- mcast->header.nodeid, ++ mcast_header.header.nodeid, + sort_queue_item_p->iovec, + sort_queue_item_p->iov_len, + endian_conversion_required); +@@ -3511,18 +3588,12 @@ + memcpy (&mcast_header, msg, sizeof (struct mcast)); + } + +-/* +- if (mcast_header.header.encapsulated == 1) { +- sort_queue = &instance->recovery_sort_queue; +- } else { +- sort_queue = &instance->regular_sort_queue; +- } +-*/ +- if (instance->memb_state == MEMB_STATE_RECOVERY) { ++ if (mcast_header.header.encapsulated == MESSAGE_ENCAPSULATED) { + sort_queue = &instance->recovery_sort_queue; + } else { + sort_queue = &instance->regular_sort_queue; + } ++ + assert (msg_len < FRAME_SIZE_MAX); + + #ifdef TEST_DROP_MCAST_PERCENTAGE +@@ -3849,6 +3920,8 @@ + out->header.type = in->header.type; + out->header.endian_detector = ENDIAN_LOCAL; + out->header.nodeid = swab32 (in->header.nodeid); ++ out->header.encapsulated = in->header.encapsulated; ++ + out->seq = swab32 (in->seq); + out->this_seqno = swab32 (in->this_seqno); + totemip_copy_endian_convert(&out->ring_id.rep, &in->ring_id.rep); +@@ -3961,16 +4034,6 @@ + addr = (struct srp_addr *)memb_commit_token->end_of_commit_token; + memb_list = (struct memb_commit_token_memb_entry *)(addr + memb_commit_token->addr_entries); + +- if (sq_lte_compare (memb_commit_token->token_seq, +- instance->my_commit_token_seq)) { +- /* +- * discard token +- */ +- return (0); +- } +- instance->my_commit_token_seq = memb_commit_token->token_seq; +- +- + #ifdef TEST_DROP_COMMIT_TOKEN_PERCENTAGE + if (random()%100 < TEST_DROP_COMMIT_TOKEN_PERCENTAGE) { + return (0); +@@ -3998,9 +4061,15 @@ + break; + + case MEMB_STATE_COMMIT: +-// if (memcmp (&memb_commit_token->ring_id, &instance->my_ring_id, +-// sizeof (struct memb_ring_id)) == 0) { +- if (memb_commit_token->ring_id.seq == instance->my_ring_id.seq) { ++ /* ++ * If retransmitted commit tokens are sent on this ring ++ * filter them out and only enter recovery once the ++ * commit token has traversed the array. This is ++ * determined by : ++ * memb_commit_token->memb_index == memb_commit_token->addr_entries) { ++ */ ++ if (memb_commit_token->ring_id.seq == instance->my_ring_id.seq && ++ memb_commit_token->memb_index == memb_commit_token->addr_entries) { + memb_state_recovery_enter (instance, memb_commit_token); + } + break; +@@ -4051,7 +4120,12 @@ + log_printf (instance->totemsrp_log_level_security, "Received message is too short... ignoring %d.\n", msg_len); + return; + } +- ++ ++ if ((int)message_header->type >= totemsrp_message_handlers.count) { ++ log_printf (instance->totemsrp_log_level_security, "Type of received message is wrong... ignoring %d.\n", (int)message_header->type); ++ return; ++ } ++ + /* + * Handle incoming message + */ +diff -uNr openais-0.80.3/exec/totemsrp.h openais-0.80.3-r1661/exec/totemsrp.h +--- openais-0.80.3/exec/totemsrp.h 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/totemsrp.h 2008-11-17 15:54:02.400604305 +0100 +@@ -104,6 +104,12 @@ + char ***status, + unsigned int *iface_count); + ++extern int totemsrp_my_nodeid_get ( ++ totemsrp_handle handle); ++ ++extern int totemsrp_my_family_get ( ++ totemsrp_handle handle); ++ + extern int totemsrp_ring_reenable ( + totemsrp_handle handle); + +diff -uNr openais-0.80.3/exec/util.c openais-0.80.3-r1661/exec/util.c +--- openais-0.80.3/exec/util.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/util.c 2008-11-17 15:54:02.380604445 +0100 +@@ -84,10 +84,88 @@ + return time_now; + } + ++struct error_code_entry { ++ enum e_ais_done code; ++ char *string; ++}; ++ ++static struct error_code_entry error_code_map[] = { ++ { ++ .code = AIS_DONE_EXIT, ++ .string = "finished, exiting normally" ++ }, ++ { ++ .code = AIS_DONE_UID_DETERMINE, ++ .string = "could not determine the process UID" ++ }, ++ { ++ .code = AIS_DONE_GID_DETERMINE, ++ .string = "could not determine the process GID" ++ }, ++ { ++ .code = AIS_DONE_MEMPOOL_INIT, ++ .string = "could not initialize the memory pools" ++ }, ++ { ++ .code = AIS_DONE_FORK, ++ .string = "could not fork" ++ }, ++ { ++ .code = AIS_DONE_LIBAIS_SOCKET, ++ .string = "could not create a socket" ++ }, ++ { ++ .code = AIS_DONE_LIBAIS_BIND, ++ .string = "could not bind to an address" ++ }, ++ { ++ .code = AIS_DONE_READKEY, ++ .string = "could not read the security key" ++ }, ++ { ++ .code = AIS_DONE_MAINCONFIGREAD, ++ .string = "could not read the main configuration file" ++ }, ++ { ++ .code = AIS_DONE_LOGSETUP, ++ .string = "could not setup the logging system" ++ }, ++ { ++ .code = AIS_DONE_AMFCONFIGREAD, ++ .string = "could not read the AMF configuration" ++ }, ++ { ++ .code = AIS_DONE_DYNAMICLOAD, ++ .string = "could not load a dynamic object" ++ }, ++ { .code = AIS_DONE_OBJDB, ++ .string = "could not use the object database" ++ }, ++ { ++ .code = AIS_DONE_INIT_SERVICES, ++ .string = "could not initlalize services" ++ }, ++ { ++ .code = AIS_DONE_OUT_OF_MEMORY, ++ .string = "Out of memory" ++ }, ++ { ++ .code = AIS_DONE_FATAL_ERR, ++ .string = "Unknown fatal error" ++ }, ++}; + + void openais_exit_error (enum e_ais_done err) + { +- log_printf (LOG_LEVEL_ERROR, "AIS Executive exiting (%d).\n", err); ++ char *error_string = "Error code not available"; ++ int i; ++ ++ for (i = 0; i < (sizeof (error_code_map) / sizeof (struct error_code_entry)); i++) { ++ if (err == error_code_map[i].code) { ++ error_string = error_code_map[i].string; ++ } ++ } ++ log_printf (LOG_LEVEL_ERROR, "AIS Executive exiting (reason: %s).\n", error_string); + log_flush(); + exit (err); + } +diff -uNr openais-0.80.3/exec/version.h openais-0.80.3-r1661/exec/version.h +--- openais-0.80.3/exec/version.h 2007-06-26 13:36:38.000000000 +0200 ++++ openais-0.80.3-r1661/exec/version.h 2008-11-17 15:54:02.380604445 +0100 +@@ -1 +1 @@ +-#define RELEASE_VERSION "subrev 1358 version 0.80.3" ++#define RELEASE_VERSION "subrev 1152 version 0.80" +diff -uNr openais-0.80.3/exec/vsf_ykd.c openais-0.80.3-r1661/exec/vsf_ykd.c +--- openais-0.80.3/exec/vsf_ykd.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/exec/vsf_ykd.c 2008-11-17 15:54:02.390605772 +0100 +@@ -458,7 +458,7 @@ + memcpy (&ykd_ring_id, ring_id, sizeof (struct memb_ring_id)); + + if (first_run) { +- ykd_state.last_primary.member_list[0] = this_ip->nodeid; ++ ykd_state.last_primary.member_list[0] = totempg_my_nodeid_get(); + ykd_state.last_primary.member_list_entries = 1; + ykd_state.last_primary.session_id = 0; + first_run = 0; +diff -uNr openais-0.80.3/include/saCkpt.h openais-0.80.3-r1661/include/saCkpt.h +--- openais-0.80.3/include/saCkpt.h 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/include/saCkpt.h 2008-11-17 15:54:00.450629028 +0100 +@@ -199,7 +199,7 @@ + SaCkptCheckpointHandleT checkpointHandle, + SaCkptSectionCreationAttributesT *sectionCreationAttributes, + const void *initialData, +- SaUint32T initialDataSize); ++ SaSizeT initialDataSize); + + + SaAisErrorT +diff -uNr openais-0.80.3/init/redhat openais-0.80.3-r1661/init/redhat +--- openais-0.80.3/init/redhat 2007-06-26 13:38:35.000000000 +0200 ++++ openais-0.80.3-r1661/init/redhat 2008-11-17 15:54:02.790606471 +0100 +@@ -15,6 +15,7 @@ + lockfile="/var/lock/subsys/$prog" + + start() { ++ [ -x "$exec" ] || exit 5 + echo -n $"Starting OpenAIS daemon ($prog): " + daemon $exec + retval=$? +diff -uNr openais-0.80.3/lcr/Makefile openais-0.80.3-r1661/lcr/Makefile +--- openais-0.80.3/lcr/Makefile 2006-04-21 01:17:16.000000000 +0200 ++++ openais-0.80.3-r1661/lcr/Makefile 2008-11-17 15:53:59.910615969 +0100 +@@ -27,7 +27,7 @@ + include ../Makefile.inc + + CFLAGS += -I../include +-LDFLAGS += -L./ ${DYFLAGS} ++override LDFLAGS += ${DYFLAGS} + + ifeq (${OPENAIS_COMPAT}, LINUX) + LDFLAGS += -ldl +@@ -57,7 +57,7 @@ + endif + + test: test.o uis.o lcr_ifact.o +- $(CC) $(LDFLAGS) test.o lcr_ifact.o uis.o -lpthread -o test ++ $(CC) $(LDFLAGS) -fPIC test.o lcr_ifact.o uis.o -lpthread -o test + + test_static: test.o libtest_a.o libtest_b.o uis.o lcr_ifact.o + $(CC) $(LDFLAGS) test.o libtest_a.o libtest_b.o lcr_ifact.o -o test_static +@@ -71,6 +71,12 @@ + libtest_b.o: libtest_b.c + $(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c -o $@ $(*F).c + ++lcr_ifact.o: lcr_ifact.c ++ $(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c -o $@ $(*F).c ++ ++test.o: test.c ++ $(CC) $(CFLAGS) $(CPPFLAGS) -fPIC -c -o $@ $(*F).c ++ + clean: + rm -f test libtest.so* *.o uic liblcr.so* liblcr.a *.lcrso *.da *.ba *.bb *.bbg \ + test_static +diff -uNr openais-0.80.3/lcr/lcr_ifact.c openais-0.80.3-r1661/lcr/lcr_ifact.c +--- openais-0.80.3/lcr/lcr_ifact.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lcr/lcr_ifact.c 2008-11-17 15:53:59.910615969 +0100 +@@ -45,6 +45,7 @@ + struct lcr_component_instance { + struct lcr_iface *ifaces; + int iface_count; ++ unsigned int comp_handle; + void *dl_handle; + int refcount; + char library_name[256]; +@@ -68,7 +69,7 @@ + .iterator = 0 + }; + +-static unsigned int g_component_handle; ++static unsigned int g_component_handle = 0xFFFFFFFF; + + #ifdef OPENAIS_LINUX + static int lcr_select_so (const struct dirent *dirent) +@@ -170,7 +171,6 @@ + + res = getcwd (cwd, sizeof (cwd)); + if (res != NULL) { +- strcat (cwd, "/"); + path_list[0] = strdup (cwd); + path_list_entries++; + } +@@ -291,6 +291,8 @@ + } + dl_handle = dlopen (dl_name, RTLD_LAZY); + if (dl_handle == NULL) { ++ fprintf (stderr, "LCR error loading plugin: %s\n", ++ dlerror()); + continue; + } + instance = lcr_comp_find (iface_name, version, iface_number); +@@ -301,8 +303,8 @@ + } + + /* +- * No matching interfaces found, try next shared object +- */ ++ * No matching interfaces found, try next shared object ++ */ + if (g_component_handle != 0xFFFFFFFF) { + hdb_handle_destroy (&lcr_component_instance_database, + g_component_handle); +@@ -349,19 +351,19 @@ + + // TODO error checking in this code is weak + /* +- * Find all *.lcrso files in search paths ++ * Search through all lcrso files for desired interface + */ + for (i = 0; i < path_list_entries; i++) { +- res = interface_find_and_load ( +- path_list[i], +- iface_name, +- version, +- &instance, +- &iface_number); ++ res = interface_find_and_load ( ++ path_list[i], ++ iface_name, ++ version, ++ &instance, ++ &iface_number); + +- if (res == 0) { +- goto found; +- } ++ if (res == 0) { ++ goto found; ++ } + } + + /* +@@ -379,9 +381,10 @@ + iface_handle); + hdb_handle_get (&lcr_iface_instance_database, + *iface_handle, (void *)&iface_instance); +- iface_instance->component_handle = g_component_handle; ++ iface_instance->component_handle = instance->comp_handle; + iface_instance->context = context; + iface_instance->destructor = instance->ifaces[iface_number].destructor; ++ hdb_handle_put (&lcr_iface_instance_database, *iface_handle); + return (0); + } + +@@ -408,17 +411,21 @@ + void lcr_component_register (struct lcr_comp *comp) + { + struct lcr_component_instance *instance; ++ static unsigned int comp_handle; + + hdb_handle_create (&lcr_component_instance_database, + sizeof (struct lcr_component_instance), +- &g_component_handle); ++ &comp_handle); + hdb_handle_get (&lcr_component_instance_database, +- g_component_handle, (void *)&instance); ++ comp_handle, (void *)&instance); + + instance->ifaces = comp->ifaces; + instance->iface_count = comp->iface_count; ++ instance->comp_handle = comp_handle; + instance->dl_handle = NULL; + + hdb_handle_put (&lcr_component_instance_database, +- g_component_handle); ++ comp_handle); ++ ++ g_component_handle = comp_handle; + } +diff -uNr openais-0.80.3/lcr/test.c openais-0.80.3-r1661/lcr/test.c +--- openais-0.80.3/lcr/test.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lcr/test.c 2008-11-17 15:53:59.900633359 +0100 +@@ -87,7 +87,7 @@ + (void *)0xaaaa1111); + assert (res == 0); + +- a_iface_ver1 = (struct iface *)a_iface_ver0_p; ++ a_iface_ver1 = (struct iface *)a_iface_ver1_p; + + res = lcr_ifact_reference ( + &b_ifact_handle_ver1, +@@ -97,7 +97,7 @@ + (void *)0xbbbb1111); + assert (res == 0); + +- b_iface_ver1 = (struct iface *)b_iface_ver0_p; ++ b_iface_ver1 = (struct iface *)b_iface_ver1_p; + + a_iface_ver0->func1(); + a_iface_ver0->func2(); +diff -uNr openais-0.80.3/lib/amf.c openais-0.80.3-r1661/lib/amf.c +--- openais-0.80.3/lib/amf.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lib/amf.c 2008-11-17 15:54:03.480606331 +0100 +@@ -101,6 +101,10 @@ + + void amfHandleInstanceDestructor (void *instance) + { ++ struct amfInstance *amfInstance = instance; ++ ++ pthread_mutex_destroy (&amfInstance->response_mutex); ++ pthread_mutex_destroy (&amfInstance->dispatch_mutex); + } + + SaAisErrorT +diff -uNr openais-0.80.3/lib/cfg.c openais-0.80.3-r1661/lib/cfg.c +--- openais-0.80.3/lib/cfg.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lib/cfg.c 2008-11-17 15:54:03.480606331 +0100 +@@ -88,6 +88,10 @@ + */ + void cfg_handleInstanceDestructor (void *instance) + { ++ struct cfg_instance *cfg_instance = instance; ++ ++ pthread_mutex_destroy (&cfg_instance->response_mutex); ++ pthread_mutex_destroy (&cfg_instance->dispatch_mutex); + } + + SaAisErrorT +diff -uNr openais-0.80.3/lib/ckpt.c openais-0.80.3-r1661/lib/ckpt.c +--- openais-0.80.3/lib/ckpt.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lib/ckpt.c 2008-11-17 15:54:03.480606331 +0100 +@@ -155,15 +155,24 @@ + */ + void ckptHandleInstanceDestructor (void *instance) + { ++ struct ckptInstance *ckptInstance = instance; ++ ++ pthread_mutex_destroy (&ckptInstance->response_mutex); ++ pthread_mutex_destroy (&ckptInstance->dispatch_mutex); + } + + void checkpointHandleInstanceDestructor (void *instance) + { +- return; ++ struct ckptCheckpointInstance *checkpointInstance = instance; ++ ++ pthread_mutex_destroy (&checkpointInstance->response_mutex); + } + + void ckptSectionIterationHandleInstanceDestructor (void *instance) + { ++ struct ckptSectionIterationInstance *iterationInstance = instance; ++ ++ pthread_mutex_destroy (&iterationInstance->response_mutex); + } + + static void ckptSectionIterationInstanceFinalize (struct ckptSectionIterationInstance *ckptSectionIterationInstance) +@@ -191,8 +200,6 @@ + + saHandleDestroy (&ckptSectionIterationHandleDatabase, + ckptSectionIterationInstance->sectionIterationHandle); +- +- pthread_mutex_destroy (&ckptSectionIterationInstance->response_mutex); + } + + static void ckptCheckpointInstanceFinalize (struct ckptCheckpointInstance *ckptCheckpointInstance) +@@ -216,8 +223,6 @@ + list_del (&ckptCheckpointInstance->list); + + saHandleDestroy (&checkpointHandleDatabase, ckptCheckpointInstance->checkpointHandle); +- +- pthread_mutex_destroy (&ckptCheckpointInstance->response_mutex); + } + + static void ckptInstanceFinalize (struct ckptInstance *ckptInstance) +@@ -1027,7 +1032,7 @@ + SaCkptCheckpointHandleT checkpointHandle, + SaCkptSectionCreationAttributesT *sectionCreationAttributes, + const void *initialData, +- SaUint32T initialDataSize) ++ SaSizeT initialDataSize) + { + SaAisErrorT error; + struct ckptCheckpointInstance *ckptCheckpointInstance; +diff -uNr openais-0.80.3/lib/clm.c openais-0.80.3-r1661/lib/clm.c +--- openais-0.80.3/lib/clm.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lib/clm.c 2008-11-17 15:54:03.490605981 +0100 +@@ -92,6 +92,10 @@ + + void clmHandleInstanceDestructor (void *instance) + { ++ struct clmInstance *clmInstance = instance; ++ ++ pthread_mutex_destroy (&clmInstance->response_mutex); ++ pthread_mutex_destroy (&clmInstance->dispatch_mutex); + } + + +@@ -494,9 +498,6 @@ + clmInstance->finalize = 1; + + pthread_mutex_unlock (&clmInstance->response_mutex); +- pthread_mutex_destroy (&clmInstance->response_mutex); +- +- pthread_mutex_destroy (&clmInstance->dispatch_mutex); + + saHandleDestroy (&clmHandleDatabase, clmHandle); + +diff -uNr openais-0.80.3/lib/cpg.c openais-0.80.3-r1661/lib/cpg.c +--- openais-0.80.3/lib/cpg.c 2007-06-25 05:09:31.000000000 +0200 ++++ openais-0.80.3-r1661/lib/cpg.c 2008-11-17 15:54:03.490605981 +0100 +@@ -1,7 +1,7 @@ + /* + * vi: set autoindent tabstop=4 shiftwidth=4 : + * +- * Copyright (c) 2006-2007 Red Hat, Inc. ++ * Copyright (c) 2006-2008 Red Hat, Inc. + * + * All rights reserved. + * +@@ -76,6 +76,10 @@ + */ + static void cpg_instance_destructor (void *instance) + { ++ struct cpg_inst *cpg_inst = instance; ++ ++ pthread_mutex_destroy (&cpg_inst->response_mutex); ++ pthread_mutex_destroy (&cpg_inst->dispatch_mutex); + } + + +@@ -103,8 +107,7 @@ + goto error_destroy; + } + +- error = saServiceConnect (&cpg_inst->dispatch_fd, +- &cpg_inst->response_fd, ++ error = saServiceConnect (&cpg_inst->response_fd, &cpg_inst->dispatch_fd, + CPG_SERVICE); + if (error != SA_AIS_OK) { + goto error_put_destroy; +@@ -153,9 +156,6 @@ + cpg_inst->finalize = 1; + + pthread_mutex_unlock (&cpg_inst->response_mutex); +- pthread_mutex_destroy (&cpg_inst->response_mutex); +- +- pthread_mutex_destroy (&cpg_inst->dispatch_mutex); + + saHandleDestroy (&cpg_handle_t_db, handle); + +@@ -457,7 +457,7 @@ + iov[0].iov_base = &req_lib_cpg_trackstart; + iov[0].iov_len = sizeof (struct req_lib_cpg_trackstart); + +- error = saSendMsgReceiveReply (cpg_inst->dispatch_fd, iov, 1, ++ error = saSendMsgReceiveReply (cpg_inst->response_fd, iov, 1, + &res_lib_cpg_trackstart, sizeof (struct res_lib_cpg_trackstart)); + + if (error != SA_AIS_OK) { +diff -uNr openais-0.80.3/lib/evs.c openais-0.80.3-r1661/lib/evs.c +--- openais-0.80.3/lib/evs.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lib/evs.c 2008-11-17 15:54:03.490605981 +0100 +@@ -80,6 +80,10 @@ + */ + static void evs_instance_destructor (void *instance) + { ++ struct evs_inst *evs_inst = instance; ++ ++ pthread_mutex_destroy (&evs_inst->response_mutex); ++ pthread_mutex_destroy (&evs_inst->dispatch_mutex); + } + + +@@ -162,9 +166,6 @@ + evs_inst->finalize = 1; + + pthread_mutex_unlock (&evs_inst->response_mutex); +- pthread_mutex_destroy (&evs_inst->response_mutex); +- +- pthread_mutex_destroy (&evs_inst->dispatch_mutex); + + saHandleDestroy (&evs_handle_t_db, handle); + /* +diff -uNr openais-0.80.3/lib/evt.c openais-0.80.3-r1661/lib/evt.c +--- openais-0.80.3/lib/evt.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lib/evt.c 2008-11-17 15:54:03.480606331 +0100 +@@ -110,10 +110,12 @@ + * ei_version: version sent to the evtInitialize call. + * ei_node_id: our node id. + * ei_node_name: our node name. +- * ei_finalize: instance in finalize flag +- * ei_dispatch_mutex: mutex for dispatch fd ++ * ei_dispatch_mutex: mutex for dispatch fd. This lock also ensures that ++ * only one thread is using ei_dispatch_data. + * ei_response_mutex: mutex for response fd + * ei_channel_list: list of associated channels (struct handle_list) ++ * ei_dispatch_data: event buffer for evtDispatch ++ * ei_finalize: instance in finalize flag + * ei_data_available: Indicates that there is a pending event message though + * there may not be a poll event. This can happen + * when we get a SA_AIS_ERR_TRY_AGAIN when asking for an +@@ -127,11 +129,12 @@ + SaVersionT ei_version; + SaClmNodeIdT ei_node_id; + SaNameT ei_node_name; +- int ei_finalize; + pthread_mutex_t ei_dispatch_mutex; + pthread_mutex_t ei_response_mutex; + struct list_head ei_channel_list; +- int ei_data_available; ++ struct res_overlay ei_dispatch_data; ++ unsigned int ei_finalize:1; ++ unsigned int ei_data_available:1; + }; + + +@@ -245,6 +248,9 @@ + saHandleDestroy(&channel_handle_db, handle); + saHandleInstancePut(&channel_handle_db, handle); + } ++ ++ pthread_mutex_destroy(&evti->ei_dispatch_mutex); ++ pthread_mutex_destroy(&evti->ei_response_mutex); + } + + /* +@@ -272,6 +278,7 @@ + saEvtEventFree(handle); + } + ++ pthread_mutex_destroy(&eci->eci_mutex); + } + + /* +@@ -296,6 +303,8 @@ + if (edi->edi_event_data) { + free(edi->edi_event_data); + } ++ ++ pthread_mutex_destroy(&edi->edi_mutex); + } + + static SaAisErrorT evt_recv_event(int fd, struct lib_event_data **msg) +@@ -599,7 +608,6 @@ + int ignore_dispatch = 0; + int cont = 1; /* always continue do loop except when set to 0 */ + int poll_fd; +- struct res_overlay dispatch_data; + struct lib_event_data *evt = 0; + struct res_evt_event_data res; + +@@ -674,15 +682,15 @@ + } + + if (ufds.revents & POLLIN) { +- error = saRecvRetry (evti->ei_dispatch_fd, &dispatch_data.header, ++ error = saRecvRetry (evti->ei_dispatch_fd, &evti->ei_dispatch_data.header, + sizeof (mar_res_header_t)); + + if (error != SA_AIS_OK) { + goto dispatch_unlock; + } +- if (dispatch_data.header.size > sizeof (mar_res_header_t)) { +- error = saRecvRetry (evti->ei_dispatch_fd, &dispatch_data.data, +- dispatch_data.header.size - sizeof (mar_res_header_t)); ++ if (evti->ei_dispatch_data.header.size > sizeof (mar_res_header_t)) { ++ error = saRecvRetry (evti->ei_dispatch_fd, &evti->ei_dispatch_data.data, ++ evti->ei_dispatch_data.header.size - sizeof (mar_res_header_t)); + if (error != SA_AIS_OK) { + goto dispatch_unlock; + } +@@ -697,7 +705,7 @@ + * Fake up a header message and the switch statement will + * take care of the rest. + */ +- dispatch_data.header.id = MESSAGE_RES_EVT_AVAILABLE; ++ evti->ei_dispatch_data.header.id = MESSAGE_RES_EVT_AVAILABLE; + } + + /* +@@ -707,13 +715,11 @@ + * EvtFinalize has been called in another thread. + */ + memcpy(&callbacks, &evti->ei_callback, sizeof(evti->ei_callback)); +- pthread_mutex_unlock(&evti->ei_dispatch_mutex); +- + + /* + * Dispatch incoming response + */ +- switch (dispatch_data.header.id) { ++ switch (evti->ei_dispatch_data.header.id) { + + case MESSAGE_RES_EVT_AVAILABLE: + evti->ei_data_available = 0; +@@ -782,7 +788,7 @@ + case MESSAGE_RES_EVT_CHAN_OPEN_CALLBACK: + { + struct res_evt_open_chan_async *resa = +- (struct res_evt_open_chan_async *)&dispatch_data; ++ (struct res_evt_open_chan_async *)&evti->ei_dispatch_data; + struct event_channel_instance *eci; + + /* +@@ -815,11 +821,13 @@ + break; + + default: +- DPRINT (("Dispatch: Bad message type 0x%x\n", dispatch_data.header.id)); ++ DPRINT (("Dispatch: Bad message type 0x%x\n", evti->ei_dispatch_data.header.id)); + error = SA_AIS_ERR_LIBRARY; +- goto dispatch_put; ++ goto dispatch_unlock; + } + ++ pthread_mutex_unlock(&evti->ei_dispatch_mutex); ++ + /* + * If empty is zero it means the we got the + * message from the queue and we are responsible +@@ -854,7 +862,7 @@ + goto dispatch_put; + + dispatch_unlock: +- pthread_mutex_unlock(&evti->ei_dispatch_mutex); ++ pthread_mutex_unlock(&evti->ei_dispatch_mutex); + dispatch_put: + saHandleInstancePut(&evt_instance_handle_db, evtHandle); + return error; +@@ -896,9 +904,6 @@ + evti->ei_finalize = 1; + + pthread_mutex_unlock (&evti->ei_response_mutex); +- pthread_mutex_destroy (&evti->ei_response_mutex); +- +- pthread_mutex_destroy (&evti->ei_dispatch_mutex); + + saHandleDestroy(&evt_instance_handle_db, evtHandle); + /* +diff -uNr openais-0.80.3/lib/lck.c openais-0.80.3-r1661/lib/lck.c +--- openais-0.80.3/lib/lck.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lib/lck.c 2008-11-17 15:54:03.480606331 +0100 +@@ -144,11 +144,14 @@ + */ + void lckHandleInstanceDestructor (void *instance) + { ++ struct lckInstance *lckInstance = instance; ++ ++ pthread_mutex_destroy (&lckInstance->response_mutex); ++ pthread_mutex_destroy (&lckInstance->dispatch_mutex); + } + + void lckResourceHandleInstanceDestructor (void *instance) + { +- return; + } + + void lckResourceHandleLockIdInstanceDestructor (void *instance) +diff -uNr openais-0.80.3/lib/msg.c openais-0.80.3-r1661/lib/msg.c +--- openais-0.80.3/lib/msg.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lib/msg.c 2008-11-17 15:54:03.490605981 +0100 +@@ -131,11 +131,14 @@ + */ + void msgHandleInstanceDestructor (void *instance) + { ++ struct msgInstance *msgInstance = instance; ++ ++ pthread_mutex_destroy (&msgInstance->response_mutex); ++ pthread_mutex_destroy (&msgInstance->dispatch_mutex); + } + + void queueHandleInstanceDestructor (void *instance) + { +- return; + } + + #ifdef COMPILE_OUT +diff -uNr openais-0.80.3/lib/util.c openais-0.80.3-r1661/lib/util.c +--- openais-0.80.3/lib/util.c 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/lib/util.c 2008-11-17 15:54:03.490605981 +0100 +@@ -543,7 +543,7 @@ + handleDatabase->handleCount += 1; + newHandles = (struct saHandle *)realloc (handleDatabase->handles, + sizeof (struct saHandle) * handleDatabase->handleCount); +- if (newHandles == 0) { ++ if (newHandles == NULL) { + pthread_mutex_unlock (&handleDatabase->mutex); + return (SA_AIS_ERR_NO_MEMORY); + } +@@ -552,6 +552,8 @@ + + instance = malloc (instanceSize); + if (instance == 0) { ++ free (newHandles); ++ pthread_mutex_unlock (&handleDatabase->mutex); + return (SA_AIS_ERR_NO_MEMORY); + } + +diff -uNr openais-0.80.3/man/openais.conf.5 openais-0.80.3-r1661/man/openais.conf.5 +--- openais-0.80.3/man/openais.conf.5 2007-06-24 08:33:09.000000000 +0200 ++++ openais-0.80.3-r1661/man/openais.conf.5 2008-11-17 15:54:04.010616877 +0100 +@@ -135,6 +135,17 @@ + reserved and should not be used. + + .TP ++clear_node_high_bit ++This configuration option is optional and is only relevant when no nodeid is ++specified. Some openais clients require a signed 32 bit nodeid that is greater ++than zero however by default openais uses all 32 bits of the IPv4 address space ++when generating a nodeid. Set this option to yes to force the high bit to be ++zero and therefor ensure the nodeid is a positive signed 32 bit integer. ++ ++WARNING: The clusters behavior is undefined if this option is enabled on only ++a subset of the cluster (for example during a rolling upgrade). ++ ++.TP + secauth + This specifies that HMAC/SHA1 authentication should be used to authenticate + all messages. It further specifies that all data should be encrypted with the +diff -uNr openais-0.80.3/test/Makefile openais-0.80.3-r1661/test/Makefile +--- openais-0.80.3/test/Makefile 2007-06-25 04:52:58.000000000 +0200 ++++ openais-0.80.3-r1661/test/Makefile 2008-11-17 15:53:59.760604514 +0100 +@@ -49,7 +49,7 @@ + + all: testclm testamf1 \ + testckpt ckptstress ckptbench \ +- ckptbenchth ckpt-rd ckpt-wr testevt testevs \ ++ ckptbenchth ckpt-rd ckpt-wr ckpt-overload-exit testevt testevs \ + evsbench subscription publish evtbench unlink testclm2 testlck \ + testmsg testcpg testcpg2 cpgbench openais-cfgtool + +@@ -128,6 +128,9 @@ + ckpt-wr: ckpt-wr.o sa_error.o $(LIBRARIES) + $(CC) $(LDFLAGS) -o ckpt-wr ckpt-wr.o sa_error.o $(LIBS) + ++ckpt-overload-exit: ckpt-overload-exit.o sa_error.o $(LIBRARIES) ++ $(CC) $(LDFLAGS) -o ckpt-overload-exit ckpt-overload-exit.o sa_error.o $(LIBS) ++ + testclm2: testclm2.o $(LIBRARIES) + $(CC) $(LDFLAGS) -o testclm2 testclm2.o $(LIBS) + +diff -uNr openais-0.80.3/test/ckpt-overload-exit.c openais-0.80.3-r1661/test/ckpt-overload-exit.c +--- openais-0.80.3/test/ckpt-overload-exit.c 1970-01-01 01:00:00.000000000 +0100 ++++ openais-0.80.3-r1661/test/ckpt-overload-exit.c 2008-11-17 15:53:59.760604514 +0100 +@@ -0,0 +1,157 @@ ++/* ++ * Copyright (c) 2008 Red Hat, Inc. ++ * ++ * All rights reserved. ++ * ++ * Author: Steven Dake (sdake@redhat.com) ++ * ++ * 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. ++ */ ++/* ++ * Overloads the ckpt system with checkpoints (30k checkpoints) and then exits ++ * ungracefully. This will cause the entire system to go into overload ++ * as it sends out close messages for the 30k open checkpoints. ++ */ ++ ++ ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <errno.h> ++#include <unistd.h> ++#include <sys/types.h> ++#include <sys/socket.h> ++#include <sys/select.h> ++#include <sys/un.h> ++#include <time.h> ++ ++#include "saAis.h" ++#include "saCkpt.h" ++#include "sa_error.h" ++ ++#define SECONDS_TO_EXPIRE 500 ++ ++int ckptinv; ++void printSaNameT (SaNameT *name) ++{ ++ int i; ++ ++ for (i = 0; i < name->length; i++) { ++ printf ("%c", name->value[i]); ++ } ++} ++ ++SaVersionT version = { 'B', 1, 1 }; ++ ++SaNameT checkpointName = { 16, "checkpoint-sync\0" }; ++ ++SaCkptCheckpointCreationAttributesT checkpointCreationAttributes = { ++ .creationFlags = SA_CKPT_WR_ALL_REPLICAS, ++ .checkpointSize = 250000, ++ .retentionDuration = SA_TIME_ONE_SECOND * 60, ++ .maxSections = 1, ++ .maxSectionSize = 250000, ++ .maxSectionIdSize = 10 ++}; ++ ++char readBuffer1[1025]; ++ ++SaCkptIOVectorElementT ReadVectorElements[] = { ++ { ++ SA_CKPT_DEFAULT_SECTION_ID, ++ readBuffer1, ++ sizeof (readBuffer1), ++ 0, ++ 0 ++ } ++}; ++ ++#define DATASIZE 127000 ++char data[DATASIZE]; ++SaCkptIOVectorElementT WriteVectorElements[] = { ++ { ++ SA_CKPT_DEFAULT_SECTION_ID, ++ data, /*"written data #1, this should extend past end of old section data", */ ++ DATASIZE, /*sizeof ("data #1, this should extend past end of old section data") + 1, */ ++ 0, //5, ++ 0 ++ } ++}; ++ ++SaCkptCallbacksT callbacks = { ++ 0, ++ 0 ++}; ++ ++#define MAX_DATA_SIZE 100 ++ ++int main (void) { ++ SaCkptHandleT ckptHandle; ++ SaCkptCheckpointHandleT checkpointHandle; ++ SaAisErrorT error; ++ char data[MAX_DATA_SIZE]; ++ SaCkptIOVectorElementT writeElement; ++ SaUint32T erroroneousVectorIndex = 0; ++ int i; ++ ++ error = saCkptInitialize (&ckptHandle, &callbacks, &version); ++ printf ("%s: CkptInitialize\n", ++ get_test_output (error, SA_AIS_OK)); ++ ++ for (i = 0; i < 30000; i++) { ++ checkpointName.length = ++ sprintf((char*)checkpointName.value, "ckp%05d",i); ++ ++ do { ++ error = saCkptCheckpointOpen (ckptHandle, ++ &checkpointName, ++ &checkpointCreationAttributes, ++ SA_CKPT_CHECKPOINT_CREATE|SA_CKPT_CHECKPOINT_READ|SA_CKPT_CHECKPOINT_WRITE, ++ 0, ++ &checkpointHandle); ++ } while (error == SA_AIS_ERR_TRY_AGAIN); ++ ++ sprintf((char*)&data, "%04d", i); ++ writeElement.sectionId = (SaCkptSectionIdT)SA_CKPT_DEFAULT_SECTION_ID; ++ writeElement.dataBuffer = data; ++ writeElement.dataSize = strlen (data) + 1; ++ writeElement.dataOffset = 0; ++ writeElement.readSize = 0; ++ ++ do { ++ error = saCkptCheckpointWrite (checkpointHandle, ++ &writeElement, ++ 1, ++ &erroroneousVectorIndex); ++ ++ } while (error == SA_AIS_ERR_TRY_AGAIN); ++ ++ } ++ ++ return (0); ++ ++} +diff -uNr openais-0.80.3/test/testckpt.c openais-0.80.3-r1661/test/testckpt.c +--- openais-0.80.3/test/testckpt.c 2007-06-25 10:42:58.000000000 +0200 ++++ openais-0.80.3-r1661/test/testckpt.c 2008-11-17 15:53:59.760604514 +0100 +@@ -341,7 +341,7 @@ + timersub (&tv_end, &tv_start, &tv_elapsed); + printf ("Elapsed Time to expiry is %ld & %ld usec (should be about %d seconds)\n", + tv_elapsed.tv_sec, +- tv_elapsed.tv_usec, ++ (long) tv_elapsed.tv_usec, + SECONDS_TO_EXPIRE); + + error = saCkptCheckpointRetentionDurationSet (checkpointHandle, diff --git a/sys-cluster/openais/openais-0.80.3.ebuild b/sys-cluster/openais/openais-0.80.3-r1.ebuild index 9a044328a86f..84ed541aed59 100644 --- a/sys-cluster/openais/openais-0.80.3.ebuild +++ b/sys-cluster/openais/openais-0.80.3-r1.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2008 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-cluster/openais/openais-0.80.3.ebuild,v 1.1 2008/03/17 16:02:41 xmerlin Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-cluster/openais/openais-0.80.3-r1.ebuild,v 1.1 2008/11/21 22:55:48 xmerlin Exp $ inherit eutils flag-o-matic toolchain-funcs @@ -20,6 +20,16 @@ src_unpack() { epatch "${FILESDIR}"/${P}-Makefile-ARCH.patch || die epatch "${FILESDIR}"/${P}-Makefile-LIBDIR.patch || die epatch "${FILESDIR}"/${P}-Makefile.inc-FLAGS.patch || die + + epatch "${FILESDIR}"/${P}-Makefile.inc-VARS.patch || die + epatch "${FILESDIR}"/${P}-Makefile-VARS.patch || die + + #epatch "${FILESDIR}"/${P}-r1514.patch || die + epatch "${FILESDIR}"/${P}-r1661.patch || die + + #epatch "${FILESDIR}"/${P}-r1661-pacemaker-openais.conf.patch || die + #epatch "${FILESDIR}"/${P}-r1661-pacemaker.patch || die + #epatch "${FILESDIR}"/pacemaker.diff || die } pkg_setup() { |