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 +#endif #include #include #include @@ -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 #include #include @@ -54,7 +56,11 @@ #include #include #include +#if defined(HAVE_GETPEERUCRED) +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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,