See patches. I split it to two parts, where: part 1 = Functionality part 2 = cpgbound
Regards, Honza
>From 512a6df157634e7bd0230c8f55965a6bfc9423ad Mon Sep 17 00:00:00 2001 From: Jan Friesse <jfrie...@redhat.com> Date: Thu, 13 Aug 2009 15:27:38 +0200 Subject: [PATCH 1/2] Better limits for OpenAIS The current OpenAIS has bugs where the maximum message size is 470k when the IPC limit is more like 1mb. This patch does the following things: 1) fixes that defect 2) returns INVALID_PARAM in the case a limit is exceeded in util.h 3) returns INVALID_PARAM in the case a limit is exceeded in totempg by ipc connections --- branches/whitetank/exec/ipc.c | 17 ++++++++++++++++- branches/whitetank/exec/totempg.c | 27 +++++++++++++++++++++------ branches/whitetank/lib/util.c | 3 +++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/branches/whitetank/exec/ipc.c b/branches/whitetank/exec/ipc.c index aaffd85..025086e 100644 --- a/branches/whitetank/exec/ipc.c +++ b/branches/whitetank/exec/ipc.c @@ -363,6 +363,19 @@ retry_semop: send_ok = 0; } + /* + * This happens when the message contains some kind of invalid + * parameter, such as an invalid size + */ + if (reserved_msgs == -1) { + res_overlay.header.size = + ais_service[conn_info->service]->lib_service[header->id].response_size; + res_overlay.header.id = + ais_service[conn_info->service]->lib_service[header->id].response_id; + res_overlay.header.error = SA_AIS_ERR_INVALID_PARAM; + openais_response_send (conn_info, &res_overlay, + res_overlay.header.size); + } else if (send_ok) { ipc_serialize_lock_fn(); ais_service[conn_info->service]->lib_service[header->id].lib_handler_fn (conn_info, header); @@ -380,7 +393,9 @@ retry_semop: res_overlay.header.size); } - totempg_groups_joined_release (reserved_msgs); + if (reserved_msgs != -1) { + totempg_groups_joined_release (reserved_msgs); + } openais_conn_refcount_dec (conn); } pthread_exit (0); diff --git a/branches/whitetank/exec/totempg.c b/branches/whitetank/exec/totempg.c index 0217ec3..f60c84d 100644 --- a/branches/whitetank/exec/totempg.c +++ b/branches/whitetank/exec/totempg.c @@ -146,6 +146,8 @@ static int mcast_packed_msg_count = 0; static int totempg_reserved = 0; +static unsigned int totempg_size_limit; + /* * Function and data used to log messages */ @@ -707,6 +709,8 @@ int totempg_initialize ( return (-1); } + totemsrp_net_mtu_adjust (totem_config); + res = totemmrp_initialize ( poll_handle, totem_config, @@ -720,7 +724,9 @@ int totempg_initialize ( callback_token_received_fn, 0); - totemsrp_net_mtu_adjust (totem_config); + totempg_size_limit = (totemmrp_avail() - 1) * + (totempg_totem_config->net_mtu - + sizeof (struct totempg_mcast) - 16); return (res); } @@ -779,7 +785,7 @@ static int mcast_msg ( } if (byte_count_send_ok (total_size + sizeof(unsigned short) * - (mcast_packed_msg_count+1)) == 0) { + (mcast_packed_msg_count)) == 0) { pthread_mutex_unlock (&mcast_msg_mutex); return(-1); @@ -859,6 +865,9 @@ static int mcast_msg ( iovecs[2].iov_len = max_packet_size; assert (totemmrp_avail() > 0); res = totemmrp_mcast (iovecs, 3, guarantee); + if (res == -1) { + goto error_exit; + } /* * Recalculate counts and indexes for the next. @@ -894,6 +903,7 @@ static int mcast_msg ( mcast_packed_msg_count++; } +error_exit: pthread_mutex_unlock (&mcast_msg_mutex); return (res); } @@ -906,7 +916,7 @@ static int msg_count_send_ok ( { int avail = 0; - avail = totemmrp_avail () - totempg_reserved - 1; + avail = totemmrp_avail (); return (avail > msg_count); } @@ -923,9 +933,9 @@ static int byte_count_send_ok ( unsigned int msg_count = 0; int avail = 0; - avail = totemmrp_avail () - 1; + avail = totemmrp_avail (); - msg_count = (byte_count / (totempg_totem_config->net_mtu - 25)) + 1; + msg_count = (byte_count / (totempg_totem_config->net_mtu - sizeof (struct totempg_mcast) - 16)); return (avail > msg_count); } @@ -935,7 +945,7 @@ static int send_reserve ( { unsigned int msg_count = 0; - msg_count = (msg_size / (totempg_totem_config->net_mtu - 25)) + 1; + msg_count = (msg_size / (totempg_totem_config->net_mtu - sizeof (struct totempg_mcast) - 16)) + 1; totempg_reserved += msg_count; return (msg_count); @@ -1156,6 +1166,10 @@ int totempg_groups_joined_reserve ( for (i = 0; i < iov_len; i++) { size += iovec[i].iov_len; } + if (size >= totempg_size_limit) { + reserved = -1; + goto error_put; + } reserved = send_reserve (size); if (msg_count_send_ok (reserved) == 0) { @@ -1163,6 +1177,7 @@ int totempg_groups_joined_reserve ( reserved = 0; } +error_put: hdb_handle_put (&totempg_groups_instance_database, handle); error_exit: diff --git a/branches/whitetank/lib/util.c b/branches/whitetank/lib/util.c index 5bdaeb4..5dc9292 100644 --- a/branches/whitetank/lib/util.c +++ b/branches/whitetank/lib/util.c @@ -574,6 +574,9 @@ openais_msg_send ( int req_buffer_idx = 0; for (i = 0; i < iov_len; i++) { + if ((req_buffer_idx + iov[i].iov_len) > REQ_SIZE) { + return (SA_AIS_ERR_INVALID_PARAM); + } memcpy (&ipc_segment->shared_memory->req_buffer[req_buffer_idx], iov[i].iov_base, iov[i].iov_len); -- 1.6.2.5
>From 20df53a7a60b47cd7c8eb4ab817d05df5b8d9b94 Mon Sep 17 00:00:00 2001 From: Jan Friesse <jfrie...@redhat.com> Date: Thu, 13 Aug 2009 15:29:22 +0200 Subject: [PATCH 2/2] Add cpgbound test program This program finds the boundary limit and displays it. --- branches/whitetank/test/Makefile | 12 +++- branches/whitetank/test/cpgbound.c | 123 ++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 branches/whitetank/test/cpgbound.c diff --git a/branches/whitetank/test/Makefile b/branches/whitetank/test/Makefile index 381c8eb..5992122 100644 --- a/branches/whitetank/test/Makefile +++ b/branches/whitetank/test/Makefile @@ -45,13 +45,15 @@ TEST_SRC = testclm.c testamf1.c \ testckpt.c ckptstress.c ckptbench.c \ ckptbenchth.c testevt.c testevs.c evsbench.c \ evsverify.c subscription.c publish.c evtbench.c \ - sa_error.c unlink.c testclm2.c testlck.c testconfdb.c + sa_error.c unlink.c testclm2.c testlck.c testconfdb.c \ + cpgbound.c all: testclm testamf1 \ testckpt ckptstress ckptbench \ ckptbenchth ckpt-rd ckpt-wr ckpt-overload-exit testevt testevs \ evsbench evsverify subscription publish evtbench unlink testclm2 \ - testlck testcpg testcpg2 testconfdb cpgbench openais-cfgtool testmsg + testlck testcpg testcpg2 testconfdb cpgbench openais-cfgtool testmsg \ + cpgbound testtimer: testtimer.o $(LIBRARIES) $(CC) $(LDFLAGS) -o testtimer testtimer.o ../exec/timer.o @@ -146,6 +148,9 @@ testmsg: testmsg.o $(LIBRARIES) testcpg: testcpg.o $(LIBRARIES) $(CC) $(LDFLAGS) -o testcpg testcpg.o $(LIBS) +cpgbound: cpgbound.o $(LIBRARIES) + $(CC) $(LDFLAGS) -o cpgbound cpgbound.o $(LIBS) + testcpg2: testcpg2.o $(LIBRARIES) $(CC) $(LDFLAGS) -o testcpg2 testcpg2.o $(LIBS) @@ -163,7 +168,8 @@ clean: testamf5 testamf6 testamfth testckpt ckptstress testtimer \ ckptbench ckptbenchth testevt testevs ckpt-wr ckpt-rd \ evsbench subscription publish evtbench unlink testcpg \ - testclm2 testlck testconfdb cpgbench openais-cfgtool testmsg + testclm2 testlck testconfdb cpgbench openais-cfgtool testmsg \ + cpgbound %.o: %.c $(CC) $(CFLAGS) $(CPPFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< diff --git a/branches/whitetank/test/cpgbound.c b/branches/whitetank/test/cpgbound.c new file mode 100644 index 0000000..44574a1 --- /dev/null +++ b/branches/whitetank/test/cpgbound.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2009 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Steven Dake (sd...@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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <string.h> +#include "saAis.h" +#include "cpg.h" + +static void cpg_deliver_fn ( + cpg_handle_t handle, + struct cpg_name *group_name, + uint32_t nodeid, + uint32_t pid, + void *m, + int msg_len) +{ +} + +static void cpg_confchg_fn ( + cpg_handle_t handle, + struct cpg_name *group_name, + struct cpg_address *member_list, int member_list_entries, + struct cpg_address *left_list, int left_list_entries, + struct cpg_address *joined_list, int joined_list_entries) +{ +} + +static cpg_callbacks_t callbacks = { + cpg_deliver_fn, + cpg_confchg_fn +}; + +static struct cpg_name group_name = { + .value = "cpg_bm", + .length = 6 +}; + + +static unsigned char buffer[2000000]; +int main (void) +{ + cpg_handle_t handle; + SaAisErrorT result; + unsigned int i = 0; + struct iovec iov; + int res; + unsigned int msg_size; + + result = cpg_initialize (&handle, &callbacks); + if (result != SA_AIS_OK) { + printf ("Couldn't initialize CPG service %d\n", result); + exit (0); + } + + res = cpg_join (handle, &group_name); + if (res != SA_AIS_OK) { + printf ("cpg_join failed with result %d\n", res); + exit (1); + } + + iov.iov_base = (void *)buffer; + + /* + * Demonstrate cpg_mcast_joined + */ + msg_size = 1025000; + for (i = 0; i < 1000000000; i++) { + iov.iov_len = msg_size; +try_again_one: + result = cpg_mcast_joined (handle, CPG_TYPE_AGREED, + &iov, 1); + if (result == SA_AIS_ERR_TRY_AGAIN) { + goto try_again_one; + } + if (result == SA_AIS_ERR_INVALID_PARAM) { + printf ("found boundary at %d\n", msg_size); + exit (1); + } + msg_size += 1; + printf ("msg size %d\n", msg_size); + result = cpg_dispatch (handle, CPG_DISPATCH_ALL); + } + + cpg_finalize (handle); + + return (0); +} -- 1.6.2.5
_______________________________________________ Openais mailing list Openais@lists.linux-foundation.org https://lists.linux-foundation.org/mailman/listinfo/openais