Hello community,
here is the log from the commit of package libqb for openSUSE:Factory checked in at 2013-08-04 20:39:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libqb (Old)
and /work/SRC/openSUSE:Factory/.libqb.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libqb"
Changes:
--------
--- /work/SRC/openSUSE:Factory/libqb/libqb.changes 2013-07-08 07:18:12.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.libqb.new/libqb.changes 2013-08-04 23:52:27.000000000 +0200
@@ -1,0 +2,27 @@
+Fri Jul 26 01:19:30 UTC 2013 - ygao@suse.com
+
+- Bump version to 0.16.0
+- ipc_socket.c: Detect EOF connection on connection STREAM socket
+- ipc_socket.c: Handle the unlikely event of an EAGAIN or EINTR during dgram max size detection
+- Fixes sem leak
+- Fixes less-than-zero comparision of unsigned int
+- Fixes double fd close
+- Fixes fd leak
+- Fixes use ater free in shm disconnect
+- Fixes use after free during ipcs client disconnect
+- ipcc: Add abilty to verify dgram kernel buffer size meets max msg value
+- Upstream version cs: 75f7ed373758b3cb9087e89e4fae17379dd7b483 (v0.16.0)
+
+-------------------------------------------------------------------
+Mon Jul 22 07:38:56 UTC 2013 - ygao@suse.com
+
+- ringbuffer: Make max_size of ringbuffer accurate so shm ipc max msg size value is honored
+- ipcs: For shm ipc, always retry outstanding notifications when next event is sent
+- ipc_socket: In fbsd send() returns ENOBUFS when dgram queue is full, this should be treated similar to EAGAIN
+- kqueue: Properly enable kqueue filter in poll loop
+- ipcs: Attempt to resend outstanding event notifications during event send
+- ipcs: Disconnect shm ipc connection when poll socket returns error on msg receive
+- ipcs: Properly disconnect client connection on POLLNVAL or any other error causing connection removal from mainloop.
+- Upstream version cs: 39e9ef542dc89893c7c5af4fbd539338266e8031
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libqb.spec ++++++
--- /var/tmp/diff_new_pack.11ZHls/_old 2013-08-04 23:52:28.000000000 +0200
+++ /var/tmp/diff_new_pack.11ZHls/_new 2013-08-04 23:52:28.000000000 +0200
@@ -1,7 +1,7 @@
#
# spec file for package libqb
#
-# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -17,12 +17,12 @@
Name: libqb
-Version: 0.14.4
+Version: 0.16.0
Release: 0
Summary: An IPC library for high performance servers
License: LGPL-2.1+
Group: System/Libraries
-Url: http://www.libqb.org
+Url: https://github.com/ClusterLabs/libqb
Source0: %{name}.tar.bz2
BuildRoot: %{_tmppath}/%{name}-%{version}-build
@@ -31,8 +31,8 @@
BuildRequires: check-devel
BuildRequires: doxygen
BuildRequires: libtool
-BuildRequires: procps
BuildRequires: pkgconfig
+BuildRequires: procps
# Need git so build-aux/git-version-gen can extract the version number and
# commit hash during autogen run (not used currently)
#BuildRequires: git
@@ -44,7 +44,6 @@
%package -n libqb0
Summary: An IPC library for high performance servers
-License: LGPL-2.1+
Group: System/Libraries
Provides: %{name} = %{version}
@@ -55,7 +54,6 @@
%package devel
Summary: Development files for %{name}
-License: LGPL-2.1+
Group: Development/Libraries/C and C++
Requires: %{name} = %{version}-%{release}
Requires: pkgconfig
@@ -69,7 +67,7 @@
%setup -q -n %{name}
%build
-#./autogen.sh
+./autogen.sh
%configure --disable-static
make %{?_smp_mflags}
++++++ _service ++++++
--- /var/tmp/diff_new_pack.11ZHls/_old 2013-08-04 23:52:28.000000000 +0200
+++ /var/tmp/diff_new_pack.11ZHls/_new 2013-08-04 23:52:28.000000000 +0200
@@ -7,8 +7,8 @@
To update to a new release, change "revision" to the desired
git commit hash and bump "version" if necessary
-->
- <param name="version">0.14.4</param>
- <param name="revision">7c6e109046ec772a97a7fe2cdf61f84fc2155b7e</param>
+ <param name="version">0.16.0</param>
+ <param name="revision">75f7ed373758b3cb9087e89e4fae17379dd7b483</param>
</service>
<service name="recompress" mode="disabled">
++++++ libqb.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/.tarball-version new/libqb/.tarball-version
--- old/libqb/.tarball-version 2013-07-02 11:28:45.000000000 +0200
+++ new/libqb/.tarball-version 2013-07-26 03:10:21.000000000 +0200
@@ -1 +1 @@
-0.14.4.53-7c6e
+0.16.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/.version new/libqb/.version
--- old/libqb/.version 2012-06-07 11:27:48.000000000 +0200
+++ new/libqb/.version 2013-07-26 03:10:02.000000000 +0200
@@ -1 +1 @@
-0.13.0.51-e70e
+0.16.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/ChangeLog new/libqb/ChangeLog
--- old/libqb/ChangeLog 2013-07-02 11:28:45.000000000 +0200
+++ new/libqb/ChangeLog 2013-07-26 03:10:21.000000000 +0200
@@ -1,7 +1,146 @@
-2013-06-29 David Vossel
+2013-07-26 David Vossel
- Merge pull request #73 from davidvossel/ref_count_cleanup
- cleanup connection and service ref counting without changing behavior
+ Bump version to 0.16.0 ... do not use version 0.15.0
+ The use of version-info conflicted with the naming
+ convention used to represent libqb version numbers. Because
+ of this the shared library file used for release 0.15.0
+ did not properly match the release version. From now on
+ the version number will be manually set to guarantee consistency
+ between .so file and release version.
+
+ Update release gpg sign key
+
+2013-07-25 David Vossel
+
+ Bump the version to 0.15.0
+
+2013-07-24 David Vossel
+
+ Merge pull request #83 from davidvossel/master
+ socket ipc fixes
+
+ Low: ipc_socket: Output send event failure as debug instead of error
+
+ Low: ipcserver.c: Fix example server's glib mainloop implementation
+
+ High: ipc_socket.c: Detect EOF connection on connection STREAM socket
+
+2013-07-23 David Vossel
+
+ Merge pull request #81 from davidvossel/dgram_max_msg
+ Added ability to estimate kernel's actual max dgram buffer size in a portable way.
+
+ Low: tests: Add dgram max size detection test
+
+ Low: ipc_socket.c: Handle the unlikely event of an EAGAIN or EINTR during dgram max size detection
+
+ Merge pull request #82 from davidvossel/master
+ coverity fixes
+
+ Fixes detect disconnect on send for tcp example
+
+ Fixes sem leak
+
+ Fixes less-than-zero comparision of unsigned int
+
+ fixes double close
+
+ Fixes double close
+
+ Fixes double fd close
+
+ Fixes fd leak
+
+ Prevent use after free in benchmark util
+
+ Fixes use ater free in shm disconnect
+
+ Fixes use after free during ipcs client disconnect
+
+ Remove dead code
+
+2013-07-20 David Vossel
+
+ Low: check_ipc.c: Verify dgram max size during tests
+
+ High: ipcc: Add abilty to verify dgram kernel buffer size meets max msg value
+
+ Fixes travis build error
+
+2013-07-19 David Vossel
+
+ Merge pull request #80 from davidvossel/master
+ Fixes travis build error
+
+ Low: check_ipc.c: fix debug message to only display once.
+
+ High: ringbuffer: Make max_size of ringbuffer accurate so shm ipc max msg size value is honored
+
+ Low: ipcs: For shm ipc, always retry outstanding notifications when next event is sent
+
+ Low: tests: Added test to verify sending ipc msg equal to max size succeeds
+
+ Merge pull request #79 from davidvossel/master
+ fix shared memory ipc so max msg size is honored correctly
+
+2013-07-13 David Vossel
+
+ Merge pull request #78 from davidvossel/master
+ fixes travis compile time issue
+
+ Fix: ipcs: Fixes compile time issue reported by travis
+
+ Merge pull request #77 from davidvossel/stress_tests_fixes
+ Adds new ipc event stress test and fixes issues the new test exposed
+
+ Low: loop_pool_kqueue: remove potentially noisy dbug statement
+
+ Low: tests: rework bulk event msg ipc test
+ Some environments have very small dgram msg queues. In
+ these environments we have to be able to read off the event
+ queue before being able to send the rest of events for the
+ bulk event test.
+
+ Account for fbsd ENOBUFS during stress test
+
+ Low: tests: Adds ipc event stress test to testsuite
+
+ Low: ipc_socket: In fbsd send() returns ENOBUFS when dgram queue is full, this should be treated similar to EAGAIN
+
+ High: kqueue: Properly enable kqueue filter in poll loop
+
+ Low: ipcs: Attempt to resend outstanding event notifications during event send
+
+2013-07-03 David Vossel
+
+ Merge pull request #75 from davidvossel/ref_count_cleanup
+ Low: qbipcs: update ipcs connection iterator documentation
+
+ Low: qbipcs.h: update ipcs connection iterator documentation
+
+ Merge pull request #74 from davidvossel/ref_count_cleanup
+ Properly disconnect clients when ipc dispatch fails.
+
+2013-07-02 David Vossel
+
+ Fix: ipcs: Disconnect shm ipc connection when poll socket returns error on msg receive
+
+ Fix: ipcs: Properly disconnect client connection on POLLNVAL or any other error causing connection removal from mainloop.
+ qb_ipcs_dispatch_connection_request is a callback function registered with
+ mainloop, or whatever other looping thread implementation is in use. When
+ this callback is registered, a reference of the connection object is given
+ to the mainloop thread. If this callback ever returns something none zero
+ the callback (and corresponding fd) is unregistered from the loop automatically,
+ so we must decrement the reference in this instance.
+
+ Since unregistering this callback from mainloop guarantees a disconnect
+ simply because requests on the fd are no longer processed, it is best
+ that we completely disconnect the connection (which will handle the unref)
+ when this callback returns an error... Otherwise since the fd is unregistered
+ from the mainloop thread, it may not be possible to detect a disconnect
+ in the future.
+
+2013-06-29 David Vossel
Simplify internal ipcs ref counting, add comments and document api behavior
@@ -9,6 +148,9 @@
Low remove ref-count error in example ipcserver.
+ Merge pull request #73 from davidvossel/ref_count_cleanup
+ cleanup connection and service ref counting without changing behavior
+
Merge pull request #72 from davidvossel/master
Fixes ref count leak in example ipcserver.c
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/build-aux/release.mk new/libqb/build-aux/release.mk
--- old/libqb/build-aux/release.mk 2012-06-07 10:58:53.000000000 +0200
+++ new/libqb/build-aux/release.mk 2013-07-26 03:08:27.000000000 +0200
@@ -1,7 +1,7 @@
# to build official release tarballs, handle tagging and publish.
# signing key
-gpgsignkey=956EEFB5
+gpgsignkey=C38157D2
project=libqb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/configure new/libqb/configure
--- old/libqb/configure 2013-07-02 11:28:31.000000000 +0200
+++ new/libqb/configure 2013-07-26 03:09:25.000000000 +0200
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for libqb 0.14.4.53-7c6e.
+# Generated by GNU Autoconf 2.69 for libqb 0.16.0.
#
# Report bugs to .
#
@@ -590,8 +590,8 @@
# Identity of this package.
PACKAGE_NAME='libqb'
PACKAGE_TARNAME='libqb'
-PACKAGE_VERSION='0.14.4.53-7c6e'
-PACKAGE_STRING='libqb 0.14.4.53-7c6e'
+PACKAGE_VERSION='0.16.0'
+PACKAGE_STRING='libqb 0.16.0'
PACKAGE_BUGREPORT='quarterback-devel@fedorahosted.org'
PACKAGE_URL=''
@@ -1374,7 +1374,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures libqb 0.14.4.53-7c6e to adapt to many kinds of systems.
+\`configure' configures libqb 0.16.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1444,7 +1444,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of libqb 0.14.4.53-7c6e:";;
+ short | recursive ) echo "Configuration of libqb 0.16.0:";;
esac
cat <<\_ACEOF
@@ -1568,7 +1568,7 @@
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-libqb configure 0.14.4.53-7c6e
+libqb configure 0.16.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2345,7 +2345,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by libqb $as_me 0.14.4.53-7c6e, which was
+It was created by libqb $as_me 0.16.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -4487,7 +4487,7 @@
# Define the identity of the package.
PACKAGE='libqb'
- VERSION='0.14.4.53-7c6e'
+ VERSION='0.16.0'
cat >>confdefs.h <<_ACEOF
@@ -19387,7 +19387,7 @@
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by libqb $as_me 0.14.4.53-7c6e, which was
+This file was extended by libqb $as_me 0.16.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -19453,7 +19453,7 @@
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-libqb config.status 0.14.4.53-7c6e
+libqb config.status 0.16.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/docs/Makefile.in new/libqb/docs/Makefile.in
--- old/libqb/docs/Makefile.in 2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/docs/Makefile.in 2013-07-25 10:58:37.000000000 +0200
@@ -290,9 +290,9 @@
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign docs/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign docs/Makefile
+ $(AUTOMAKE) --gnu docs/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/docs/html.dox new/libqb/docs/html.dox
--- old/libqb/docs/html.dox 2013-07-02 11:28:43.000000000 +0200
+++ new/libqb/docs/html.dox 2013-07-26 03:09:56.000000000 +0200
@@ -1,6 +1,6 @@
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = libqb
-PROJECT_NUMBER = 0.14.4.53-7c6e
+PROJECT_NUMBER = 0.16.0
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/docs/man.dox new/libqb/docs/man.dox
--- old/libqb/docs/man.dox 2013-07-02 11:28:43.000000000 +0200
+++ new/libqb/docs/man.dox 2013-07-26 03:09:56.000000000 +0200
@@ -1,6 +1,6 @@
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = libqb
-PROJECT_NUMBER = 0.14.4.53-7c6e
+PROJECT_NUMBER = 0.16.0
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/examples/Makefile.in new/libqb/examples/Makefile.in
--- old/libqb/examples/Makefile.in 2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/examples/Makefile.in 2013-07-25 10:58:37.000000000 +0200
@@ -325,9 +325,9 @@
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign examples/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu examples/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign examples/Makefile
+ $(AUTOMAKE) --gnu examples/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/examples/ipcclient.c new/libqb/examples/ipcclient.c
--- old/libqb/examples/ipcclient.c 2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/examples/ipcclient.c 2013-07-25 08:36:33.000000000 +0200
@@ -53,7 +53,7 @@
_benchmark(qb_ipcc_connection_t *conn, int write_size)
{
struct iovec iov[2];
- unsigned int res;
+ ssize_t res;
struct qb_ipc_request_header hdr;
int write_count = 0;
float secs;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/examples/ipcserver.c new/libqb/examples/ipcserver.c
--- old/libqb/examples/ipcserver.c 2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/examples/ipcserver.c 2013-07-25 08:36:33.000000000 +0200
@@ -181,8 +181,9 @@
#ifdef HAVE_GLIB
struct gio_to_qb_poll {
gboolean is_used;
- GIOChannel *channel;
int32_t events;
+ int32_t source;
+ int32_t fd;
void *data;
qb_ipcs_dispatch_fn_t fn;
enum qb_loop_priority p;
@@ -197,6 +198,16 @@
return (adaptor->fn(fd, condition, adaptor->data) == 0);
}
+static void
+gio_poll_destroy(gpointer data)
+{
+ struct gio_to_qb_poll *adaptor = (struct gio_to_qb_poll *)data;
+
+ qb_log(LOG_DEBUG, "fd %d adaptor destroyed\n", adaptor->fd);
+ adaptor->is_used = QB_FALSE;
+ adaptor->fd = 0;
+}
+
static int32_t
my_g_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
void *data, qb_ipcs_dispatch_fn_t fn)
@@ -218,14 +229,19 @@
return -ENOMEM;
}
- adaptor->channel = channel;
adaptor->fn = fn;
adaptor->events = evts;
adaptor->data = data;
adaptor->p = p;
adaptor->is_used = TRUE;
+ adaptor->fd = fd;
+
+ adaptor->source = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, evts, gio_read_socket, adaptor, gio_poll_destroy);
+
+ /* we are handing the channel off to be managed by mainloop now.
+ * remove our reference. */
+ g_io_channel_unref(channel);
- g_io_add_watch(channel, evts, gio_read_socket, adaptor);
return 0;
}
@@ -241,7 +257,7 @@
{
struct gio_to_qb_poll *adaptor;
if (qb_array_index(gio_map, fd, (void **)&adaptor) == 0) {
- g_io_channel_unref(adaptor->channel);
+ g_source_remove(adaptor->source);
adaptor->is_used = FALSE;
}
return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/examples/tcpserver.c new/libqb/examples/tcpserver.c
--- old/libqb/examples/tcpserver.c 2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/examples/tcpserver.c 2013-07-25 08:36:33.000000000 +0200
@@ -66,7 +66,10 @@
} else {
printf("Recieved: %s\n", recv_data);
snprintf(send_data, 1024, "ACK %d bytes", bytes_recieved);
- send(fd, send_data, strlen(send_data), 0);
+ if (send(fd, send_data, strlen(send_data), 0) < 0) {
+ close(fd);
+ return QB_FALSE;
+ }
}
return QB_TRUE;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/include/Makefile.in new/libqb/include/Makefile.in
--- old/libqb/include/Makefile.in 2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/include/Makefile.in 2013-07-25 10:58:37.000000000 +0200
@@ -289,9 +289,9 @@
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign include/Makefile
+ $(AUTOMAKE) --gnu include/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/include/qb/Makefile.in new/libqb/include/qb/Makefile.in
--- old/libqb/include/qb/Makefile.in 2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/include/qb/Makefile.in 2013-07-25 10:58:37.000000000 +0200
@@ -282,9 +282,9 @@
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/qb/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu include/qb/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign include/qb/Makefile
+ $(AUTOMAKE) --gnu include/qb/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/include/qb/qbipcc.h new/libqb/include/qb/qbipcc.h
--- old/libqb/include/qb/qbipcc.h 2012-06-07 10:58:53.000000000 +0200
+++ new/libqb/include/qb/qbipcc.h 2013-07-25 08:36:33.000000000 +0200
@@ -70,11 +70,34 @@
* @param name name of the service.
* @param max_msg_size biggest msg size.
* @return NULL (error: see errno) or a connection object.
+ *
+ * @note It is recommended to do a one time check on the
+ * max_msg_size value using qb_ipcc_verify_dgram_max_msg_size
+ * _BEFORE_ calling the connect function when IPC_SOCKET is in use.
+ * Some distributions while allow large message buffers to be
+ * set on the socket, but not actually honor them because of
+ * kernel state values. The qb_ipcc_verify_dgram_max_msg_size
+ * function both sets the socket buffer size and verifies it by
+ * doing a send/recv.
*/
qb_ipcc_connection_t*
qb_ipcc_connect(const char *name, size_t max_msg_size);
/**
+ * Test kernel dgram socket buffers to verify the largest size up
+ * to the max_msg_size value a single msg can be. Rounds down to the
+ * nearest 1k.
+ *
+ * @param max_msg_size biggest msg size.
+ * @return -1 if max size can not be detected, positive value
+ * representing the largest single msg up to max_msg_size
+ * that can successfully be sent over a unix dgram socket.
+ */
+int32_t
+qb_ipcc_verify_dgram_max_msg_size(size_t max_msg_size);
+
+
+/**
* Disconnect an IPC connection.
*
* @param c connection instance
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/include/qb/qbipcs.h new/libqb/include/qb/qbipcs.h
--- old/libqb/include/qb/qbipcs.h 2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/include/qb/qbipcs.h 2013-07-22 08:51:47.000000000 +0200
@@ -388,7 +388,7 @@
/**
* Get the first connection.
*
- * @note call qb_ipcs_connection_ref_dec() after using the connection.
+ * @note call qb_ipcs_connection_unref() after using the connection.
*
* @param pt service instance
* @return first connection
@@ -398,7 +398,7 @@
/**
* Get the next connection.
*
- * @note call qb_ipcs_connection_ref_dec() after using the connection.
+ * @note call qb_ipcs_connection_unref() after using the connection.
*
* @param pt service instance
* @param current current connection
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/Makefile.am new/libqb/lib/Makefile.am
--- old/libqb/lib/Makefile.am 2013-06-08 07:44:23.000000000 +0200
+++ new/libqb/lib/Makefile.am 2013-07-26 03:08:27.000000000 +0200
@@ -29,38 +29,7 @@
lib_LTLIBRARIES = libqb.la
-# From: http://sourceware.org/autobook/autobook/autobook_91.html
-# (for my own sanity).
-#
-# 1) If you have changed any of the sources for this library, the revision
-# number must be incremented. This is a new revision of the current
-# interface.
-#
-# 2) If the interface has changed, then current must be incremented, and
-# revision reset to `0'. This is the first revision of a new interface.
-#
-# 3) If the new interface is a superset of the previous interface
-# (that is, if the previous interface has not been broken by the changes
-# in this new release), then age must be incremented. This release is
-# backwards compatible with the previous release.
-#
-# 4) If the new interface has removed elements with respect to the previous
-# interface, then you have broken backward compatibility and age must be
-# reset to `0'. This release has a new, but backwards incompatible
-# interface. For example, if the next release of the library included
-# some new commands for an existing socket protocol, you would use
-# -version-info 1:0:1. This is the first revision of a new interface.
-# This release is backwards compatible with the previous release.
-# Later, you implement a faster way of handling part of the algorithm
-# at the core of the library, and release it with -version-info 1:1:1.
-# This is a new revision of the current interface.
-# Unfortunately the speed of your new implementation can only be fully
-# exploited by changing the API to access the structures at a lower level,
-# which breaks compatibility with the previous interface, so you release
-# it as -version-info 2:0:0. This release has a new, but backwards
-# incompatible interface.
-#
-libqb_la_LDFLAGS = -version-info 14:4:14
+libqb_la_LDFLAGS = -version-number 0:16:0
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
array.c loop.c loop_poll.c loop_job.c \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/Makefile.in new/libqb/lib/Makefile.in
--- old/libqb/lib/Makefile.in 2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/lib/Makefile.in 2013-07-26 03:09:26.000000000 +0200
@@ -333,39 +333,7 @@
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
lib_LTLIBRARIES = libqb.la
-
-# From: http://sourceware.org/autobook/autobook/autobook_91.html
-# (for my own sanity).
-#
-# 1) If you have changed any of the sources for this library, the revision
-# number must be incremented. This is a new revision of the current
-# interface.
-#
-# 2) If the interface has changed, then current must be incremented, and
-# revision reset to `0'. This is the first revision of a new interface.
-#
-# 3) If the new interface is a superset of the previous interface
-# (that is, if the previous interface has not been broken by the changes
-# in this new release), then age must be incremented. This release is
-# backwards compatible with the previous release.
-#
-# 4) If the new interface has removed elements with respect to the previous
-# interface, then you have broken backward compatibility and age must be
-# reset to `0'. This release has a new, but backwards incompatible
-# interface. For example, if the next release of the library included
-# some new commands for an existing socket protocol, you would use
-# -version-info 1:0:1. This is the first revision of a new interface.
-# This release is backwards compatible with the previous release.
-# Later, you implement a faster way of handling part of the algorithm
-# at the core of the library, and release it with -version-info 1:1:1.
-# This is a new revision of the current interface.
-# Unfortunately the speed of your new implementation can only be fully
-# exploited by changing the API to access the structures at a lower level,
-# which breaks compatibility with the previous interface, so you release
-# it as -version-info 2:0:0. This release has a new, but backwards
-# incompatible interface.
-#
-libqb_la_LDFLAGS = -version-info 14:4:14
+libqb_la_LDFLAGS = -version-number 0:16:0
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
array.c loop.c loop_poll.c loop_job.c \
loop_timerlist.c ipcc.c ipcs.c ipc_shm.c \
@@ -401,9 +369,9 @@
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu lib/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign lib/Makefile
+ $(AUTOMAKE) --gnu lib/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/ipc_int.h new/libqb/lib/ipc_int.h
--- old/libqb/lib/ipc_int.h 2013-06-08 07:44:23.000000000 +0200
+++ new/libqb/lib/ipc_int.h 2013-07-25 08:36:33.000000000 +0200
@@ -196,7 +196,6 @@
int32_t qb_ipcc_us_sock_connect(const char *socket_name, int32_t * sock_pt);
int32_t qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data);
-int32_t qb_ipcs_dispatch_service_request(int32_t fd, int32_t revents, void *data);
struct qb_ipcs_connection* qb_ipcs_connection_alloc(struct qb_ipcs_service *s);
int32_t qb_ipcs_process_request(struct qb_ipcs_service *s,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/ipc_setup.c new/libqb/lib/ipc_setup.c
--- old/libqb/lib/ipc_setup.c 2013-03-27 09:16:31.000000000 +0100
+++ new/libqb/lib/ipc_setup.c 2013-07-22 08:51:47.000000000 +0200
@@ -122,7 +122,9 @@
int32_t
qb_ipc_us_sock_error_is_disconnected(int err)
{
- if (err == -EAGAIN ||
+ if (err >= 0) {
+ return QB_FALSE;
+ } else if (err == -EAGAIN ||
err == -ETIMEDOUT ||
err == -EINTR ||
#ifdef EWOULDBLOCK
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/ipc_shm.c new/libqb/lib/ipc_shm.c
--- old/libqb/lib/ipc_shm.c 2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/lib/ipc_shm.c 2013-07-25 08:36:33.000000000 +0200
@@ -229,8 +229,8 @@
if (c->setup.u.us.sock > 0) {
qb_ipcc_us_sock_close(c->setup.u.us.sock);
(void)c->service->poll_fns.dispatch_del(c->setup.u.us.sock);
- qb_ipcs_connection_unref(c);
c->setup.u.us.sock = -1;
+ qb_ipcs_connection_unref(c);
}
}
if (c->state == QB_IPCS_CONNECTION_SHUTTING_DOWN ||
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/ipc_socket.c new/libqb/lib/ipc_socket.c
--- old/libqb/lib/ipc_socket.c 2013-03-27 09:16:31.000000000 +0100
+++ new/libqb/lib/ipc_socket.c 2013-07-25 08:36:33.000000000 +0200
@@ -104,10 +104,16 @@
rc = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &optval, &optlen);
- qb_util_log(LOG_DEBUG, "%d: getsockopt(%d, needed:%d) actual:%d",
- rc, sockfd, max_msg_size, optval);
+ qb_util_log(LOG_TRACE, "%d: getsockopt(%d, needed:%d) actual:%d",
+ rc, sockfd, max_msg_size, optval);
- if (rc == 0 && optval < max_msg_size) {
+ /* The optvat <= max_msg_size check is weird...
+ * during testing it was discovered in some instances if the
+ * default optval is exactly equal to our max_msg_size, we couldn't
+ * actually send a message that large unless we explicilty set
+ * it using setsockopt... there is no good explaination for this. Most
+ * likely this is hitting some sort of "off by one" error in the kernel. */
+ if (rc == 0 && optval <= max_msg_size) {
optval = max_msg_size;
optlen = sizeof(optval);
rc = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, &optval, optlen);
@@ -115,6 +121,86 @@
return rc;
}
+static int32_t
+dgram_verify_msg_size(size_t max_msg_size)
+{
+ int32_t rc = -1;
+ int32_t sockets[2];
+ int32_t tries = 0;
+ int32_t write_passed = 0;
+ int32_t read_passed = 0;
+ char buf[max_msg_size];
+
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) < 0) {
+ goto cleanup_socks;
+ }
+
+ if (set_sock_size(sockets[0], max_msg_size) != 0) {
+ goto cleanup_socks;
+ }
+ if (set_sock_size(sockets[1], max_msg_size) != 0) {
+ goto cleanup_socks;
+ }
+
+ for (tries = 0; tries < 3; tries++) {
+
+ if (write_passed == 0) {
+ rc = write(sockets[1], buf, max_msg_size);
+
+ if (rc < 0 && (errno == EAGAIN || errno == EINTR)) {
+ continue;
+ } else if (rc == max_msg_size) {
+ write_passed = 1;
+ } else {
+ break;
+ }
+ }
+
+ if (read_passed == 0) {
+ rc = read(sockets[0], buf, max_msg_size);
+
+ if (rc < 0 && (errno == EAGAIN || errno == EINTR)) {
+ continue;
+ } else if (rc == max_msg_size) {
+ read_passed = 1;
+ } else {
+ break;
+ }
+ }
+
+ if (read_passed && write_passed) {
+ rc = 0;
+ break;
+ }
+ }
+
+
+cleanup_socks:
+ close(sockets[0]);
+ close(sockets[1]);
+ return rc;
+}
+
+int32_t
+qb_ipcc_verify_dgram_max_msg_size(size_t max_msg_size)
+{
+ int32_t i;
+ int32_t last = -1;
+
+ if (dgram_verify_msg_size(max_msg_size) == 0) {
+ return max_msg_size;
+ }
+
+ for (i = 1024; i < max_msg_size; i+=1024) {
+ if (dgram_verify_msg_size(i) != 0) {
+ break;
+ }
+ last = i;
+ }
+
+ return last;
+}
+
/*
* bind to "base_name-local_name"
* connect to "base_name-remote_name"
@@ -219,8 +305,8 @@
rc = send(one_way->u.us.sock, msg_ptr, msg_len, MSG_NOSIGNAL);
if (rc == -1) {
rc = -errno;
- if (errno != EAGAIN) {
- qb_util_perror(LOG_ERR, "socket_send:send");
+ if (errno != EAGAIN && errno != ENOBUFS) {
+ qb_util_perror(LOG_DEBUG, "socket_send:send");
}
}
qb_sigpipe_ctl(QB_SIGPIPE_DEFAULT);
@@ -254,8 +340,8 @@
if (rc == -1) {
rc = -errno;
- if (errno != EAGAIN) {
- qb_util_perror(LOG_ERR, "socket_sendv:writev %d",
+ if (errno != EAGAIN && errno != ENOBUFS) {
+ qb_util_perror(LOG_DEBUG, "socket_sendv:writev %d",
one_way->u.us.sock);
}
}
@@ -401,6 +487,7 @@
c->event.u.us.shared_data = shm_ptr + (2 * sizeof(struct ipc_us_control));
close(fd_hdr);
+ fd_hdr = -1;
res = qb_ipc_dgram_sock_connect(r->response, "response", "request",
r->max_msg_size, &c->request.u.us.sock);
@@ -418,7 +505,9 @@
return 0;
cleanup_hdr:
- close(fd_hdr);
+ if (fd_hdr >= 0) {
+ close(fd_hdr);
+ }
close(c->event.u.us.sock);
close(c->request.u.us.sock);
unlink(r->request);
@@ -439,6 +528,7 @@
fd, revents, c->description);
if (revents & POLLNVAL) {
qb_util_log(LOG_DEBUG, "NVAL conn (%s)", c->description);
+ qb_ipcs_disconnect(c);
return -EINVAL;
}
if (revents & POLLHUP) {
@@ -446,6 +536,28 @@
qb_ipcs_disconnect(c);
return -ESHUTDOWN;
}
+
+ /* If we actually get POLLIN for some reason here, it most
+ * certainly means EOF. Do a recv on the fd to detect eof and
+ * then disconnect */
+ if (revents & POLLIN) {
+ char buf[10];
+ int res;
+
+ res = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
+ if (res < 0 && errno != EAGAIN && errno != EWOULDBLOCK) {
+ res = -errno;
+ } else if (res == 0) {
+ qb_util_log(LOG_DEBUG, "EOF conn (%s)", c->description);
+ res = -ESHUTDOWN;
+ }
+
+ if (res < 0) {
+ qb_ipcs_disconnect(c);
+ return res;
+ }
+ }
+
return 0;
}
@@ -582,6 +694,7 @@
ctl->flow_control = 0;
close(fd_hdr);
+ fd_hdr = -1;
/* request channel */
res = qb_ipc_dgram_sock_setup(r->response, "request",
@@ -617,7 +730,9 @@
free(c->response.u.us.sock_name);
free(c->event.u.us.sock_name);
- close(fd_hdr);
+ if (fd_hdr >= 0) {
+ close(fd_hdr);
+ }
unlink(r->request);
munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE);
return res;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/ipcc.c new/libqb/lib/ipcc.c
--- old/libqb/lib/ipcc.c 2013-03-27 09:16:31.000000000 +0100
+++ new/libqb/lib/ipcc.c 2013-07-22 08:51:47.000000000 +0200
@@ -110,7 +110,7 @@
poll_ms = 0;
}
res2 = qb_ipc_us_ready(one_way, &c->setup, poll_ms, events);
- if (res2 < 0 && qb_ipc_us_sock_error_is_disconnected(res2)) {
+ if (qb_ipc_us_sock_error_is_disconnected(res2)) {
errno = -res2;
qb_util_perror(LOG_DEBUG,
"%s %d %s",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/ipcs.c new/libqb/lib/ipcs.c
--- old/libqb/lib/ipcs.c 2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/lib/ipcs.c 2013-07-25 08:36:33.000000000 +0200
@@ -342,6 +342,10 @@
{
ssize_t res = 0;
+ if (!c->service->needs_sock_for_poll) {
+ return res;
+ }
+
if (c->outstanding_notifiers > 0) {
res = qb_ipc_us_send(&c->setup, c->receive_buf,
c->outstanding_notifiers);
@@ -349,6 +353,7 @@
if (res > 0) {
c->outstanding_notifiers -= res;
}
+
assert(c->outstanding_notifiers >= 0);
if (c->outstanding_notifiers == 0) {
c->poll_events = POLLIN | POLLPRI | POLLNVAL;
@@ -369,6 +374,7 @@
assert(c->outstanding_notifiers >= 0);
if (c->outstanding_notifiers > 0) {
c->outstanding_notifiers++;
+ res = resend_event_notifications(c);
} else {
res = qb_ipc_us_send(&c->setup, &c->outstanding_notifiers, 1);
if (res == -EAGAIN) {
@@ -400,7 +406,7 @@
if (res == size) {
c->stats.events++;
resn = new_event_notification(c);
- if (resn < 0 && resn != -EAGAIN) {
+ if (resn < 0 && resn != -EAGAIN && resn != -ENOBUFS) {
errno = -resn;
qb_util_perror(LOG_WARNING,
"new_event_notification (%s)",
@@ -409,6 +415,10 @@
}
} else if (res == -EAGAIN || res == -ETIMEDOUT) {
struct qb_ipc_one_way *ow = _event_sock_one_way_get(c);
+
+ if (c->outstanding_notifiers > 0) {
+ resn = resend_event_notifications(c);
+ }
if (ow) {
resn = qb_ipc_us_ready(ow, &c->setup, 0, POLLOUT);
if (resn < 0) {
@@ -447,6 +457,10 @@
}
} else if (res == -EAGAIN || res == -ETIMEDOUT) {
struct qb_ipc_one_way *ow = _event_sock_one_way_get(c);
+
+ if (c->outstanding_notifiers > 0) {
+ resn = resend_event_notifications(c);
+ }
if (ow) {
resn = qb_ipc_us_ready(ow, &c->setup, 0, POLLOUT);
if (resn < 0) {
@@ -677,9 +691,8 @@
} else if (size == 0 || hdr->id == QB_IPC_MSG_DISCONNECT) {
qb_util_log(LOG_DEBUG, "client requesting a disconnect (%s)",
c->description);
- qb_ipcs_disconnect(c);
- c = NULL;
res = -ESHUTDOWN;
+ goto cleanup;
} else {
c->stats.requests++;
res = c->service->serv_fns.msg_process(c, hdr, hdr->size);
@@ -703,17 +716,6 @@
#define IPC_REQUEST_TIMEOUT 10
#define MAX_RECV_MSGS 50
-int32_t
-qb_ipcs_dispatch_service_request(int32_t fd, int32_t revents, void *data)
-{
- int32_t res = _process_request_((struct qb_ipcs_connection *)data,
- IPC_REQUEST_TIMEOUT);
- if (res > 0) {
- return 0;
- }
- return res;
-}
-
static ssize_t
_request_q_len_get(struct qb_ipcs_connection *c)
{
@@ -741,22 +743,24 @@
{
struct qb_ipcs_connection *c = (struct qb_ipcs_connection *)data;
char bytes[MAX_RECV_MSGS];
- int32_t res;
+ int32_t res = 0;
int32_t res2;
int32_t recvd = 0;
ssize_t avail;
if (revents & POLLNVAL) {
qb_util_log(LOG_DEBUG, "NVAL conn (%s)", c->description);
- return -EINVAL;
+ res = -EINVAL;
+ goto dispatch_cleanup;
}
if (revents & POLLHUP) {
qb_util_log(LOG_DEBUG, "HUP conn (%s)", c->description);
- qb_ipcs_disconnect(c);
- return -ESHUTDOWN;
+ res = -ESHUTDOWN;
+ goto dispatch_cleanup;
}
if (revents & POLLOUT) {
+ /* try resend events now that fd can write */
res = resend_event_notifications(c);
if (res < 0 && res != -EAGAIN) {
errno = -res;
@@ -764,12 +768,15 @@
"resend_event_notifications (%s)",
c->description);
}
+ /* nothing to read */
if ((revents & POLLIN) == 0) {
- return 0;
+ res = 0;
+ goto dispatch_cleanup;
}
}
if (c->fc_enabled) {
- return 0;
+ res = 0;
+ goto dispatch_cleanup;
}
avail = _request_q_len_get(c);
@@ -779,18 +786,24 @@
errno = -res2;
qb_util_perror(LOG_WARNING, "conn (%s) disconnected",
c->description);
- qb_ipcs_disconnect(c);
- return -ESHUTDOWN;
+ res = -ESHUTDOWN;
+ goto dispatch_cleanup;
} else {
qb_util_log(LOG_WARNING,
"conn (%s) Nothing in q but got POLLIN on fd:%d (res2:%d)",
c->description, fd, res2);
- return 0;
+ res = 0;
+ goto dispatch_cleanup;
}
}
do {
res = _process_request_(c, IPC_REQUEST_TIMEOUT);
+
+ if (res == -ESHUTDOWN) {
+ goto dispatch_cleanup;
+ }
+
if (res > 0 || res == -ENOBUFS || res == -EINVAL) {
recvd++;
}
@@ -801,11 +814,12 @@
if (c->service->needs_sock_for_poll && recvd > 0) {
res2 = qb_ipc_us_recv(&c->setup, bytes, recvd, -1);
- if (res2 < 0) {
+ if (qb_ipc_us_sock_error_is_disconnected(res2)) {
errno = -res2;
- qb_util_perror(LOG_ERR,
- "error receiving from setup sock (%s)",
- c->description);
+ qb_util_perror(LOG_ERR, "error receiving from setup sock (%s)", c->description);
+
+ res = -ESHUTDOWN;
+ goto dispatch_cleanup;
}
}
@@ -822,9 +836,12 @@
qb_util_perror(LOG_ERR, "request returned error (%s)",
c->description);
}
- qb_ipcs_connection_unref(c);
}
+dispatch_cleanup:
+ if (res != 0) {
+ qb_ipcs_disconnect(c);
+ }
return res;
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/log_thread.c new/libqb/lib/log_thread.c
--- old/libqb/lib/log_thread.c 2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/lib/log_thread.c 2013-07-25 08:36:33.000000000 +0200
@@ -249,7 +249,7 @@
for (;;) {
res = sem_getvalue(&logt_print_finished, &value);
if (res != 0 || value == 0) {
- return;
+ break;
}
sem_wait(&logt_print_finished);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/loop_poll_kqueue.c new/libqb/lib/loop_poll_kqueue.c
--- old/libqb/lib/loop_poll_kqueue.c 2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/lib/loop_poll_kqueue.c 2013-07-22 08:51:47.000000000 +0200
@@ -55,7 +55,7 @@
struct kevent ke;
short filters = _poll_to_filter_(events);
- EV_SET(&ke, fd, filters, EV_ADD, 0, 0, (intptr_t)pe);
+ EV_SET(&ke, fd, filters, EV_ADD | EV_ENABLE, 0, 0, (intptr_t)pe);
res = kevent(s->epollfd, &ke, 1, NULL, 0, NULL);
if (res == -1) {
@@ -75,7 +75,7 @@
short old_filters = _poll_to_filter_(pe->ufd.events);
EV_SET(&ke[0], fd, old_filters, EV_DELETE, 0, 0, (intptr_t)pe);
- EV_SET(&ke[1], fd, new_filters, EV_ADD, 0, 0, (intptr_t)pe);
+ EV_SET(&ke[1], fd, new_filters, EV_ADD | EV_ENABLE, 0, 0, (intptr_t)pe);
res = kevent(s->epollfd, ke, 2, NULL, 0, NULL);
if (res == -1) {
@@ -140,11 +140,13 @@
for (i = 0; i < event_count; i++) {
revents = 0;
pe = (struct qb_poll_entry *)events[i].udata;
+#if 0
if (events[i].flags) {
qb_util_log(LOG_TRACE,
"got flags %d on fd %d.", events[i].flags,
pe->ufd.fd);
}
+#endif
if (events[i].flags & EV_ERROR) {
qb_util_log(LOG_WARNING,
"got EV_ERROR on fd %d.", pe->ufd.fd);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/ringbuffer.c new/libqb/lib/ringbuffer.c
--- old/libqb/lib/ringbuffer.c 2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/lib/ringbuffer.c 2013-07-25 08:36:33.000000000 +0200
@@ -141,7 +141,14 @@
#ifdef QB_FORCE_SHM_ALIGN
page_size = QB_MAX(page_size, 16 * 1024);
#endif /* QB_FORCE_SHM_ALIGN */
+ /* The user of this api expects the 'size' parameter passed into this function
+ * to be reflective of the max size single write we can do to the
+ * ringbuffer. This means we have to add both the 'margin' space used
+ * to calculate if there is enough space for a new chunk as well as the '+1' that
+ * prevents overlap of the read/write pointers */
+ size += QB_RB_CHUNK_MARGIN + 1;
real_size = QB_ROUNDUP(size, page_size);
+
shared_size =
sizeof(struct qb_ringbuffer_shared_s) + shared_user_data_size;
@@ -228,6 +235,7 @@
"shm size:%zd; real_size:%zd; rb->word_size:%d", size,
real_size, rb->shared_hdr->word_size);
+ /* this function closes fd_data */
error = qb_sys_circular_mmap(fd_data, &shm_addr, real_size);
rb->shared_data = shm_addr;
if (error != 0) {
@@ -245,11 +253,9 @@
}
close(fd_hdr);
- close(fd_data);
return rb;
cleanup_data:
- close(fd_data);
if (flags & QB_RB_FLAG_CREATE) {
unlink(rb->shared_hdr->data_path);
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/lib/unix.c new/libqb/lib/unix.c
--- old/libqb/lib/unix.c 2013-06-08 07:44:23.000000000 +0200
+++ new/libqb/lib/unix.c 2013-07-25 08:36:33.000000000 +0200
@@ -141,7 +141,7 @@
unlink_exit:
unlink(path);
- if (fd > 0) {
+ if (fd >= 0) {
close(fd);
}
return res;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/tests/Makefile.in new/libqb/tests/Makefile.in
--- old/libqb/tests/Makefile.in 2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/tests/Makefile.in 2013-07-25 10:58:37.000000000 +0200
@@ -543,9 +543,9 @@
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign tests/Makefile
+ $(AUTOMAKE) --gnu tests/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/tests/bms.c new/libqb/tests/bms.c
--- old/libqb/tests/bms.c 2013-03-07 09:03:14.000000000 +0100
+++ new/libqb/tests/bms.c 2013-07-25 08:36:33.000000000 +0200
@@ -116,6 +116,7 @@
sizeof(response));
if (res < 0) {
qb_perror(LOG_ERR, "qb_ipcs_response_send");
+ return res;
}
}
if (events) {
@@ -123,6 +124,7 @@
sizeof(response));
if (res < 0) {
qb_perror(LOG_ERR, "qb_ipcs_event_send");
+ return res;
}
}
return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/tests/check_ipc.c new/libqb/tests/check_ipc.c
--- old/libqb/tests/check_ipc.c 2013-07-02 11:27:40.000000000 +0200
+++ new/libqb/tests/check_ipc.c 2013-07-25 08:36:33.000000000 +0200
@@ -33,7 +33,21 @@
#include
static const char *ipc_name = "ipc_test";
-#define MAX_MSG_SIZE (8192*16)
+
+#define DEFAULT_MAX_MSG_SIZE (8192*16)
+static int CALCULATED_DGRAM_MAX_MSG_SIZE = 0;
+
+#define DGRAM_MAX_MSG_SIZE \
+ (CALCULATED_DGRAM_MAX_MSG_SIZE == 0 ? \
+ CALCULATED_DGRAM_MAX_MSG_SIZE = qb_ipcc_verify_dgram_max_msg_size(DEFAULT_MAX_MSG_SIZE) : \
+ CALCULATED_DGRAM_MAX_MSG_SIZE)
+
+#define MAX_MSG_SIZE (ipc_type == QB_IPC_SOCKET ? DGRAM_MAX_MSG_SIZE : DEFAULT_MAX_MSG_SIZE)
+
+/* The size the giant msg's data field needs to be to make
+ * this the largests msg we can successfully send. */
+#define GIANT_MSG_DATA_SIZE MAX_MSG_SIZE - sizeof(struct qb_ipc_response_header) - 8
+
static qb_ipcc_connection_t *conn;
static enum qb_ipc_type ipc_type;
@@ -44,6 +58,8 @@
IPC_MSG_RES_DISPATCH,
IPC_MSG_REQ_BULK_EVENTS,
IPC_MSG_RES_BULK_EVENTS,
+ IPC_MSG_REQ_STRESS_EVENT,
+ IPC_MSG_RES_STRESS_EVENT,
IPC_MSG_REQ_SERVER_FAIL,
IPC_MSG_RES_SERVER_FAIL,
IPC_MSG_REQ_SERVER_DISCONNECT,
@@ -75,6 +91,7 @@
static int32_t send_event_on_created = QB_FALSE;
static int32_t disconnect_after_created = QB_FALSE;
static int32_t num_bulk_events = 10;
+static int32_t num_stress_events = 30000;
static int32_t reference_count_test = QB_FALSE;
@@ -91,7 +108,7 @@
void *data, size_t size)
{
struct qb_ipc_request_header *req_pt = (struct qb_ipc_request_header *)data;
- struct qb_ipc_response_header response;
+ struct qb_ipc_response_header response = { 0, };
ssize_t res;
if (req_pt->id == IPC_MSG_REQ_TX_RX) {
@@ -134,9 +151,26 @@
MAX_MSG_SIZE*10);
ck_assert_int_eq(res, -EMSGSIZE);
- for (m = 0; m < num_bulk_events; m++) {
- res = qb_ipcs_event_send(c, &response,
- sizeof(response));
+ /* send one event before responding */
+ res = qb_ipcs_event_send(c, &response, sizeof(response));
+ ck_assert_int_eq(res, sizeof(response));
+ response.id++;
+
+ /* send response */
+ response.id = IPC_MSG_RES_BULK_EVENTS;
+ res = qb_ipcs_response_send(c, &response, response.size);
+ ck_assert_int_eq(res, sizeof(response));
+
+ /* send the rest of the events after the response */
+ for (m = 1; m < num_bulk_events; m++) {
+ res = qb_ipcs_event_send(c, &response, sizeof(response));
+
+ if (res == -EAGAIN || res == -ENOBUFS) {
+ /* retry */
+ usleep(1000);
+ m--;
+ continue;
+ }
ck_assert_int_eq(res, sizeof(response));
response.id++;
}
@@ -144,10 +178,49 @@
ck_assert_int_eq(stats->event_q_length - num, num_bulk_events);
free(stats);
- response.id = IPC_MSG_RES_BULK_EVENTS;
+ } else if (req_pt->id == IPC_MSG_REQ_STRESS_EVENT) {
+ struct {
+ struct qb_ipc_response_header hdr __attribute__ ((aligned(8)));
+ char data[GIANT_MSG_DATA_SIZE] __attribute__ ((aligned(8)));
+ uint32_t sent_msgs __attribute__ ((aligned(8)));
+ } __attribute__ ((aligned(8))) giant_event_send;
+ int32_t m;
+
+ response.size = sizeof(struct qb_ipc_response_header);
+ response.error = 0;
+
+ response.id = IPC_MSG_RES_STRESS_EVENT;
res = qb_ipcs_response_send(c, &response, response.size);
ck_assert_int_eq(res, sizeof(response));
+ giant_event_send.hdr.error = 0;
+ giant_event_send.hdr.id = IPC_MSG_RES_STRESS_EVENT;
+ for (m = 0; m < num_stress_events; m++) {
+ size_t sent_len = sizeof(struct qb_ipc_response_header);
+
+ if (((m+1) % 1000) == 0) {
+ sent_len = sizeof(giant_event_send);
+ giant_event_send.sent_msgs = m + 1;
+ }
+ giant_event_send.hdr.size = sent_len;
+
+ res = qb_ipcs_event_send(c, &giant_event_send, sent_len);
+ if (res < 0) {
+ if (res == -EAGAIN || res == -ENOBUFS) {
+ /* yield to the receive process */
+ usleep(1000);
+ m--;
+ continue;
+ } else {
+ qb_perror(LOG_DEBUG, "sending stress events");
+ ck_assert_int_eq(res, sent_len);
+ }
+ } else if (((m+1) % 1000) == 0) {
+ qb_log(LOG_DEBUG, "SENT: %d stress events sent", m+1);
+ }
+ giant_event_send.hdr.id++;
+ }
+
} else if (req_pt->id == IPC_MSG_REQ_SERVER_FAIL) {
exit(0);
} else if (req_pt->id == IPC_MSG_REQ_SERVER_DISCONNECT) {
@@ -635,6 +708,45 @@
static int32_t events_received;
+static int32_t
+count_stress_events(int32_t fd, int32_t revents, void *data)
+{
+ struct {
+ struct qb_ipc_response_header hdr __attribute__ ((aligned(8)));
+ char data[GIANT_MSG_DATA_SIZE] __attribute__ ((aligned(8)));
+ uint32_t sent_msgs __attribute__ ((aligned(8)));
+ } __attribute__ ((aligned(8))) giant_event_recv;
+ qb_loop_t *cl = (qb_loop_t*)data;
+ int32_t res;
+
+ res = qb_ipcc_event_recv(conn, &giant_event_recv,
+ sizeof(giant_event_recv),
+ -1);
+ if (res > 0) {
+ events_received++;
+
+ if ((events_received % 1000) == 0) {
+ qb_log(LOG_DEBUG, "RECV: %d stress events processed", events_received);
+ if (res != sizeof(giant_event_recv)) {
+ qb_log(LOG_DEBUG, "Unexpected recv size, expected %d got %d",
+ res, sizeof(giant_event_recv));
+ } else if (giant_event_recv.sent_msgs != events_received) {
+ qb_log(LOG_DEBUG, "Server event mismatch. Server thinks we got %d msgs, but we only received %d",
+ giant_event_recv.sent_msgs, events_received);
+ }
+ }
+ } else if (res != -EAGAIN) {
+ qb_perror(LOG_DEBUG, "count_stress_events");
+ qb_loop_stop(cl);
+ return -1;
+ }
+
+ if (events_received >= num_stress_events) {
+ qb_loop_stop(cl);
+ return -1;
+ }
+ return 0;
+}
static int32_t
count_bulk_events(int32_t fd, int32_t revents, void *data)
@@ -719,6 +831,78 @@
stop_process(pid);
}
+static void
+test_ipc_stress_test(void)
+{
+ struct qb_ipc_request_header req_header;
+ struct qb_ipc_response_header res_header;
+ struct iovec iov[1];
+ int32_t c = 0;
+ int32_t j = 0;
+ pid_t pid;
+ int32_t res;
+ qb_loop_t *cl;
+ int32_t fd;
+
+ pid = run_function_in_new_process(run_ipc_server);
+ fail_if(pid == -1);
+ sleep(1);
+
+ do {
+ conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE);
+ if (conn == NULL) {
+ j = waitpid(pid, NULL, WNOHANG);
+ ck_assert_int_eq(j, 0);
+ sleep(1);
+ c++;
+ }
+ } while (conn == NULL && c < 5);
+ fail_if(conn == NULL);
+
+ qb_log(LOG_DEBUG, "Testing %d iterations of EVENT msg passing.", num_stress_events);
+
+ events_received = 0;
+ cl = qb_loop_create();
+ res = qb_ipcc_fd_get(conn, &fd);
+ ck_assert_int_eq(res, 0);
+ res = qb_loop_poll_add(cl, QB_LOOP_MED,
+ fd, POLLIN,
+ cl, count_stress_events);
+ ck_assert_int_eq(res, 0);
+
+ res = send_and_check(IPC_MSG_REQ_STRESS_EVENT, 0, recv_timeout, QB_TRUE);
+
+ qb_loop_run(cl);
+ ck_assert_int_eq(events_received, num_stress_events);
+
+ req_header.id = IPC_MSG_REQ_SERVER_FAIL;
+ req_header.size = sizeof(struct qb_ipc_request_header);
+
+ iov[0].iov_len = req_header.size;
+ iov[0].iov_base = &req_header;
+ res = qb_ipcc_sendv_recv(conn, iov, 1,
+ &res_header,
+ sizeof(struct qb_ipc_response_header), -1);
+ if (res != -ECONNRESET && res != -ENOTCONN) {
+ qb_log(LOG_ERR, "id:%d size:%d", res_header.id, res_header.size);
+ ck_assert_int_eq(res, -ENOTCONN);
+ }
+
+ qb_ipcc_disconnect(conn);
+ stop_process(pid);
+}
+
+START_TEST(test_ipc_stress_test_us)
+{
+ qb_enter();
+ send_event_on_created = QB_FALSE;
+ ipc_type = QB_IPC_SOCKET;
+ ipc_name = __func__;
+ test_ipc_stress_test();
+ qb_leave();
+}
+END_TEST
+
START_TEST(test_ipc_bulk_events_us)
{
qb_enter();
@@ -918,6 +1102,17 @@
}
END_TEST
+START_TEST(test_ipc_stress_test_shm)
+{
+ qb_enter();
+ send_event_on_created = QB_FALSE;
+ ipc_type = QB_IPC_SHM;
+ ipc_name = __func__;
+ test_ipc_stress_test();
+ qb_leave();
+}
+END_TEST
+
START_TEST(test_ipc_bulk_events_shm)
{
qb_enter();
@@ -1000,6 +1195,37 @@
}
END_TEST
+static void test_max_dgram_size(void)
+{
+ /* most implementations will not let you set a dgram buffer
+ * of 1 million bytes. This test verifies that the we can detect
+ * the max dgram buffersize regardless, and that the value we detect
+ * is consistent. */
+ int32_t init;
+ int32_t i;
+
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_REMOVE,
+ QB_LOG_FILTER_FILE, "*", LOG_TRACE);
+
+ init = qb_ipcc_verify_dgram_max_msg_size(1000000);
+ fail_if(init <= 0);
+ for (i = 0; i < 100; i++) {
+ int try = qb_ipcc_verify_dgram_max_msg_size(1000000);
+ ck_assert_int_eq(init, try);
+ }
+
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, "*", LOG_TRACE);
+}
+
+START_TEST(test_ipc_max_dgram_size)
+{
+ qb_enter();
+ test_max_dgram_size();
+ qb_leave();
+}
+END_TEST
+
static Suite *
make_shm_suite(void)
{
@@ -1031,6 +1257,11 @@
tcase_set_timeout(tc, 16);
suite_add_tcase(s, tc);
+ tc = tcase_create("ipc_stress_test_shm");
+ tcase_add_test(tc, test_ipc_stress_test_shm);
+ tcase_set_timeout(tc, 16);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("ipc_bulk_events_shm");
tcase_add_test(tc, test_ipc_bulk_events_shm);
tcase_set_timeout(tc, 16);
@@ -1059,6 +1290,11 @@
Suite *s = suite_create("socket");
TCase *tc;
+ tc = tcase_create("ipc_max_dgram_size");
+ tcase_add_test(tc, test_ipc_max_dgram_size);
+ tcase_set_timeout(tc, 30);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("ipc_server_fail_soc");
tcase_add_test(tc, test_ipc_server_fail_soc);
tcase_set_timeout(tc, 6);
@@ -1089,6 +1325,11 @@
tcase_set_timeout(tc, 16);
suite_add_tcase(s, tc);
+ tc = tcase_create("ipc_stress_test_us");
+ tcase_add_test(tc, test_ipc_stress_test_us);
+ tcase_set_timeout(tc, 60);
+ suite_add_tcase(s, tc);
+
tc = tcase_create("ipc_bulk_events_us");
tcase_add_test(tc, test_ipc_bulk_events_us);
tcase_set_timeout(tc, 16);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libqb/tools/Makefile.in new/libqb/tools/Makefile.in
--- old/libqb/tools/Makefile.in 2013-07-02 11:28:30.000000000 +0200
+++ new/libqb/tools/Makefile.in 2013-07-25 10:58:37.000000000 +0200
@@ -282,9 +282,9 @@
exit 1;; \
esac; \
done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tools/Makefile'; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \
$(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign tools/Makefile
+ $(AUTOMAKE) --gnu tools/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org