The current trunk 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 coroipcc 3) returns INVALID_PARAM in the case a limit is exceeded in totempg by ipc connections 4) adds a cpgbound program which finds the boundary limit and displays it. Regards -steve
Index: test/cpgbound.c =================================================================== --- test/cpgbound.c (revision 0) +++ test/cpgbound.c (revision 0) @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2009 Red Hat, Inc. + * + * All rights reserved. + * + * Author: Steven Dake ([email protected]) + * + * This software licensed under BSD license, the text of which follows: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the MontaVista Software, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <string.h> +#include <corosync/corotypes.h> +#include <corosync/cpg.h> + +static void cpg_deliver_fn ( + cpg_handle_t handle, + const struct cpg_name *group_name, + uint32_t nodeid, + uint32_t pid, + void *m, + size_t msg_len) +{ +} + +static void cpg_confchg_fn ( + cpg_handle_t handle, + const struct cpg_name *group_name, + const struct cpg_address *member_list, size_t member_list_entries, + const struct cpg_address *left_list, size_t left_list_entries, + const struct cpg_address *joined_list, size_t 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; + cs_error_t result; + unsigned int i = 0; + struct iovec iov; + int res; + unsigned int msg_size; + + result = cpg_initialize (&handle, &callbacks); + if (result != CS_OK) { + printf ("Couldn't initialize CPG service %d\n", result); + exit (0); + } + + res = cpg_join (handle, &group_name); + if (res != CS_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 == CS_ERR_TRY_AGAIN) { + goto try_again_one; + } + if (result == CS_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, CS_DISPATCH_ALL); + } + + cpg_finalize (handle); + + return (0); +} Index: test/Makefile.am =================================================================== --- test/Makefile.am (revision 2384) +++ test/Makefile.am (working copy) @@ -36,7 +36,7 @@ noinst_PROGRAMS = testevs evsbench evsverify cpgverify testcpg testcpg2 cpgbench testconfdb \ logsysbench logsysrec testquorum testvotequorum1 testvotequorum2 \ logsys_s logsys_t1 logsys_t2 testcpgzc cpgbenchzc testzcgc \ - stress_cpgzc stress_cpgfdget stress_cpgcontext + stress_cpgzc stress_cpgfdget stress_cpgcontext cpgbound testevs_LDADD = -levs -lcoroipcc testevs_LDFLAGS = -L../lib @@ -66,6 +66,8 @@ evsverify_LDFLAGS = -L../lib -L../exec cpgverify_LDADD = -lcpg -ltotem_pg -lcoroipcc cpgverify_LDFLAGS = -L../lib -L../exec +cpgbound_LDADD = -lcpg -lcoroipcc +cpgbound_LDFLAGS = -L../lib evsbench_LDADD = -levs -lcoroipcc evsbench_LDFLAGS = -L../lib cpgbench_LDADD = -lcpg -lcoroipcc Index: exec/totempg.c =================================================================== --- exec/totempg.c (revision 2384) +++ exec/totempg.c (working copy) @@ -155,6 +155,8 @@ static int totempg_reserved = 0; +static unsigned int totempg_size_limit; + /* * Function and data used to log messages */ @@ -719,6 +721,8 @@ return (-1); } + totemsrp_net_mtu_adjust (totem_config); + res = totemmrp_initialize ( poll_handle, totem_config, @@ -732,7 +736,9 @@ 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); } @@ -791,7 +797,7 @@ } 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); @@ -872,6 +878,9 @@ 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. @@ -907,6 +916,7 @@ mcast_packed_msg_count++; } +error_exit: pthread_mutex_unlock (&mcast_msg_mutex); return (res); } @@ -919,7 +929,7 @@ { int avail = 0; - avail = totemmrp_avail () - totempg_reserved - 1; + avail = totemmrp_avail (); return (avail > msg_count); } @@ -930,9 +940,9 @@ 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); } @@ -942,7 +952,7 @@ { 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); @@ -1163,6 +1173,10 @@ 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) { @@ -1170,6 +1184,7 @@ reserved = 0; } +error_put: hdb_handle_put (&totempg_groups_instance_database, handle); error_exit: Index: exec/coroipcs.c =================================================================== --- exec/coroipcs.c (revision 2384) +++ exec/coroipcs.c (working copy) @@ -625,6 +625,18 @@ header, conn_info->sending_allowed_private_data); + /* + * This happens when the message contains some kind of invalid + * parameter, such as an invalid size + */ + if (send_ok == -1) { + coroipc_response_header.size = sizeof (coroipc_response_header_t); + coroipc_response_header.id = 0; + coroipc_response_header.error = CS_ERR_INVALID_PARAM; + coroipcs_response_send (conn_info, + &coroipc_response_header, + sizeof (coroipc_response_header_t)); + } else if (send_ok) { api->serialize_lock(); api->handler_fn_get (conn_info->service, header->id) (conn_info, header); Index: exec/main.c =================================================================== --- exec/main.c (revision 2384) +++ exec/main.c (working copy) @@ -573,6 +573,9 @@ pd->reserved_msgs = totempg_groups_joined_reserve ( corosync_group_handle, &reserve_iovec, 1); + if (pd->reserved_msgs == -1) { + return (-1); + } sending_allowed = (corosync_quorum_is_quorate() == 1 || @@ -590,6 +593,9 @@ struct sending_allowed_private_data_struct *pd = (struct sending_allowed_private_data_struct *)sending_allowed_private_data; + if (pd->reserved_msgs == -1) { + return; + } totempg_groups_joined_release (pd->reserved_msgs); } Index: lib/coroipcc.c =================================================================== --- lib/coroipcc.c (revision 2384) +++ lib/coroipcc.c (working copy) @@ -408,6 +408,10 @@ int req_buffer_idx = 0; for (i = 0; i < iov_len; i++) { + if ((req_buffer_idx + iov[i].iov_len) > + ipc_instance->request_size) { + return (CS_ERR_INVALID_PARAM); + } memcpy (&ipc_instance->request_buffer[req_buffer_idx], iov[i].iov_base, iov[i].iov_len);
_______________________________________________ Openais mailing list [email protected] https://lists.linux-foundation.org/mailman/listinfo/openais
