Merge tag 'upstream/1.0.1' into debian/master

Upstream version 1.0.1
This commit is contained in:
Ferenc Wágner 2016-12-04 20:53:39 +01:00
commit ea68808d27
70 changed files with 2005 additions and 674 deletions

View File

@ -1 +1 @@
1.0
1.0.1

View File

@ -1 +1 @@
1.0
1.0.1

462
ChangeLog
View File

@ -1,3 +1,422 @@
2016-11-24 Christine Caulfield <ccaulfie@redhat.com>
version: Update version for 1.0.1 release
2016-11-24 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #233 from jnpkrn/copr-tito
build: git -> automatic COPR builds integration followup
2016-11-23 Jan Pokorný <jpokorny@redhat.com>
build: tito: minor adjustments
2016-11-22 Jan Pokorný <jpokorny@redhat.com>
doc: README: add a status badge+link for the COPR builds
2016-11-22 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #232 from jnpkrn/copr-tito
build: allow for git -> automatic COPR builds integration
2016-11-18 Jan Pokorný <jpokorny@redhat.com>
build: allow for git -> automatic COPR builds integration
New tito-related files makes the repository compatible with tito method
of building in COPR (https://fedorahosted.org/copr/wiki/UserDocs#Tito).
build: ensure debug make flags are not derived when unsuitable
Unfortunately, debug messages of GNU make are emitted to stdout, which
spoils the extracted output we rely on. So prevent it (as well as
any other extraneous option) by force.
(discovered during git -> automatic COPR builds integration)
build: ensure check_SCRIPTS are distributed
(discovered during git -> automatic COPR builds integration)
2016-11-08 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #231 from jnpkrn/unlink-or-truncate
Unlink or truncate (as a fallback) files when shm IPC client terminates connection forcibly
2016-11-04 Jan Pokorný <jpokorny@redhat.com>
tests: start stdlib failures injection effort with unlink{,at} + test
There are not many ways to test alternate code paths having failure of
some function from standard library as a precondition.
For a starter, we need to test failing unlink{,at} functions in a
controlled manner to mimic client and server path of the IPC connection
having different privileges to validate the previous commit. But the
test suite cannot assume it has root privileges (so as to add artificial
user system-wide, which is a pretty stupid idea on its own), cannot
generally use stuff like chroot/namespacing (not to speak about
synergies of the former like docker). So what's left is to make our
own playground, or better yet, use existing playground but just to
modify the rules of the game a bit when it's desired -- a variation
of old good LD_PRELOAD trick.
Note that this concept was already used in syslog tests (see commit
642f74d) and is now further extended using dlsym(RTLD_NEXT, "symbol")
to resolve the standard library symbol being shadowed by our little
"module". This hence yields a customized wrapping we use to either
inject a call failure or to increase an invocation counter so as to
assure something has indeed been called. As the mechanisms used are
not supposed to be available everywhere, the build system is
conditionalized respectively.
Back to our test when unlink{,at} fails, with the help of the described
mechanism, it was actually easy to massage test_ipc_server_fail_shm
into test_ipcc_truncate_when_unlink_fails_shm desired addition, which
is also featured in this commit, together with a modification to
resources.test script so that it expects particular number of empty
file leftovers (see previous commit).
It's expected that the module for failure injections will keep growing
so as to enable better overall coverage of the code (on the platforms
where this provision is available).
Med: rb: use new qb_rb_close_helper able to resort to file truncating
This changeset builds on previous 2-3 commits and represents the main
libqb's answer to the original question behind pacemaker's security
defect known as CVE-2016-7035.
Beside the helper partly unifying handling of qb_rb_force_close and
qb_rb_close, it provides the former with ability to use file truncating
as a fallback for when unlinking fails, e.g., because client (note that
mentioned is currently only relevant for the client side as normally
server is responsible for the lifecycle of the materialized files,
unless it crashes and only client is left to do its best) is not the
owner while they are placed at a directory with restricted deletion,
which enforces this very ownership condition.
In practice, this means that, at worst, just the zero-size files are
left behind, so not that much space exhaustion (usually "ramdisk"
like tmpfs is what backs default storage directory /dev/shm, so it
boils down to physical memory exhaustion, even if it can be just
for page cache and related overhead) can happen even on repeated
crashes as the memory mappings are cleared as much as possible.
Also openat/unlinkat functions (sported in qb_sys_unlink_or_truncate_at
as of the previous commit) are, when applicable, used so as to limit
possible race conditions between/during individual path traversals
(both files being got rid of presumably share the same directory).
Few words on which actions are attempted in which order for the
equivalent of qb_rb_force_close now:
There are subtle interactions between what's externally visible
(files) and what's not (memory mappings associated with such files),
and perhaps between memory pages management from the perspective of
the former (usually "ramdisk"/tmpfs) and the latter (mmap + munmap).
If the associated file is no longer publicly exposed by the means of
unlink (even if the object survives internally as refcounting is in
the game, with mmap holding a reference), memory mapping is not
affected. On the other hand, if it's just limited by truncation
to zero size, memory mapping is aware and generates SIGBUS in response
to accessing respective addresses. Similarly, accessing munmap'd
(no refcounting here) memory generates SIGSEGV. For delicacy,
the inputs for all of unlink, truncate, and munmap are stored
at the mmap'd location we are about to drop, but that's just a matter
of making copies ahead of time.
At Ken's suggestion, the scheme is: (unlink or truncate) then munmap,
which has a benefit that externally visible (and program's life span
otherwise surviving!) part is eliminated first, with memory mappings
(disposed at program termination automatically at latest) to follow.
(There was originally a paranoid expectation on my side that truncate
on tmpfs actually does silent munmap, so that our munmap could in fact
tear down the mapping added in the interim by the libraries, signal
handler or due to requirements of another thread, also because of
munmap on the range without any current mappings will not fail, and
thus there's likely no portable way to non-intrusively check the
status, but also due to documented SIGBUS vs. SIGSEGV differences
the whole assumption appears bogus on the second thought.)
Relevant unit tests that exercise client-side unlinking:
- check_ipc: test_ipc_server_fail_shm, test_ipc_exit_shm
- new test in a subsequent commit
Low: unix: new qb_sys_unlink_or_truncate{,_at} helpers
These are intended for subsequent qb_rb_{force_,}close refactorization
and utilization of this new truncate as a fallback after unlink failure
as detailed in the commit to follow.
For newer POSIX revision compliant systems, there's "at" variant using
openat/unlinkat functions so that paths do not have to be traversed
in full anew when not needed (as both unlink and truncate operate on
the same path).
Med: rb: make it more robust against trivial IPC API misuses
...using a new private inline helper that is intended to "decorate"
argument (plus extra reference level added) to qb_rb_{force_,}close().
It is purposefully not hardwired to neither qb_rb_close (it's a public
API function that should not change its semantics) nor qb_rb_force_close
(just for symmetry, preempting issues when the two would differ, and
also makes them more mutually compatible, which is already expected
at qb_ipcc_shm_disconnect).
It sets the original ringbuffer pointer to NULL (having the immediate
impact on other threads/asynchronous handling) and also sets the
(currently underused) reference counter set to exacly 1 (that is
subsequently going to be decremented in qb_rb_close so that it's
sound in the current arrangement).
More in the comment at the helper.
Suitable places are also made to use it right away.
Refactor: ipc_shm: better grip on ringbuffers to close
Also remove unused comment-introduced section of code.
2016-10-21 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #230 from jnpkrn/log_thread
Med: log_thread: logt_wthread_lock is vital for logging thread
Merge pull request #228 from jnpkrn/maint
Various cleanups (symbol imports, typos, doc)
2016-10-21 Jan Pokorný <jpokorny@redhat.com>
Refactor: log_thread: fix and diminish inferior comments
Med: log_thread: logt_wthread_lock is vital for logging thread
This fixes issue with would-fail-if-applied-to-thread-right-away
qb_log_thread_priority_set invocation when logging thread doesn't
exist yet, which will arrange for calling itself at the time of
thread's birth that is the moment it will actually fail.
In this + lock-could-not-have-been-initialized corner cases, the
already running thread would proceed as allowed by error condition
handling in the main thread, trying to dereference uninitialized
(or outdated) pointer to the lock at hand, resulting in segfault.
Also include the test that would have been caught that (we use the
fact that it doesn't matter whether setting of the scheduler parameters
fails due to bad input or just because of lack of privileges as it's
the failure at the right moment that is of our interest).
See also:
https://github.com/ClusterLabs/libqb/issues/229
2016-10-20 Christine Caulfield <ccaulfie@redhat.com>
tests: Unit test for previous zero tag patch
log: Remove check for HAVE_SCHED_GET_PRIORITY_MAX
it doesn't exist
2016-10-18 Jan Pokorný <jpokorny@redhat.com>
tests: SIGSTOP cannot be caught, blocked, or ignored
...per signal(7), so it is foolish trying to do so.
2016-10-18 Christine Caulfield <ccaulfie@redhat.com>
log: Don't overwrite valid tags
If a tag of 0 is passed into the logger and an existing callsite
is found with a non-zero tag, the don't overwrite the existing tag.
2016-10-17 Jan Pokorný <jpokorny@redhat.com>
Low: ipc_shm: fix superfluous NULL check
That's what qb_rb_chunk_reclaim does since commit
ef7739873842a3e7933ef610b9b61e0f4a7d2fde that made this
check redundant.
doc: elaborate more on thread safety as it's not so pure
Low: further sanitize qbipc[cs].h public headers wrt. includes
Low: sanitize import of <poll.h> symbols
Low: sanitize import of <qb/qbarray.h> symbols
2016-10-12 Jan Pokorný <jpokorny@redhat.com>
Fix typos: availabi{l -> li}ty, explici{lt -> tl}y
2016-10-11 Christine Caulfield <ccaulfie@redhat.com>
Merge branch 'jnpkrn-Svante-Signell-Hurd'
Merge branch 'Svante-Signell-Hurd' of https://github.com/jnpkrn/libqb into jnpkrn-Svante-Signell-Hurd
2016-10-11 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #226 from jnpkrn/maint
Maint: fix typos + resources.test
2016-10-07 Jan Pokorný <jpokorny@redhat.com>
tests: resources: check for proper names of leftover processes
Unfortunately, the change in test names introduced with commit e990681
hadn't been reflected (until now).
Also reformat shell syntax per more usual convention.
Fix typos: differ{ne -> en}t, is -> if
2016-10-04 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #224 from jnpkrn/maint
Maint: typo + unused functions checked in configure
2016-09-30 Jan Pokorný <jpokorny@redhat.com>
Fix typo: asyncronous -> asynchronous
Build: configure: do not check for unused "sched" functions
Do not compile-time-conditionalize based on one of them being available,
either.
2016-09-23 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #223 from jnpkrn/maint
maint: qb-blackbox man page should accompany the binary
2016-09-22 Jan Pokorný <jpokorny@redhat.com>
maint: qb-blackbox man page should accompany the binary
2016-08-01 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #218 from wferi/apropos
docs: qbdefs.h: description must directly follow @file
2016-07-31 Ferenc Wágner <wferi@niif.hu>
docs: qbdefs.h: description must directly follow @file
If we want to see it again in the man page NAME section, where it can
be indexed by apropos or whatis.
2016-06-30 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #221 from jnpkrn/typo-qblog.h
Fix typo: qblog.h: q{g -> b}_log_filter_ctl
2016-06-29 Jan Pokorný <jpokorny@redhat.com>
Fix typo: qblog.h: q{g -> b}_log_filter_ctl
2016-06-20 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #217 from jnpkrn/log-serialize-check-char-properly
Low: log: check for appropriate space when serializing a char
2016-06-20 Christine Caulfield <ccaulfie@redhat.com>
log: Add missing z,j, & t types to the logger
Reviewed-by: Ken Gaillot <kgaillot@redhat.com>
Reviewed-by: Jan Pokorný <jpokorny@redhat.com>
2016-06-17 Jan Pokorný <jpokorny@redhat.com>
Low: log: check for appropriate space when serializing a char
... where appropriate space is measured for, surprisingly, a char,
not for an int. Note that's also the actual type used for both
de-/serializing, so there's no conflict.
Also bother to explain why, now surprisingly for real, an unsigned int
is scraped out from va_list (akin to to STDARG(3)).
2016-06-06 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #213 from liu4480/master
low:fixed:Spelling error of failure in qbhdb.h
2016-06-06 bin.liu <bliu@suse.com>
low:fixed:Spelling error of failure in qbhdb.h
There are spelling error in include/qb/qbhdb.h, "failure" is
wroten as "faliure"
2016-05-06 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #211 from jnpkrn/CI-travis-clang
CI: make travis use also clang compiler (for good measure)
2016-05-05 Jan Pokorný <jpokorny@redhat.com>
CI: make travis use also clang compiler (for good measure)
Also, unify the indentation.
tests: make clang-friendly (avoid using run-time VLAs)
This is to also get libqb from the Debian's shame list:
http://clang.debian.net/status.php?version=3.4.2&key=VARIABLE_LENGTH_ARRAY
2016-04-29 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #210 from jnpkrn/tests-ensure-failure-output
tests: ensure verbose output on failure w/ more recent automake
2016-04-28 Jan Pokorný <jpokorny@redhat.com>
tests: ensure verbose output on failure w/ more recent automake
...so as to obtain a first glance diagnostics in all cases with possibly
remote build system preventing other means of investigation.
2016-04-19 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #209 from jnpkrn/header-based-versioning-PATCH-to-MICRO
API: header-based versioning: s/PATCH/MICRO
2016-04-18 Jan Pokorný <jpokorny@redhat.com>
API: header-based versioning: s/PATCH/MICRO
Under the influence of libxml2 and considering that actual "patch"
information in fact, if significant, ends up encoded in QB_VER_REST,
shift away from convention codified, e.g., by semver.org (not adored
by libqb, anyway) and rename designated PATCH component of the version
to MICRO accordingly.
Note that at this point, after a release without any header-based
versioning present and just a few commits after it was tentatively
introduced, it's a painless change. Once this PATCH nomenclature
is leaked into a full release, there's no way to get rid of it
reasonably...
2016-04-07 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #208 from jnpkrn/update-git-version-gen
build: use latest git-version-gen from gnulib (rev. 6118065)
Merge pull request #207 from jnpkrn/alternative-header-based-versioning
API: introduce alternative, header-based versioning
2016-04-04 Jan Pokorný <jpokorny@redhat.com>
build: persuade git-version-gen vMAJOR.MINOR tags just miss .0
Recent "v1.0" discovered this discrepancy propagated all around
and also this is not very compatible with the logic of commit 26d3911.
Treat missing "patch" component of the version as an implicit zero
to make such oddity go away.
Adjust spec file generation accordingly.
build: use latest git-version-gen from gnulib (rev. 6118065)
Preserve, however, the modification by David Vossel to keep the script
working as expected also with lightweight tags (e.g., v1.0rc3).
2016-04-01 Jan Pokorný <jpokorny@redhat.com>
API: introduce alternative, header-based versioning
Mainly as a light-weight alternative to full-blown autoconf/pkg-config
machineries, whereby one can:
* workaround functionality not present in libqb up to 1.0 (inclusive)
- note that this versioning schema is being introduced *after*
1.0.0 release so one cannot tell that version from any older,
but will be able to safely identify any later one (1.0.1+)
and act accordingly
- example:
#if !defined(QB_VER_MAJOR) || ((QB_VER_MAJOR == 1) && (QB_VER_MINOR < 1))
#warning "Feature X not supported"
int do_foo(int arg) { };
#else
int
do_foo(int arg)
{
/* use feature X of libqb */
}
#endif
* make its program report libqb API version it was built with by
emitting QB_VER_STR symbolic string (see tests/print_ver.c for example)
Also added is a print_ver test program to:
* emit how original unparsed version is parsed to particular components
defined in qbconfig.h (QB_VER_{MAJOR,MINOR,PATCH} symbolic integer
constants and QB_VER_REST symbolic string) when being compiled
* emit mentioned QB_VER_STR symbolic string joining the components
back to a single string, plus the components themselves
Resolves: https://github.com/ClusterLabs/libqb/issues/186
2016-04-01 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #196 from jnpkrn/demystify-qblog.h
Low: explain mysterious lines in a public header (qblog.h)
Merge pull request #191 from jnpkrn/refactor-test-case-defs
tests: refactor test case defs using versatile add_tcase macro
2016-03-18 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #205 from jnpkrn/docs-fix-make-doxygen
@ -36,6 +455,18 @@
Merge pull request #203 from jnpkrn/docs-refactor-doxygen
Docs: refactor doxygen configuration files
2016-03-17 Svante Signell <svante.signell@gmail.com>
Add Hurd support
* configure.ac: Define QB_GNU.
Add a check for a working clock_getres for the CLOCK_MONOTONIC
option defining HAVE_CLOCK_GETRES_MONOTONIC.
* lib/log_thread.c: Replace second argument of
qb_log_thread_priority_set(): logt_sched_param.sched_priority by 0
when not supported by the OS.
* lib/util.c: Use the CLOCK_REALTIME option in clock_getres() if
HAVE_CLOCK_GETRES_MONOTONIC os not defined.
2016-03-17 Jan Pokorný <jpokorny@redhat.com>
docs: *.dox.in: comment out the defaults/empty values
@ -168,6 +599,25 @@
build: do not install syslog_override for the RPM packaging
2016-03-04 Jan Pokorný <jpokorny@redhat.com>
build: be more restrictive about QB_HAVE_ATTRIBUTE_SECTION
That's because the code relies on (fairly unportable) treatment by the
linker, specifically ld linker from binutils suite:
<https://sourceware.org/binutils/docs/ld/Orphan-Sections.html>
and without that in place, QB_HAVE_ATTRIBUTE_SECTION cannot be enabled
as the __{start,stop}_SECNAME extern references in qb/qblog.h will not
get resolved at the link time.
Low: further avoid magic in qblog.h by using named constants
Also advise to use these constants and obey this in the internal code.
defs: add wrappers over preprocessor operators
Low: explain mysterious lines in a public header (qblog.h)
Also fix the previous inversion of the expression that in fact did not
use to check for anything (for "assert(1)" being a NOOP).
2016-03-01 Chrissie Caulfield <ccaulfie@redhat.com>
Merge pull request #190 from jnpkrn/build-syslog-tests-followup
@ -175,6 +625,18 @@
2016-03-01 Jan Pokorný <jpokorny@redhat.com>
tests: refactor test case defs using versatile add_tcase macro
This reduces repeated code significantly, and allows for easier
supervision of what's being grouped to the suites + possibly what
timeouts apply.
Note that some artificial test case identifiers (in check_array.c,
check_log.c, check_loop.c, check_rb.c, check_utils.c) got changed
so they now follow 1:1 the test (function) name that is being run
for the case at hand without the "test_" prefix (strict convention).
Exception to this are test_ipc_disp_* tests in check_ipc.c that got,
conversely, changed to test_ipc_dispatch_* to follow the test case
identifiers.
build: enable syslog tests when configuring in spec
...hence make syslog tests executed in %check.

View File

@ -60,16 +60,20 @@ $(SPEC): $(SPEC).in
@rm -f $@-t $@
@date="$(shell LC_ALL=C date "+%a %b %d %Y")" && \
if [ -f .tarball-version ]; then \
gitver="$(shell cat .tarball-version)" && \
ver="$(shell cat .tarball-version)" && \
gitver=`echo $$ver | sed \
-e 's|^\(v[0-9][0-9]*\.[0-9][0-9]*\)\([^.].*\)\?$$|\1.0\2|'` && \
rpmver=$$gitver && \
alphatag="" && \
dirty="" && \
numcomm="0"; \
else \
gitver="$(shell git describe --abbrev=4 --match='v*' --tags HEAD 2>/dev/null)" && \
ver="$(shell git describe --abbrev=4 --match='v*' --tags HEAD 2>/dev/null)" && \
gitver=`echo $$ver | sed \
-e 's|^\(v[0-9][0-9]*\.[0-9][0-9]*\)\([^.].*\)\?$$|\1.0\2|'` && \
rpmver=`echo $$gitver | sed -e "s/^v//" -e "s/-.*//g"` && \
alphatag=`echo $$gitver | sed -e "s/.*-//" -e "s/^g//"` && \
vtag=`echo $$gitver | sed -e "s/-.*//g"` && \
vtag=`echo $$ver | sed -e "s/-.*//g"` && \
numcomm=`git rev-list $$vtag..HEAD | wc -l` && \
git update-index --refresh > /dev/null 2>&1 || true && \
dirty=`git diff-index --name-only HEAD 2>/dev/null`; \

View File

@ -922,16 +922,20 @@ $(SPEC): $(SPEC).in
@rm -f $@-t $@
@date="$(shell LC_ALL=C date "+%a %b %d %Y")" && \
if [ -f .tarball-version ]; then \
gitver="$(shell cat .tarball-version)" && \
ver="$(shell cat .tarball-version)" && \
gitver=`echo $$ver | sed \
-e 's|^\(v[0-9][0-9]*\.[0-9][0-9]*\)\([^.].*\)\?$$|\1.0\2|'` && \
rpmver=$$gitver && \
alphatag="" && \
dirty="" && \
numcomm="0"; \
else \
gitver="$(shell git describe --abbrev=4 --match='v*' --tags HEAD 2>/dev/null)" && \
ver="$(shell git describe --abbrev=4 --match='v*' --tags HEAD 2>/dev/null)" && \
gitver=`echo $$ver | sed \
-e 's|^\(v[0-9][0-9]*\.[0-9][0-9]*\)\([^.].*\)\?$$|\1.0\2|'` && \
rpmver=`echo $$gitver | sed -e "s/^v//" -e "s/-.*//g"` && \
alphatag=`echo $$gitver | sed -e "s/.*-//" -e "s/^g//"` && \
vtag=`echo $$gitver | sed -e "s/-.*//g"` && \
vtag=`echo $$ver | sed -e "s/-.*//g"` && \
numcomm=`git rev-list $$vtag..HEAD | wc -l` && \
git update-index --refresh > /dev/null 2>&1 || true && \
dirty=`git diff-index --name-only HEAD 2>/dev/null`; \

View File

@ -10,6 +10,7 @@ focused APIs that are highly tuned for maximum performance for client-server
applications.
[![Build Status](https://travis-ci.org/ClusterLabs/libqb.png)](https://travis-ci.org/ClusterLabs/libqb)
[![COPR Build Status](https://copr.fedorainfracloud.org/coprs/g/ClusterLabs/devel/package/libqb/status_image/last_build.png)](https://copr.fedorainfracloud.org/coprs/g/ClusterLabs/devel/package/libqb/)
## For more information, see:
* [libqb wiki](https://github.com/clusterlabs/libqb/wiki)

View File

@ -1,8 +1,8 @@
#!/bin/sh
# Print a version string.
scriptversion=2011-02-19.19; # UTC
scriptversion=2016-01-11.22; # UTC
# Copyright (C) 2007-2011 Free Software Foundation, Inc.
# Copyright (C) 2007-2016 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -44,8 +44,10 @@ scriptversion=2011-02-19.19; # UTC
# files to pick up a version string change; and leave it stale to
# minimize rebuild time after unrelated changes to configure sources.
#
# It is probably wise to add these two files to .gitignore, so that you
# don't accidentally commit either generated file.
# As with any generated file in a VC'd directory, you should add
# /.version to .gitignore, so that you don't accidentally commit it.
# .tarball-version is never generated in a VC'd directory, so needn't
# be listed there.
#
# Use the following line in your configure.ac, so that $(VERSION) will
# automatically be up-to-date each time configure is run (and note that
@ -57,24 +59,74 @@ scriptversion=2011-02-19.19; # UTC
# [bug-project@example])
#
# Then use the following lines in your Makefile.am, so that .version
# will be present for dependencies, and so that .tarball-version will
# exist in distribution tarballs.
# will be present for dependencies, and so that .version and
# .tarball-version will exist in distribution tarballs.
#
# EXTRA_DIST = $(top_srcdir)/.version
# BUILT_SOURCES = $(top_srcdir)/.version
# $(top_srcdir)/.version:
# echo $(VERSION) > $@-t && mv $@-t $@
# dist-hook:
# echo $(VERSION) > $(distdir)/.tarball-version
case $# in
1|2) ;;
*) echo 1>&2 "Usage: $0 \$srcdir/.tarball-version" \
'[TAG-NORMALIZATION-SED-SCRIPT]'
exit 1;;
esac
tarball_version_file=$1
tag_sed_script="${2:-s/x/x/}"
me=$0
version="git-version-gen $scriptversion
Copyright 2011 Free Software Foundation, Inc.
There is NO warranty. You may redistribute this software
under the terms of the GNU General Public License.
For more information about these matters, see the files named COPYING."
usage="\
Usage: $me [OPTION]... \$srcdir/.tarball-version [TAG-NORMALIZATION-SED-SCRIPT]
Print a version string.
Options:
--prefix PREFIX prefix of git tags (default 'v')
--fallback VERSION
fallback version to use if \"git --version\" fails
--help display this help and exit
--version output version information and exit
Running without arguments will suffice in most cases."
prefix=v
fallback=
while test $# -gt 0; do
case $1 in
--help) echo "$usage"; exit 0;;
--version) echo "$version"; exit 0;;
--prefix) shift; prefix="$1";;
--fallback) shift; fallback="$1";;
-*)
echo "$0: Unknown option '$1'." >&2
echo "$0: Try '--help' for more information." >&2
exit 1;;
*)
if test "x$tarball_version_file" = x; then
tarball_version_file="$1"
elif test "x$tag_sed_script" = x; then
tag_sed_script="$1"
else
echo "$0: extra non-option argument '$1'." >&2
exit 1
fi;;
esac
shift
done
if test "x$tarball_version_file" = x; then
echo "$usage"
exit 1
fi
tag_sed_script="${tag_sed_script:-s/x/x/}"
nl='
'
@ -92,22 +144,22 @@ then
[0-9]*) ;;
*) v= ;;
esac
test -z "$v" \
test "x$v" = x \
&& echo "$0: WARNING: $tarball_version_file is missing or damaged" 1>&2
fi
if test -n "$v"
if test "x$v" != x
then
: # use $v
# Otherwise, if there is at least one git commit involving the working
# directory, and "git describe" output looks sensible, use that to
# derive a version string.
elif test "`git log -1 --pretty=format:x . 2>&1`" = x \
&& v=`git describe --abbrev=4 --match='v*' --tags HEAD 2>/dev/null \
&& v=`git describe --abbrev=4 --match="$prefix*" --tags HEAD 2>/dev/null \
|| git describe --abbrev=4 --tags HEAD 2>/dev/null` \
&& v=`printf '%s\n' "$v" | sed "$tag_sed_script"` \
&& case $v in
v[0-9]*) ;;
$prefix[0-9]*) ;;
*) (exit 1) ;;
esac
then
@ -136,16 +188,18 @@ then
# Remove the "g" in git describe's output string, to save a byte.
v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
v_from_git=1
else
elif test "x$fallback" = x || git --version >/dev/null 2>&1; then
v=UNKNOWN
else
v=$fallback
fi
v=`echo "$v" |sed 's/^v//'`
v=`echo "$v" |sed "s/^$prefix//"`
# Test whether to append the "-dirty" suffix only if the version
# string we're using came from git. I.e., skip the test if it's "UNKNOWN"
# or if it came from .tarball-version.
if test -n "$v_from_git"; then
if test "x$v_from_git" != x; then
# Don't declare a version "dirty" merely because a time stamp has changed.
git update-index --refresh > /dev/null 2>&1
@ -161,12 +215,12 @@ if test -n "$v_from_git"; then
fi
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
echo "$v" | tr -d "$nl"
printf %s "$v"
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-time-zone: "UTC"
# time-stamp-time-zone: "UTC0"
# time-stamp-end: "; # UTC"
# End:

231
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for libqb 1.0.
# Generated by GNU Autoconf 2.69 for libqb 1.0.1.
#
# Report bugs to <developers@clusterlabs.org>.
#
@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='libqb'
PACKAGE_TARNAME='libqb'
PACKAGE_VERSION='1.0'
PACKAGE_STRING='libqb 1.0'
PACKAGE_VERSION='1.0.1'
PACKAGE_STRING='libqb 1.0.1'
PACKAGE_BUGREPORT='developers@clusterlabs.org'
PACKAGE_URL=''
@ -653,6 +653,8 @@ HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS_TRUE
HAVE_GCC_BUILTINS_FOR_SYNC_OPERATIONS_FALSE
HAVE_GCC_BUILTINS_FOR_SYNC_OPERATIONS_TRUE
LIBOBJS
HAVE_FAILURE_INJECTION_FALSE
HAVE_FAILURE_INJECTION_TRUE
HAVE_KQUEUE_FALSE
HAVE_KQUEUE_TRUE
HAVE_POLL_FALSE
@ -1378,7 +1380,7 @@ if test "$ac_init_help" = "long"; then
# 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 1.0 to adapt to many kinds of systems.
\`configure' configures libqb 1.0.1 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1448,7 +1450,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of libqb 1.0:";;
short | recursive ) echo "Configuration of libqb 1.0.1:";;
esac
cat <<\_ACEOF
@ -1573,7 +1575,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
libqb configure 1.0
libqb configure 1.0.1
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -2350,7 +2352,7 @@ cat >config.log <<_ACEOF
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 1.0, which was
It was created by libqb $as_me 1.0.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -4531,7 +4533,7 @@ fi
# Define the identity of the package.
PACKAGE='libqb'
VERSION='1.0'
VERSION='1.0.1'
cat >>confdefs.h <<_ACEOF
@ -17645,58 +17647,49 @@ $as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MSG_NOSIGNAL" >&5
$as_echo_n "checking for MSG_NOSIGNAL... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a working clock_getres(CLOCK_MONOTONIC, &ts)" >&5
$as_echo_n "checking for a working clock_getres(CLOCK_MONOTONIC, &ts)... " >&6; }
if test "$cross_compiling" = yes; then :
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run test program while cross compiling
See \`config.log' for more details" "$LINENO" 5; }
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/socket.h>
#include <time.h>
int
main ()
{
int f = MSG_NOSIGNAL;
struct timespec ts; if(clock_getres(CLOCK_MONOTONIC, &ts)) return -1;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
if ac_fn_c_try_run "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_MSG_NOSIGNAL 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SO_NOSIGPIPE " >&5
$as_echo_n "checking for SO_NOSIGPIPE ... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/socket.h>
int
main ()
{
int f = SO_NOSIGPIPE;
;
return 0;
}
cat >>confdefs.h <<_ACEOF
#define HAVE_CLOCK_GETRES_MONOTONIC 1
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_SO_NOSIGPIPE 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
# Checks for library functions.
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
# Checks for library functions
for ac_header in unistd.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
@ -18277,8 +18270,8 @@ for ac_func in alarm clock_gettime ftruncate gettimeofday \
pthread_mutexattr_setpshared \
pthread_condattr_setpshared \
sem_timedwait semtimedop \
sched_get_priority_max sched_setscheduler \
getpeerucred getpeereid
getpeerucred getpeereid \
openat unlinkat
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -18291,6 +18284,87 @@ fi
done
# Checks for defined macros
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for MSG_NOSIGNAL" >&5
$as_echo_n "checking for MSG_NOSIGNAL... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/socket.h>
int
main ()
{
int f = MSG_NOSIGNAL;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_MSG_NOSIGNAL 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SO_NOSIGPIPE " >&5
$as_echo_n "checking for SO_NOSIGPIPE ... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/socket.h>
int
main ()
{
int f = SO_NOSIGPIPE;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_SO_NOSIGPIPE 1" >>confdefs.h
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for RTLD_NEXT" >&5
$as_echo_n "checking for RTLD_NEXT... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>
int
main ()
{
void *h = RTLD_NEXT;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_FAILURE_INJECTION 1" >>confdefs.h
have_RTLD_NEXT=yes
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
if test "x$ac_cv_func_sem_timedwait" = xyes; then
HAVE_SEM_TIMEDWAIT_TRUE=
HAVE_SEM_TIMEDWAIT_FALSE='#'
@ -18323,6 +18397,14 @@ else
HAVE_KQUEUE_FALSE=
fi
if test "x$have_RTLD_NEXT" = xyes; then
HAVE_FAILURE_INJECTION_TRUE=
HAVE_FAILURE_INJECTION_FALSE='#'
else
HAVE_FAILURE_INJECTION_TRUE='#'
HAVE_FAILURE_INJECTION_FALSE=
fi
ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
@ -18550,6 +18632,15 @@ _ACEOF
CP=rsync
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Solaris" >&5
$as_echo "Solaris" >&6; }
;;
*gnu*)
cat >>confdefs.h <<_ACEOF
#define QB_GNU 1
_ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: GNU" >&5
$as_echo "GNU" >&6; }
;;
*)
as_fn_error $? "Unsupported OS? hmmmm" "$LINENO" 5
@ -18880,16 +18971,18 @@ fi
# --- callsite sections ---
if test "x${GCC}" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC supports __attribute__((section())" >&5
$as_echo_n "checking whether GCC supports __attribute__((section())... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC supports __attribute__((section()) + ld supports orphan sections" >&5
$as_echo_n "checking whether GCC supports __attribute__((section()) + ld supports orphan sections... " >&6; }
if test "x${ac_cv_link_attribute_section}" = x ; then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <assert.h>
extern void * __start___verbose, * __stop___verbose;
int
main ()
{
static int my_var __attribute__((section("__verbose"))) = 5;
if (__start___verbose == __stop___verbose) assert(0);
if (my_var == 5) return 0;
else return -1;
@ -18981,6 +19074,36 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
# version parsing (for qbconfig.h)
cat >>confdefs.h <<_ACEOF
#define QB_VER_MAJOR $(echo "${VERSION}" \
| sed -e 's|^\([0-9][0-9]*\).*|\1|' \
-e t -e 's|.*|1|')
_ACEOF
cat >>confdefs.h <<_ACEOF
#define QB_VER_MINOR $(echo "${VERSION}" \
| sed -e 's|^[0-9][0-9]*\.\([0-9][0-9]*\).*|\1|' \
-e t -e 's|.*|0|')
_ACEOF
cat >>confdefs.h <<_ACEOF
#define QB_VER_MICRO $(echo "${VERSION}" \
| sed -e 's|^[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\).*|\1|' \
-e t -e 's|.*|0|')
_ACEOF
cat >>confdefs.h <<_ACEOF
#define QB_VER_REST $(echo "${VERSION}" \
| sed -e 's|^[0-9][0-9]*\(\.[0-9][0-9]*\)\{0,2\}\(.*\)|"\2"|' \
-e t -e 's|.*|""|')
_ACEOF
ac_config_files="$ac_config_files Makefile include/Makefile include/qb/Makefile lib/Makefile lib/libqb.pc tools/Makefile tests/Makefile tests/test.conf examples/Makefile docs/Makefile docs/common.dox docs/html.dox docs/man.dox"
@ -19153,6 +19276,10 @@ if test -z "${HAVE_KQUEUE_TRUE}" && test -z "${HAVE_KQUEUE_FALSE}"; then
as_fn_error $? "conditional \"HAVE_KQUEUE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${HAVE_FAILURE_INJECTION_TRUE}" && test -z "${HAVE_FAILURE_INJECTION_FALSE}"; then
as_fn_error $? "conditional \"HAVE_FAILURE_INJECTION\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
if test -z "${HAVE_GCC_BUILTINS_FOR_SYNC_OPERATIONS_TRUE}" && test -z "${HAVE_GCC_BUILTINS_FOR_SYNC_OPERATIONS_FALSE}"; then
as_fn_error $? "conditional \"HAVE_GCC_BUILTINS_FOR_SYNC_OPERATIONS\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
@ -19570,7 +19697,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# 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 1.0, which was
This file was extended by libqb $as_me 1.0.1, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -19636,7 +19763,7 @@ _ACEOF
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 1.0
libqb config.status 1.0.1
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@ -3,8 +3,10 @@
AC_PREREQ([2.61])
dnl inject zero as a "patch" component of the version if missing in tag
AC_INIT([libqb],
m4_esyscmd([build-aux/git-version-gen .tarball-version]),
m4_esyscmd([build-aux/git-version-gen .tarball-version \
's|^\(v[0-9][0-9]*\.[0-9][0-9]*\)\([^.].*\)\?$|\1.0\2|']),
[developers@clusterlabs.org])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_SRCDIR([lib/ringbuffer.c])
@ -172,7 +174,39 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
]
)
AC_MSG_CHECKING(for a working clock_getres(CLOCK_MONOTONIC, &ts))
AC_RUN_IFELSE([AC_LANG_PROGRAM(
[[#include <time.h>]],
[[struct timespec ts; if(clock_getres(CLOCK_MONOTONIC, &ts)) return -1;]])],
[
AC_MSG_RESULT([yes])
AC_DEFINE_UNQUOTED([HAVE_CLOCK_GETRES_MONOTONIC], 1, [Define to 1 if clock_getres(CLOCK_MONOTONIC, &ts) works])
],
[
AC_MSG_RESULT([no])
]
)
# Checks for library functions
AC_FUNC_CHOWN
AC_FUNC_FORK
AC_FUNC_MMAP
AC_FUNC_STRERROR_R
AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday \
localtime localtime_r memset munmap socket \
strchr strrchr strdup strstr strcasecmp \
poll epoll_create epoll_create1 kqueue \
random rand getrlimit sysconf \
pthread_spin_lock pthread_setschedparam \
pthread_mutexattr_setpshared \
pthread_condattr_setpshared \
sem_timedwait semtimedop \
getpeerucred getpeereid \
openat unlinkat])
# Checks for defined macros
AC_MSG_CHECKING(for MSG_NOSIGNAL)
AC_TRY_COMPILE([#include <sys/socket.h>],
[ int f = MSG_NOSIGNAL; ],
@ -188,23 +222,18 @@ AC_TRY_COMPILE([#include <sys/socket.h>],
AC_DEFINE(HAVE_SO_NOSIGPIPE, 1,
[Define this symbol if you have SO_NOSIGPIPE]) ],
[ AC_MSG_RESULT(no)])
AC_MSG_CHECKING([for RTLD_NEXT])
AC_TRY_COMPILE([#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h>],
[ void *h = RTLD_NEXT; ],
[ AC_MSG_RESULT([yes])
AC_DEFINE([HAVE_FAILURE_INJECTION], 1,
[have failure injection])
have_RTLD_NEXT=yes ],
[ AC_MSG_RESULT([no])])
# Checks for library functions.
AC_FUNC_CHOWN
AC_FUNC_FORK
AC_FUNC_MMAP
AC_FUNC_STRERROR_R
AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday \
localtime localtime_r memset munmap socket \
strchr strrchr strdup strstr strcasecmp \
poll epoll_create epoll_create1 kqueue \
random rand getrlimit sysconf \
pthread_spin_lock pthread_setschedparam \
pthread_mutexattr_setpshared \
pthread_condattr_setpshared \
sem_timedwait semtimedop \
sched_get_priority_max sched_setscheduler \
getpeerucred getpeereid])
AM_CONDITIONAL(HAVE_SEM_TIMEDWAIT,
[test "x$ac_cv_func_sem_timedwait" = xyes])
@ -214,6 +243,8 @@ AM_CONDITIONAL(HAVE_POLL,
[test "x$ac_cv_func_poll" = xyes])
AM_CONDITIONAL(HAVE_KQUEUE,
[test "x$ac_cv_func_kqueue" = xyes])
AM_CONDITIONAL(HAVE_FAILURE_INJECTION,
[test "x$have_RTLD_NEXT" = xyes])
AC_CONFIG_LIBOBJ_DIR(lib)
AC_REPLACE_FUNCS(strlcpy strlcat strchrnul)
@ -335,6 +366,11 @@ case "$host_os" in
CP=rsync
AC_MSG_RESULT([Solaris])
;;
*gnu*)
AC_DEFINE_UNQUOTED([QB_GNU], [1],
[Compiling for GNU/Hurd platform])
AC_MSG_RESULT([GNU])
;;
*)
AC_MSG_ERROR([Unsupported OS? hmmmm])
;;
@ -549,10 +585,12 @@ AC_SUBST(HAVE_SYSLOG_TESTS)
# --- callsite sections ---
if test "x${GCC}" = xyes; then
AC_MSG_CHECKING([whether GCC supports __attribute__((section())])
AC_MSG_CHECKING([whether GCC supports __attribute__((section()) + ld supports orphan sections])
if test "x${ac_cv_link_attribute_section}" = x ; then
AC_TRY_LINK([],
AC_TRY_LINK([#include <assert.h>
extern void * __start___verbose, * __stop___verbose;],
[static int my_var __attribute__((section("__verbose"))) = 5;
if (__start___verbose == __stop___verbose) assert(0);
if (my_var == 5) return 0;
else return -1;
],
@ -610,6 +648,28 @@ AC_DEFINE_UNQUOTED([SOCKETDIR], "$(eval echo ${SOCKETDIR})", [Socket directory])
AC_DEFINE_UNQUOTED([LOCALSTATEDIR], "$(eval echo ${localstatedir})", [localstate directory])
AC_DEFINE_UNQUOTED([PACKAGE_FEATURES], "${PACKAGE_FEATURES}", [quarterback built-in features])
# version parsing (for qbconfig.h)
AC_DEFINE_UNQUOTED([QB_VER_MAJOR],
[$(echo "${VERSION}" \
| sed -e 's|^\([[0-9]][[0-9]]*\).*|\1|' \
-e t -e 's|.*|1|')],
[libqb major version])
AC_DEFINE_UNQUOTED([QB_VER_MINOR],
[$(echo "${VERSION}" \
| sed -e 's|^[[0-9]][[0-9]]*\.\([[0-9]][[0-9]]*\).*|\1|' \
-e t -e 's|.*|0|')],
[libqb minor version])
AC_DEFINE_UNQUOTED([QB_VER_MICRO],
[$(echo "${VERSION}" \
| sed -e 's|^[[0-9]][[0-9]]*\.[[0-9]][[0-9]]*\.\([[0-9]][[0-9]]*\).*|\1|' \
-e t -e 's|.*|0|')],
[libqb patch version])
AC_DEFINE_UNQUOTED([QB_VER_REST],
[$(echo "${VERSION}" \
| sed -e 's|^[[0-9]][[0-9]]*\(\.[[0-9]][[0-9]]*\)\{0,2\}\(.*\)|"\2"|' \
-e t -e 's|.*|""|')],
[libqb patch version])
AC_CONFIG_FILES([Makefile
include/Makefile
include/qb/Makefile

View File

@ -26,7 +26,7 @@ if HAVE_DOXYGEN
inc_dir = $(top_srcdir)/include/qb
public_headers = $(sort $(patsubst %.in,%,$(subst $(inc_dir)/,,$(shell \
printf 'include $(inc_dir)/Makefile.am\n\n%%.var:\n\t@echo $$($$*)' \
| ${MAKE} --no-print-directory -f- inst_HEADERS.var \
| MAKEFLAGS= ${MAKE} --no-print-directory -f- inst_HEADERS.var \
|| echo $(inc_dir)/qb*.h*))))
public_headers_omit = qbconfig.h
public_headers_pick = $(filter-out $(public_headers_omit),$(public_headers) )

View File

@ -327,7 +327,7 @@ dist_man_MANS = man8/qb-blackbox.8
@HAVE_DOXYGEN_TRUE@inc_dir = $(top_srcdir)/include/qb
@HAVE_DOXYGEN_TRUE@public_headers = $(sort $(patsubst %.in,%,$(subst $(inc_dir)/,,$(shell \
@HAVE_DOXYGEN_TRUE@ printf 'include $(inc_dir)/Makefile.am\n\n%%.var:\n\t@echo $$($$*)' \
@HAVE_DOXYGEN_TRUE@ | ${MAKE} --no-print-directory -f- inst_HEADERS.var \
@HAVE_DOXYGEN_TRUE@ | MAKEFLAGS= ${MAKE} --no-print-directory -f- inst_HEADERS.var \
@HAVE_DOXYGEN_TRUE@ || echo $(inc_dir)/qb*.h*))))
@HAVE_DOXYGEN_TRUE@public_headers_omit = qbconfig.h

View File

@ -38,7 +38,7 @@ PROJECT_NAME = libqb
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 1.0
PROJECT_NUMBER = 1.0.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

View File

@ -3,9 +3,11 @@
*
* @section overview Overview
*
* libqb is a thread-safe library with the primary purpose of providing
* high-performance, reusable features for client-server architecture,
* such as logging, tracing, inter-process communication (IPC), and polling.
* libqb is a library with the primary purpose of providing high-performance,
* reusable features for client-server architecture, such as logging, tracing,
* inter-process communication (IPC), and polling. Except for some documented
* anti-pattern use cases regarding IPC communication and logging, it is deemed
* thread-safe.
*
* We don't intend this to be an all-encompassing library, but instead
* provide very specially focused APIs that are highly tuned for maximum
@ -92,6 +94,13 @@
* For performance, QB_IPC_SHM (shared memory) is recommended. It is tuned for
* very high performance.
*
* @par Multithreading
* As of current implementation, there are not many guarantees about ipc system
* being thread-safe. What remains there is mostly owing to the encapsulation
* of independent IPC connections. Therefore it is highly recommended to have
* a single one pushed throughout its lifecycle just with a single thread;
* anything else would likely warrant external synchronization enforcement.
*
* @par Client API
* @copydoc qbipcc.h
* @see qbipcc.h

View File

@ -1,4 +1,4 @@
.TH "qbarray.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbarray.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME

View File

@ -1,4 +1,4 @@
.TH "qbatomic.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbatomic.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME

View File

@ -1,8 +1,11 @@
.TH "qbdefs.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbdefs.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME
qbdefs.h \-
.PP
These are some convience macros and defines\&.
.SH SYNOPSIS
.br
.PP
@ -43,6 +46,18 @@ qbdefs.h \-
.RI "#define \fBqb_bit_is_clear\fP(barray, bit) (!(barray & \fBqb_bit_value\fP(bit)))"
.br
.ti -1c
.RI "#define \fBQB_PP_JOIN_\fP(a, b) a##b"
.br
.ti -1c
.RI "#define \fBQB_PP_JOIN\fP(a, b) \fBQB_PP_JOIN_\fP(a, b)"
.br
.ti -1c
.RI "#define \fBQB_PP_STRINGIFY_\fP(arg) #arg"
.br
.ti -1c
.RI "#define \fBQB_PP_STRINGIFY\fP(arg) \fBQB_PP_STRINGIFY_\fP(arg)"
.br
.ti -1c
.RI "#define \fBHZ\fP 100 /* 10ms */"
.br
.ti -1c
@ -75,14 +90,16 @@ qbdefs.h \-
.in -1c
.SH "Detailed Description"
.PP
These are some convience macros and defines\&.
.PP
\fBAuthor:\fP
.RS 4
Angus Salkeld asalkeld@redhat.com
Angus Salkeld asalkeld@redhat.com
.RE
.PP
These are some convience macros and defines\&.
.SH "Macro Definition Documentation"
.PP
.SS "#define HZ 100 /* 10ms */"
@ -111,6 +128,14 @@ These are some convience macros and defines\&.
.SS "#define QB_MIN(a, b) (((a) < (b)) ? (a) : (b))"
.SS "#define QB_PP_JOIN(a, b) \fBQB_PP_JOIN_\fP(a, b)"
.SS "#define QB_PP_JOIN_(a, b) a##b"
.SS "#define QB_PP_STRINGIFY(arg) \fBQB_PP_STRINGIFY_\fP(arg)"
.SS "#define QB_PP_STRINGIFY_(arg) #arg"
.SS "#define QB_ROUNDUP(x, y) ((((x) + ((y) - 1)) / (y)) * (y))"
.SS "#define QB_TIME_MS_IN_SEC 1000ULL"

View File

@ -1,4 +1,4 @@
.TH "qbhdb.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbhdb.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME
@ -186,7 +186,7 @@ Create a new handle\&.
.PP
\fBReturns:\fP
.RS 4
(0 == ok, -errno faliure)
(0 == ok, -errno failure)
.RE
.PP
@ -204,7 +204,7 @@ Request the destruction of the object\&. When the refcount is 0, it will be dest
.PP
\fBReturns:\fP
.RS 4
(0 == ok, -errno faliure)
(0 == ok, -errno failure)
.RE
.PP
@ -224,7 +224,7 @@ Get the instance associated with this handle and increase it's refcount\&.
.PP
\fBReturns:\fP
.RS 4
(0 == ok, -errno faliure)
(0 == ok, -errno failure)
.RE
.PP
@ -244,7 +244,7 @@ Get the instance associated with this handle and increase it's refcount\&.
.PP
\fBReturns:\fP
.RS 4
(0 == ok, -errno faliure)
(0 == ok, -errno failure)
.RE
.PP
@ -262,7 +262,7 @@ Put the instance associated with this handle and decrease it's refcount\&.
.PP
\fBReturns:\fP
.RS 4
(0 == ok, -errno faliure)
(0 == ok, -errno failure)
.RE
.PP
@ -280,7 +280,7 @@ Get the current refcount\&.
.PP
\fBReturns:\fP
.RS 4
(>= 0 is the refcount, -errno faliure)
(>= 0 is the refcount, -errno failure)
.RE
.PP
@ -300,7 +300,7 @@ Get the next object and increament it's refcount\&. Remember to call \fBqb_hdb_h
.PP
\fBReturns:\fP
.RS 4
(0 == ok, -errno faliure)
(0 == ok, -errno failure)
.RE
.PP

View File

@ -1,4 +1,4 @@
.TH "qbipc_common.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbipc_common.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME

View File

@ -1,4 +1,4 @@
.TH "qbipcc.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbipcc.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME
@ -9,15 +9,9 @@ Client IPC API\&.
.SH SYNOPSIS
.br
.PP
\fC#include <qb/qbconfig\&.h>\fP
\fC#include <sys/types\&.h>\fP
.br
\fC#include <pthread\&.h>\fP
.br
\fC#include <sys/poll\&.h>\fP
.br
\fC#include <sys/socket\&.h>\fP
.br
\fC#include <qb/qbhdb\&.h>\fP
\fC#include <sys/uio\&.h>\fP
.br
\fC#include <qb/qbipc_common\&.h>\fP
.br
@ -112,7 +106,7 @@ The function \fBqb_ipcc_sendv()\fP sends an iovector request\&. The function \fB
.PP
\fBAsynchronous events from the server\fP
.RS 4
The \fBqb_ipcc_event_recv()\fP function receives an out-of-band asyncronous message\&. The asynchronous messages are queued and can provide very high out-of-band performance\&. To determine when to call \fBqb_ipcc_event_recv()\fP the \fBqb_ipcc_fd_get()\fP call is used to obtain a file descriptor used in the poll() or select() system calls\&.
The \fBqb_ipcc_event_recv()\fP function receives an out-of-band asynchronous message\&. The asynchronous messages are queued and can provide very high out-of-band performance\&. To determine when to call \fBqb_ipcc_event_recv()\fP the \fBqb_ipcc_fd_get()\fP call is used to obtain a file descriptor used in the poll() or select() system calls\&.
.RE
.PP

View File

@ -1,4 +1,4 @@
.TH "qbipcs.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbipcs.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME
@ -9,14 +9,12 @@ Server IPC API\&.
.SH SYNOPSIS
.br
.PP
\fC#include <stdlib\&.h>\fP
\fC#include <sys/types\&.h>\fP
.br
\fC#include <sys/uio\&.h>\fP
.br
\fC#include <qb/qbipc_common\&.h>\fP
.br
\fC#include <qb/qbhdb\&.h>\fP
.br
\fC#include <qb/qbloop\&.h>\fP
.br
@ -141,11 +139,11 @@ Server IPC API\&.
.ti -1c
.RI "ssize_t \fBqb_ipcs_event_send\fP (\fBqb_ipcs_connection_t\fP *c, const void *data, size_t size)"
.br
.RI "\fISend an asyncronous event message to the client\&. \fP"
.RI "\fISend an asynchronous event message to the client\&. \fP"
.ti -1c
.RI "ssize_t \fBqb_ipcs_event_sendv\fP (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_t iov_len)"
.br
.RI "\fISend an asyncronous event message to the client\&. \fP"
.RI "\fISend an asynchronous event message to the client\&. \fP"
.ti -1c
.RI "void \fBqb_ipcs_connection_ref\fP (\fBqb_ipcs_connection_t\fP *c)"
.br
@ -217,7 +215,7 @@ Server IPC API\&.
.SS "typedef int32_t(* qb_ipcs_connection_accept_fn)(\fBqb_ipcs_connection_t\fP *c, uid_t uid, gid_t gid)"
.PP
This callback is to check whether you want to accept a new connection\&. The type of checks you should do are authentication, service availabilty or process resource constraints\&.
This callback is to check whether you want to accept a new connection\&. The type of checks you should do are authentication, service availability or process resource constraints\&.
.PP
\fBReturns:\fP
.RS 4
@ -576,7 +574,7 @@ Setting this will force client connections to use at least max_buf_size bytes as
.SS "ssize_t qb_ipcs_event_send (\fBqb_ipcs_connection_t\fP *c, const void *data, size_tsize)"
.PP
Send an asyncronous event message to the client\&.
Send an asynchronous event message to the client\&.
.PP
\fBParameters:\fP
.RS 4
@ -603,7 +601,7 @@ When send returns -EMSGSIZE, this means the msg is too large and will never succ
.SS "ssize_t qb_ipcs_event_sendv (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_tiov_len)"
.PP
Send an asyncronous event message to the client\&.
Send an asynchronous event message to the client\&.
.PP
\fBParameters:\fP
.RS 4

View File

@ -1,4 +1,4 @@
.TH "qblist.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qblist.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME

View File

@ -1,4 +1,4 @@
.TH "qblog.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qblog.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME
@ -52,6 +52,24 @@ The logging API provides four main parts (basics, filtering, threading & blackbo
.RI "#define \fBQB_LOG_STRERROR_MAX_LEN\fP 128"
.br
.ti -1c
.RI "#define \fBQB_ATTR_SECTION\fP __verbose /* conforms to C ident\&. */"
.br
.ti -1c
.RI "#define \fBQB_ATTR_SECTION_STR\fP \fBQB_PP_STRINGIFY\fP(\fBQB_ATTR_SECTION\fP)"
.br
.ti -1c
.RI "#define \fBQB_ATTR_SECTION_START\fP \fBQB_PP_JOIN\fP(__start_, \fBQB_ATTR_SECTION\fP)"
.br
.ti -1c
.RI "#define \fBQB_ATTR_SECTION_STOP\fP \fBQB_PP_JOIN\fP(__stop_, \fBQB_ATTR_SECTION\fP)"
.br
.ti -1c
.RI "#define \fBQB_ATTR_SECTION_START_STR\fP \fBQB_PP_STRINGIFY\fP(\fBQB_ATTR_SECTION_START\fP)"
.br
.ti -1c
.RI "#define \fBQB_ATTR_SECTION_STOP_STR\fP \fBQB_PP_STRINGIFY\fP(\fBQB_ATTR_SECTION_STOP\fP)"
.br
.ti -1c
.RI "#define \fBQB_LOG_INIT_DATA\fP(name)"
.br
.ti -1c
@ -278,10 +296,10 @@ The logging API provides four main parts (basics, filtering, threading & blackbo
.RI "uint32_t \fBtags\fP"
.br
.ti -1c
.RI "struct \fBqb_log_callsite\fP \fB__start___verbose\fP []"
.RI "struct \fBqb_log_callsite\fP \fBQB_ATTR_SECTION_START\fP []"
.br
.ti -1c
.RI "struct \fBqb_log_callsite\fP \fB__stop___verbose\fP []"
.RI "struct \fBqb_log_callsite\fP \fBQB_ATTR_SECTION_STOP\fP []"
.br
.ti -1c
.RI "enum \fBqb_log_target_slot\fP \fB__attribute__\fP"
@ -418,7 +436,7 @@ So to make all logs with the substring 'ringbuffer' go to stderr, do the followi
.PP
\fBThread safe non-blocking logging\&.\fP
.RS 4
Logging is only thread safe when threaded logging is in use\&. If you plan on logging from multiple threads, you must initialize libqb's logger thread and use qg_log_filter_ctl to set the QB_LOG_CONF_THREADED flag on all the logging targets in use\&.
Logging is only thread safe when threaded logging is in use\&. If you plan on logging from multiple threads, you must initialize libqb's logger thread and use qb_log_filter_ctl to set the QB_LOG_CONF_THREADED flag on all the logging targets in use\&.
.RE
.PP
To achieve non-blocking logging, so that any calls to write() or syslog() will not hold up your program, you can use threaded logging as well\&.
@ -526,6 +544,18 @@ You can tag messages using the second argument to \fBqb_logt()\fP or by using \f
.PP
.SS "#define LOG_TRACE (LOG_DEBUG + 1)"
.SS "#define QB_ATTR_SECTION __verbose /* conforms to C ident\&. */"
.SS "#define QB_ATTR_SECTION_START \fBQB_PP_JOIN\fP(__start_, \fBQB_ATTR_SECTION\fP)"
.SS "#define QB_ATTR_SECTION_START_STR \fBQB_PP_STRINGIFY\fP(\fBQB_ATTR_SECTION_START\fP)"
.SS "#define QB_ATTR_SECTION_STOP \fBQB_PP_JOIN\fP(__stop_, \fBQB_ATTR_SECTION\fP)"
.SS "#define QB_ATTR_SECTION_STOP_STR \fBQB_PP_STRINGIFY\fP(\fBQB_ATTR_SECTION_STOP\fP)"
.SS "#define QB_ATTR_SECTION_STR \fBQB_PP_STRINGIFY\fP(\fBQB_ATTR_SECTION\fP)"
.SS "#define qb_enter() \fBqb_log\fP(\fBLOG_TRACE\fP, 'ENTERING %s()', __func__)"
.SS "#define qb_leave() \fBqb_log\fP(\fBLOG_TRACE\fP, 'LEAVING %s()', __func__)"
@ -553,8 +583,9 @@ This is the main function to generate a log message\&.
\fBValue:\fP
.PP
.nf
void name(void); \
void name(void) { if (__start___verbose != __stop___verbose) {assert(1);} } \
void name(void); \
void name(void) \
{ if (QB_ATTR_SECTION_START == QB_ATTR_SECTION_STOP) assert(0); } \
void __attribute__ ((constructor)) name(void);
.fi
.SS "#define QB_LOG_MAX_LEN 512"
@ -571,7 +602,7 @@ void name(void); \
.nf
do { \
static struct qb_log_callsite descriptor \
__attribute__((section("__verbose"), aligned(8))) = \
__attribute__((section(QB_ATTR_SECTION_STR), aligned(8))) = \
{ __func__, __FILE__, fmt, priority, __LINE__, 0, tags }; \\
qb_log_real_(&descriptor, ##args); \
} while(0)
@ -781,8 +812,8 @@ Dump the callsite info to stdout\&.
If you are using dynamically loadable modules via dlopen() and you load them after \fBqb_log_init()\fP then after you load the module you will need to do the following to get the filters to work in that module:
.PP
.nf
* _start = dlsym (dl_handle, "__start___verbose");
* _stop = dlsym (dl_handle, "__stop___verbose");
* _start = dlsym (dl_handle, QB_ATTR_SECTION_START_STR);
* _stop = dlsym (dl_handle, QB_ATTR_SECTION_STOP_STR);
* qb_log_callsites_register(_start, _stop);
*
@ -1021,10 +1052,6 @@ Start the logging pthread\&.
.PP
.SS "enum \fBqb_log_target_slot\fP __attribute__"
.SS "struct \fBqb_log_callsite\fP __start___verbose[]"
.SS "struct \fBqb_log_callsite\fP __stop___verbose[]"
.SS "const char* filename"
.SS "const char* format"
@ -1035,6 +1062,10 @@ Start the logging pthread\&.
.SS "uint8_t priority"
.SS "struct \fBqb_log_callsite\fP QB_ATTR_SECTION_START[]"
.SS "struct \fBqb_log_callsite\fP QB_ATTR_SECTION_STOP[]"
.SS "uint32_t tags"
.SS "uint32_t targets"

View File

@ -1,4 +1,4 @@
.TH "qbloop.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbloop.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME
@ -13,6 +13,8 @@ Main loop manages timers, jobs and polling sockets\&.
.br
\fC#include <stdint\&.h>\fP
.br
\fC#include <poll\&.h>\fP
.br
.SS "Typedefs"

View File

@ -1,4 +1,4 @@
.TH "qbmap.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbmap.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME

View File

@ -1,4 +1,4 @@
.TH "qbrb.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbrb.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME

View File

@ -1,4 +1,4 @@
.TH "qbutil.h" 3 "Fri Apr 1 2016" "Version 1.0" "libqb" \" -*- nroff -*-
.TH "qbutil.h" 3 "Thu Nov 24 2016" "Version 1.0.1" "libqb" \" -*- nroff -*-
.ad l
.nh
.SH NAME

View File

@ -21,6 +21,7 @@
#include "os_base.h"
#include <signal.h>
#include <qb/qbarray.h>
#include <qb/qbdefs.h>
#include <qb/qbutil.h>
#include <qb/qblog.h>

View File

@ -21,6 +21,9 @@
/* Define to 1 if your system has a working `chown' function. */
#undef HAVE_CHOWN
/* Define to 1 if clock_getres(CLOCK_MONOTONIC, &ts) works */
#undef HAVE_CLOCK_GETRES_MONOTONIC
/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
@ -43,6 +46,9 @@
/* Define to 1 if you have the <errno.h> header file. */
#undef HAVE_ERRNO_H
/* have failure injection */
#undef HAVE_FAILURE_INJECTION
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
@ -124,6 +130,9 @@
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the `openat' function. */
#undef HAVE_OPENAT
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
@ -145,12 +154,6 @@
/* Define to 1 if you have the `random' function. */
#undef HAVE_RANDOM
/* Define to 1 if you have the `sched_get_priority_max' function. */
#undef HAVE_SCHED_GET_PRIORITY_MAX
/* Define to 1 if you have the `sched_setscheduler' function. */
#undef HAVE_SCHED_SETSCHEDULER
/* Define to 1 if you have the `semtimedop' function. */
#undef HAVE_SEMTIMEDOP
@ -280,6 +283,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `unlinkat' function. */
#undef HAVE_UNLINKAT
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
@ -362,6 +368,9 @@
/* shared and fixed mmap must align on 16k */
#undef QB_FORCE_SHM_ALIGN
/* Compiling for GNU/Hurd platform */
#undef QB_GNU
/* Enabling code using __attribute__((section)) */
#undef QB_HAVE_ATTRIBUTE_SECTION
@ -371,6 +380,18 @@
/* Compiling for Solaris platform */
#undef QB_SOLARIS
/* libqb major version */
#undef QB_VER_MAJOR
/* libqb patch version */
#undef QB_VER_MICRO
/* libqb minor version */
#undef QB_VER_MINOR
/* libqb patch version */
#undef QB_VER_REST
/* Socket directory */
#undef SOCKETDIR

View File

@ -23,10 +23,26 @@
#ifndef QB_CONFIG_H_DEFINED
#define QB_CONFIG_H_DEFINED
#include <qb/qbdefs.h> /* QB_PP_STRINGIFY */
/* need atomic memory barrier */
#define QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED 1
/* Enabling code using __attribute__((section)) */
#define QB_HAVE_ATTRIBUTE_SECTION 1
/* versioning info: MAJOR, MINOR, MICRO, and REST components */
#define QB_VER_MAJOR 1
#define QB_VER_MINOR 0
#define QB_VER_MICRO 1
#define QB_VER_REST ""
#define QB_VER_STR \
QB_PP_STRINGIFY(QB_VER_MAJOR) \
"." \
QB_PP_STRINGIFY(QB_VER_MINOR) \
"." \
QB_PP_STRINGIFY(QB_VER_MICRO) \
QB_VER_REST
#endif /* QB_CONFIG_H_DEFINED */

View File

@ -22,10 +22,26 @@
#ifndef QB_CONFIG_H_DEFINED
#define QB_CONFIG_H_DEFINED
#include <qb/qbdefs.h> /* QB_PP_STRINGIFY */
/* need atomic memory barrier */
#undef QB_ATOMIC_OP_MEMORY_BARRIER_NEEDED
/* Enabling code using __attribute__((section)) */
#undef QB_HAVE_ATTRIBUTE_SECTION
/* versioning info: MAJOR, MINOR, MICRO, and REST components */
#undef QB_VER_MAJOR
#undef QB_VER_MINOR
#undef QB_VER_MICRO
#undef QB_VER_REST
#define QB_VER_STR \
QB_PP_STRINGIFY(QB_VER_MAJOR) \
"." \
QB_PP_STRINGIFY(QB_VER_MINOR) \
"." \
QB_PP_STRINGIFY(QB_VER_MICRO) \
QB_VER_REST
#endif /* QB_CONFIG_H_DEFINED */

View File

@ -28,9 +28,9 @@ extern "C" {
/**
* @file qbdefs.h
* @author Angus Salkeld <asalkeld@redhat.com>
*
* These are some convience macros and defines.
*
* @author Angus Salkeld <asalkeld@redhat.com>
*/
/*
@ -56,6 +56,15 @@ extern "C" {
#define qb_bit_is_set(barray, bit) (barray & qb_bit_value(bit))
#define qb_bit_is_clear(barray, bit) (!(barray & qb_bit_value(bit)))
/*
* wrappers over preprocessor operators
*/
#define QB_PP_JOIN_(a, b) a##b
#define QB_PP_JOIN(a, b) QB_PP_JOIN_(a, b)
#define QB_PP_STRINGIFY_(arg) #arg
#define QB_PP_STRINGIFY(arg) QB_PP_STRINGIFY_(arg)
/*
* handy time based converters.

View File

@ -99,7 +99,7 @@ void qb_hdb_destroy(struct qb_hdb *hdb);
* @param hdb the database instance
* @param instance_size size of the object to malloc
* @param handle_id_out new handle
* @return (0 == ok, -errno faliure)
* @return (0 == ok, -errno failure)
*/
int32_t qb_hdb_handle_create(struct qb_hdb *hdb, int32_t instance_size,
qb_handle_t * handle_id_out);
@ -108,7 +108,7 @@ int32_t qb_hdb_handle_create(struct qb_hdb *hdb, int32_t instance_size,
* @param handle_in the handle
* @param hdb the database instance
* @param instance (out) pointer to the desired object.
* @return (0 == ok, -errno faliure)
* @return (0 == ok, -errno failure)
*/
int32_t qb_hdb_handle_get(struct qb_hdb *hdb, qb_handle_t handle_in,
void **instance);
@ -117,7 +117,7 @@ int32_t qb_hdb_handle_get(struct qb_hdb *hdb, qb_handle_t handle_in,
* @param handle_in the handle
* @param hdb the database instance
* @param instance (out) pointer to the desired object.
* @return (0 == ok, -errno faliure)
* @return (0 == ok, -errno failure)
*/
int32_t qb_hdb_handle_get_always(struct qb_hdb *hdb, qb_handle_t handle_in,
void **instance);
@ -125,7 +125,7 @@ int32_t qb_hdb_handle_get_always(struct qb_hdb *hdb, qb_handle_t handle_in,
* Put the instance associated with this handle and decrease it's refcount.
* @param handle_in the handle
* @param hdb the database instance
* @return (0 == ok, -errno faliure)
* @return (0 == ok, -errno failure)
*/
int32_t qb_hdb_handle_put(struct qb_hdb *hdb, qb_handle_t handle_in);
@ -136,7 +136,7 @@ int32_t qb_hdb_handle_put(struct qb_hdb *hdb, qb_handle_t handle_in);
*
* @param handle_in the handle
* @param hdb the database instance
* @return (0 == ok, -errno faliure)
* @return (0 == ok, -errno failure)
*/
int32_t qb_hdb_handle_destroy(struct qb_hdb *hdb, qb_handle_t handle_in);
@ -144,7 +144,7 @@ int32_t qb_hdb_handle_destroy(struct qb_hdb *hdb, qb_handle_t handle_in);
* Get the current refcount.
* @param handle_in the handle
* @param hdb the database instance
* @return (>= 0 is the refcount, -errno faliure)
* @return (>= 0 is the refcount, -errno failure)
*/
int32_t qb_hdb_handle_refcount_get(struct qb_hdb *hdb, qb_handle_t handle_in);
@ -162,7 +162,7 @@ void qb_hdb_iterator_reset(struct qb_hdb *hdb);
* @param hdb the database instance
* @param handle (out) the handle
* @param instance (out) pointer to the desired object.
* @return (0 == ok, -errno faliure)
* @return (0 == ok, -errno failure)
*/
int32_t qb_hdb_iterator_next(struct qb_hdb *hdb, void **instance,
qb_handle_t * handle);

View File

@ -27,12 +27,9 @@ extern "C" {
#endif
/* *INDENT-ON* */
#include <qb/qbconfig.h>
#include <sys/types.h> /* size_t, ssize_t */
#include <sys/uio.h> /* iovec */
#include <pthread.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <qb/qbhdb.h>
#include <qb/qbipc_common.h>
/**
@ -53,7 +50,7 @@ extern "C" {
* The function qb_ipcc_send() sends an message buffer request.
*
* @par Asynchronous events from the server
* The qb_ipcc_event_recv() function receives an out-of-band asyncronous message.
* The qb_ipcc_event_recv() function receives an out-of-band asynchronous message.
* The asynchronous messages are queued and can provide very high out-of-band performance.
* To determine when to call qb_ipcc_event_recv() the qb_ipcc_fd_get() call is
* used to obtain a file descriptor used in the poll() or select() system calls.

View File

@ -29,11 +29,11 @@ extern "C" {
#endif
/* *INDENT-ON* */
#include <stdlib.h>
#include <sys/uio.h>
#include <qb/qbipc_common.h>
#include <qb/qbhdb.h>
#include <qb/qbloop.h>
#include <sys/types.h> /* size_t, ssize_t */
#include <sys/uio.h> /* iovec */
#include <qb/qbipc_common.h> /* qb_ipc_type */
#include <qb/qbloop.h> /* qb_loop_priority */
/**
* @file qbipcs.h
@ -114,7 +114,7 @@ struct qb_ipcs_poll_handlers {
/**
* This callback is to check whether you want to accept a new connection.
*
* The type of checks you should do are authentication, service availabilty
* The type of checks you should do are authentication, service availability
* or process resource constraints.
* @return 0 to accept or -errno to indicate a failure (sent back to the client)
*
@ -278,7 +278,7 @@ ssize_t qb_ipcs_response_sendv(qb_ipcs_connection_t *c,
const struct iovec * iov, size_t iov_len);
/**
* Send an asyncronous event message to the client.
* Send an asynchronous event message to the client.
*
* @param c connection instance
* @param data the message to send
@ -297,7 +297,7 @@ ssize_t qb_ipcs_event_send(qb_ipcs_connection_t *c, const void *data,
size_t size);
/**
* Send an asyncronous event message to the client.
* Send an asynchronous event message to the client.
*
* @param c connection instance
* @param iov the iovec struct that points to the message to send

View File

@ -138,7 +138,7 @@ extern "C" {
* @par Thread safe non-blocking logging.
* Logging is only thread safe when threaded logging is in use. If you plan
* on logging from multiple threads, you must initialize libqb's logger thread
* and use qg_log_filter_ctl to set the QB_LOG_CONF_THREADED flag on all the
* and use qb_log_filter_ctl to set the QB_LOG_CONF_THREADED flag on all the
* logging targets in use.
*
* To achieve non-blocking logging, so that any calls to write() or syslog()
@ -253,14 +253,26 @@ struct qb_log_callsite {
typedef void (*qb_log_filter_fn)(struct qb_log_callsite * cs);
/* will be assigned by ld linker magic */
/* will be assigned by linker magic (assuming linker supports that):
* https://sourceware.org/binutils/docs/ld/Orphan-Sections.html
*/
#ifdef QB_HAVE_ATTRIBUTE_SECTION
extern struct qb_log_callsite __start___verbose[];
extern struct qb_log_callsite __stop___verbose[];
#define QB_LOG_INIT_DATA(name) \
void name(void); \
void name(void) { if (__start___verbose != __stop___verbose) {assert(1);} } \
#define QB_ATTR_SECTION __verbose /* conforms to C ident. */
#define QB_ATTR_SECTION_STR QB_PP_STRINGIFY(QB_ATTR_SECTION)
#define QB_ATTR_SECTION_START QB_PP_JOIN(__start_, QB_ATTR_SECTION)
#define QB_ATTR_SECTION_STOP QB_PP_JOIN(__stop_, QB_ATTR_SECTION)
#define QB_ATTR_SECTION_START_STR QB_PP_STRINGIFY(QB_ATTR_SECTION_START)
#define QB_ATTR_SECTION_STOP_STR QB_PP_STRINGIFY(QB_ATTR_SECTION_STOP)
extern struct qb_log_callsite QB_ATTR_SECTION_START[];
extern struct qb_log_callsite QB_ATTR_SECTION_STOP[];
/* mere linker sanity check, possible future extension for internal purposes */
#define QB_LOG_INIT_DATA(name) \
void name(void); \
void name(void) \
{ if (QB_ATTR_SECTION_START == QB_ATTR_SECTION_STOP) assert(0); } \
void __attribute__ ((constructor)) name(void);
#else
#define QB_LOG_INIT_DATA(name)
@ -345,7 +357,7 @@ void qb_log_from_external_source_va(const char *function,
#ifdef QB_HAVE_ATTRIBUTE_SECTION
#define qb_logt(priority, tags, fmt, args...) do { \
static struct qb_log_callsite descriptor \
__attribute__((section("__verbose"), aligned(8))) = \
__attribute__((section(QB_ATTR_SECTION_STR), aligned(8))) = \
{ __func__, __FILE__, fmt, priority, __LINE__, 0, tags }; \
qb_log_real_(&descriptor, ##args); \
} while(0)
@ -506,8 +518,8 @@ void qb_log_fini(void);
* you will need to do the following to get the filters to work
* in that module:
* @code
* _start = dlsym (dl_handle, "__start___verbose");
* _stop = dlsym (dl_handle, "__stop___verbose");
* _start = dlsym (dl_handle, QB_ATTR_SECTION_START_STR);
* _stop = dlsym (dl_handle, QB_ATTR_SECTION_STOP_STR);
* qb_log_callsites_register(_start, _stop);
* @endcode
*/

View File

@ -29,6 +29,7 @@ extern "C" {
#include <signal.h>
#include <stdint.h>
#include <poll.h> /* make POLLIN etc. readily available */
/**
* @file qbloop.h

View File

@ -29,7 +29,7 @@ AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
lib_LTLIBRARIES = libqb.la
libqb_la_LDFLAGS = -version-info 18:0:18
libqb_la_LDFLAGS = -version-info 18:1:18
source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \
array.c loop.c loop_poll.c loop_job.c \

View File

@ -561,7 +561,7 @@ noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h \
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
lib_LTLIBRARIES = libqb.la
libqb_la_LDFLAGS = -version-info 18:0:18
libqb_la_LDFLAGS = -version-info 18:1:18
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 \

View File

@ -19,6 +19,7 @@
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#include <poll.h>
#if defined(HAVE_GETPEERUCRED)
#include <ucred.h>

View File

@ -19,6 +19,7 @@
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#include <poll.h>
#include "ipc_int.h"
#include "util_int.h"
@ -28,10 +29,6 @@
#include <qb/qbloop.h>
#include <qb/qbrb.h>
/*
* utility functions
* --------------------------------------------------------
*/
/*
* client functions
* --------------------------------------------------------
@ -39,16 +36,15 @@
static void
qb_ipcc_shm_disconnect(struct qb_ipcc_connection *c)
{
void (*rb_destructor)(struct qb_ringbuffer_s *) = c->is_connected
? qb_rb_close
: qb_rb_force_close;
qb_ipcc_us_sock_close(c->setup.u.us.sock);
if (c->is_connected) {
qb_rb_close(c->request.u.shm.rb);
qb_rb_close(c->response.u.shm.rb);
qb_rb_close(c->event.u.shm.rb);
} else {
qb_rb_force_close(c->request.u.shm.rb);
qb_rb_force_close(c->response.u.shm.rb);
qb_rb_force_close(c->event.u.shm.rb);
}
rb_destructor(qb_rb_lastref_and_ret(&c->request.u.shm.rb));
rb_destructor(qb_rb_lastref_and_ret(&c->response.u.shm.rb));
rb_destructor(qb_rb_lastref_and_ret(&c->event.u.shm.rb));
}
static ssize_t
@ -121,9 +117,7 @@ qb_ipc_shm_peek(struct qb_ipc_one_way *one_way, void **data_out,
static void
qb_ipc_shm_reclaim(struct qb_ipc_one_way *one_way)
{
if (one_way->u.shm.rb != NULL) {
qb_rb_chunk_reclaim(one_way->u.shm.rb);
}
qb_rb_chunk_reclaim(one_way->u.shm.rb);
}
static void
@ -205,10 +199,10 @@ qb_ipcc_shm_connect(struct qb_ipcc_connection * c,
return 0;
cleanup_request_response:
qb_rb_close(c->response.u.shm.rb);
qb_rb_close(qb_rb_lastref_and_ret(&c->response.u.shm.rb));
cleanup_request:
qb_rb_close(c->request.u.shm.rb);
qb_rb_close(qb_rb_lastref_and_ret(&c->request.u.shm.rb));
return_error:
errno = -res;
@ -236,16 +230,13 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c)
if (c->state == QB_IPCS_CONNECTION_SHUTTING_DOWN ||
c->state == QB_IPCS_CONNECTION_ACTIVE) {
if (c->response.u.shm.rb) {
qb_rb_close(c->response.u.shm.rb);
c->response.u.shm.rb = NULL;
qb_rb_close(qb_rb_lastref_and_ret(&c->response.u.shm.rb));
}
if (c->event.u.shm.rb) {
qb_rb_close(c->event.u.shm.rb);
c->event.u.shm.rb = NULL;
qb_rb_close(qb_rb_lastref_and_ret(&c->event.u.shm.rb));
}
if (c->request.u.shm.rb) {
qb_rb_close(c->request.u.shm.rb);
c->request.u.shm.rb = NULL;
qb_rb_close(qb_rb_lastref_and_ret(&c->request.u.shm.rb));
}
}
}
@ -280,7 +271,7 @@ qb_ipcs_shm_rb_open(struct qb_ipcs_connection *c,
return res;
cleanup:
qb_rb_close(ow->u.shm.rb);
qb_rb_close(qb_rb_lastref_and_ret(&ow->u.shm.rb));
return res;
}
@ -333,13 +324,13 @@ qb_ipcs_shm_connect(struct qb_ipcs_service *s,
return 0;
cleanup_request_response_event:
qb_rb_close(c->event.u.shm.rb);
qb_rb_close(qb_rb_lastref_and_ret(&c->event.u.shm.rb));
cleanup_request_response:
qb_rb_close(c->response.u.shm.rb);
qb_rb_close(qb_rb_lastref_and_ret(&c->response.u.shm.rb));
cleanup_request:
qb_rb_close(c->request.u.shm.rb);
qb_rb_close(qb_rb_lastref_and_ret(&c->request.u.shm.rb));
cleanup:
r->hdr.error = res;

View File

@ -19,6 +19,7 @@
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#include <poll.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
@ -118,7 +119,7 @@ set_sock_size(int sockfd, size_t 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
* actually send a message that large unless we explicitly 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) {

View File

@ -19,6 +19,7 @@
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#include <poll.h>
#include "ipc_int.h"
#include "util_int.h"

View File

@ -19,6 +19,7 @@
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#include <poll.h>
#include "util_int.h"
#include "ipc_int.h"

View File

@ -352,8 +352,10 @@ qb_log_callsite_get(const char *function,
_custom_filter_fn(cs);
}
pthread_rwlock_unlock(&_listlock);
} else if (cs->tags != tags) {
cs->tags = tags;
} else {
if (tags && cs->tags != tags) {
cs->tags = tags;
}
if (_custom_filter_fn) {
_custom_filter_fn(cs);
}
@ -800,13 +802,13 @@ _log_so_walk_dlnames(void)
goto done;
}
start = dlsym(handle, "__start___verbose");
start = dlsym(handle, QB_ATTR_SECTION_START_STR);
error = dlerror();
if (error) {
goto done;
}
stop = dlsym(handle, "__stop___verbose");
stop = dlsym(handle, QB_ATTR_SECTION_STOP_STR);
error = dlerror();
if (error) {
goto done;
@ -868,7 +870,7 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority)
qb_log_dcs_init();
#ifdef QB_HAVE_ATTRIBUTE_SECTION
qb_log_callsites_register(__start___verbose, __stop___verbose);
qb_log_callsites_register(QB_ATTR_SECTION_START, QB_ATTR_SECTION_STOP);
dl_iterate_phdr(_log_so_walk_callback, NULL);
_log_so_walk_dlnames();
#endif /* QB_HAVE_ATTRIBUTE_SECTION */

View File

@ -23,6 +23,7 @@
#include <qb/qbrb.h>
#include "util_int.h"
#include "log_int.h"
#include "ringbuffer_int.h"
#define BB_MIN_ENTRY_SIZE (4 * sizeof(uint32_t) +\
sizeof(uint8_t) +\
@ -76,8 +77,9 @@ _blackbox_vlogger(int32_t target,
if (chunk == NULL) {
/* something bad has happened. abort blackbox logging */
qb_util_perror(LOG_ERR, "Blackbox allocation error, aborting blackbox log %s", t->filename);
qb_rb_close(t->instance);
t->instance = NULL;
qb_rb_close(qb_rb_lastref_and_ret(
(struct qb_ringbuffer_s **) &t->instance
));
return;
}
@ -132,10 +134,9 @@ _blackbox_close(int32_t target)
{
struct qb_log_target *t = qb_log_target_get(target);
if (t->instance) {
qb_rb_close(t->instance);
t->instance = NULL;
}
qb_rb_close(qb_rb_lastref_and_ret(
(struct qb_ringbuffer_s **) &t->instance
));
}
int32_t

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011 Red Hat, Inc.
* Copyright (C) 2011,2016 Red Hat, Inc.
*
* All rights reserved.
*
@ -536,6 +536,30 @@ reprocess:
format++;
}
goto reprocess;
case 'z':
format++;
if (sizeof(size_t) == sizeof(long long)) {
type_longlong = QB_TRUE;
} else {
type_long = QB_TRUE;
}
goto reprocess;
case 't':
format++;
if (sizeof(ptrdiff_t) == sizeof(long long)) {
type_longlong = QB_TRUE;
} else {
type_long = QB_TRUE;
}
goto reprocess;
case 'j':
format++;
if (sizeof(intmax_t) == sizeof(long long)) {
type_longlong = QB_TRUE;
} else {
type_long = QB_TRUE;
}
goto reprocess;
case 'd': /* int argument */
case 'i': /* int argument */
case 'o': /* unsigned int argument */
@ -604,9 +628,10 @@ reprocess:
int arg_int;
unsigned char arg_char;
if (location + sizeof (unsigned int) > max_len) {
if (location + sizeof (unsigned char) > max_len) {
return max_len;
}
/* va_arg only takes fully promoted types */
arg_int = va_arg(ap, unsigned int);
arg_char = (unsigned char)arg_int;
memcpy (&serialize[location], &arg_char, sizeof (unsigned char));
@ -737,6 +762,35 @@ reprocess:
type_longlong = QB_TRUE;
}
goto reprocess;
case 'z':
fmt[fmt_pos++] = *format;
format++;
if (sizeof(size_t) == sizeof(long long)) {
type_long = QB_FALSE;
type_longlong = QB_TRUE;
} else {
type_longlong = QB_FALSE;
type_long = QB_TRUE;
}
goto reprocess;
case 't':
fmt[fmt_pos++] = *format;
format++;
if (sizeof(ptrdiff_t) == sizeof(long long)) {
type_longlong = QB_TRUE;
} else {
type_long = QB_TRUE;
}
goto reprocess;
case 'j':
fmt[fmt_pos++] = *format;
format++;
if (sizeof(intmax_t) == sizeof(long long)) {
type_longlong = QB_TRUE;
} else {
type_long = QB_TRUE;
}
goto reprocess;
case 'd': /* int argument */
case 'i': /* int argument */
case 'o': /* unsigned int argument */

View File

@ -48,9 +48,9 @@ static int logt_sched_param_queued = QB_FALSE;
static int logt_sched_policy;
#if defined(HAVE_PTHREAD_SETSCHEDPARAM) && defined(HAVE_SCHED_GET_PRIORITY_MAX)
#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
static struct sched_param logt_sched_param;
#endif /* HAVE_PTHREAD_SETSCHEDPARAM && HAVE_SCHED_GET_PRIORITY_MAX */
#endif /* HAVE_PTHREAD_SETSCHEDPARAM */
static pthread_t logt_thread_id = 0;
@ -62,9 +62,7 @@ qb_logt_worker_thread(void *data)
int dropped = 0;
int res;
/*
* Signal wthread_create that the initialization process may continue
*/
/* Signal qb_log_thread_start that the initialization may continue */
sem_post(&logt_thread_start);
for (;;) {
retry_sem_wait:
@ -72,9 +70,7 @@ retry_sem_wait:
if (res == -1 && errno == EINTR) {
goto retry_sem_wait;
} else if (res == -1) {
/*
* This case shouldn't happen
*/
/* This case shouldn't happen */
pthread_exit(NULL);
}
@ -113,7 +109,7 @@ qb_log_thread_priority_set(int32_t policy, int32_t priority)
{
int res = 0;
#if defined(HAVE_PTHREAD_SETSCHEDPARAM) && defined(HAVE_SCHED_GET_PRIORITY_MAX)
#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
logt_sched_policy = policy;
@ -146,6 +142,7 @@ int32_t
qb_log_thread_start(void)
{
int res;
qb_thread_lock_t *wthread_lock;
if (wthread_active) {
return 0;
@ -154,26 +151,32 @@ qb_log_thread_start(void)
wthread_active = QB_TRUE;
sem_init(&logt_thread_start, 0, 0);
sem_init(&logt_print_finished, 0, 0);
errno = 0;
logt_wthread_lock = qb_thread_lock_create(QB_THREAD_LOCK_SHORT);
if (logt_wthread_lock == NULL) {
return errno ? -errno : -1;
}
res = pthread_create(&logt_thread_id, NULL,
qb_logt_worker_thread, NULL);
if (res != 0) {
wthread_active = QB_FALSE;
(void)qb_thread_lock_destroy(logt_wthread_lock);
return -res;
}
sem_wait(&logt_thread_start);
if (logt_sched_param_queued) {
res = qb_log_thread_priority_set(logt_sched_policy,
#if defined(HAVE_PTHREAD_SETSCHEDPARAM)
logt_sched_param.sched_priority);
#else
0);
#endif
if (res != 0) {
goto cleanup_pthread;
}
logt_sched_param_queued = QB_FALSE;
}
logt_wthread_lock = qb_thread_lock_create(QB_THREAD_LOCK_SHORT);
if (logt_wthread_lock == NULL) {
goto cleanup_pthread;
}
return 0;
@ -181,6 +184,12 @@ cleanup_pthread:
wthread_should_exit = QB_TRUE;
sem_post(&logt_print_finished);
pthread_join(logt_thread_id, NULL);
wthread_active = QB_FALSE;
wthread_lock = logt_wthread_lock;
logt_wthread_lock = NULL;
(void)qb_thread_lock_destroy(wthread_lock);
sem_destroy(&logt_print_finished);
sem_destroy(&logt_thread_start);

View File

@ -290,22 +290,7 @@ qb_rb_close(struct qb_ringbuffer_s * rb)
qb_enter();
(void)qb_atomic_int_dec_and_test(&rb->shared_hdr->ref_count);
if (rb->flags & QB_RB_FLAG_CREATE) {
if (rb->notifier.destroy_fn) {
(void)rb->notifier.destroy_fn(rb->notifier.instance);
}
unlink(rb->shared_hdr->data_path);
unlink(rb->shared_hdr->hdr_path);
qb_util_log(LOG_DEBUG,
"Free'ing ringbuffer: %s",
rb->shared_hdr->hdr_path);
} else {
qb_util_log(LOG_DEBUG,
"Closing ringbuffer: %s", rb->shared_hdr->hdr_path);
}
munmap(rb->shared_data, (rb->shared_hdr->word_size * sizeof(uint32_t)) << 1);
munmap(rb->shared_hdr, sizeof(struct qb_ringbuffer_shared_s));
free(rb);
(void)qb_rb_close_helper(rb, rb->flags & QB_RB_FLAG_CREATE, QB_FALSE);
}
void
@ -316,24 +301,8 @@ qb_rb_force_close(struct qb_ringbuffer_s * rb)
}
qb_enter();
if (rb->notifier.destroy_fn) {
(void)rb->notifier.destroy_fn(rb->notifier.instance);
}
errno = 0;
unlink(rb->shared_hdr->data_path);
qb_util_perror(LOG_DEBUG,
"Force free'ing ringbuffer: %s",
rb->shared_hdr->data_path);
errno = 0;
unlink(rb->shared_hdr->hdr_path);
qb_util_perror(LOG_DEBUG,
"Force free'ing ringbuffer: %s",
rb->shared_hdr->hdr_path);
munmap(rb->shared_data, (rb->shared_hdr->word_size * sizeof(uint32_t)) << 1);
munmap(rb->shared_hdr, sizeof(struct qb_ringbuffer_shared_s));
free(rb);
qb_atomic_int_set(&rb->shared_hdr->ref_count, -1);
(void)qb_rb_close_helper(rb, QB_TRUE, QB_TRUE);
}
char *

View File

@ -306,3 +306,93 @@ qb_rb_sem_create(struct qb_ringbuffer_s * rb, uint32_t flags)
}
return rc;
}
/* For qb_rb_close_helper, we need to open directory in read-only
mode and with as lightweight + strict flags as available at
given platform (O_PATH for the former, O_DIRECTORY for the
latter); end result is available as RB_DIR_RO_FLAGS.
*/
#if defined(HAVE_OPENAT) && defined(HAVE_UNLINKAT)
# ifndef O_DIRECTORY
# define RB_DIR_RO_FLAGS1 O_RDONLY
# else
# define RB_DIR_RO_FLAGS1 O_RDONLY|O_DIRECTORY
# endif
# ifndef O_PATH
# define RB_DIR_RO_FLAGS RB_DIR_RO_FLAGS1
# else
# define RB_DIR_RO_FLAGS RB_DIR_RO_FLAGS1|O_PATH
# endif
int32_t
qb_rb_close_helper(struct qb_ringbuffer_s * rb, int32_t unlink_it,
int32_t truncate_fallback)
{
int32_t res = 0, res2 = 0;
uint32_t word_size = rb->shared_hdr->word_size;
char *hdr_path = rb->shared_hdr->hdr_path;
if (unlink_it) {
qb_util_log(LOG_DEBUG, "Free'ing ringbuffer: %s", hdr_path);
if (rb->notifier.destroy_fn) {
(void)rb->notifier.destroy_fn(rb->notifier.instance);
}
} else {
qb_util_log(LOG_DEBUG, "Closing ringbuffer: %s", hdr_path);
hdr_path = NULL;
}
if (unlink_it) {
char *data_path = rb->shared_hdr->data_path;
char *sep = strrchr(data_path, '/');
/* we could modify data_path in-situ, but that would segfault if
we hadn't write permissions to the underlying mmap'd file */
char dir_path[PATH_MAX];
int dirfd;
if (sep != NULL) {
strncpy(dir_path, data_path, sep - data_path);
dir_path[sep - data_path] = '\0';
if ((dirfd = open(dir_path, RB_DIR_RO_FLAGS)) != -1) {
res = qb_sys_unlink_or_truncate_at(dirfd, sep + 1,
truncate_fallback);
/* the dirname part is assumed to be the same */
assert(!strncmp(dir_path, hdr_path, sep - data_path));
sep = hdr_path + (sep - data_path);
/* now, don't touch neither data_path nor hdr_path */
res2 = qb_sys_unlink_or_truncate_at(dirfd, sep + 1,
truncate_fallback);
close(dirfd);
} else {
res = -errno;
qb_util_perror(LOG_DEBUG,
"Cannot open dir: %s", hdr_path);
}
} else {
res = -EINVAL;
qb_util_perror(LOG_DEBUG,
"Not dir-separable path: %s", hdr_path);
}
#else
res = qb_sys_unlink_or_truncate(data_path, truncate_fallback);
res2 = qb_sys_unlink_or_truncate(hdr_path, truncate_fallback);
#endif /* defined(HAVE_OPENAT) && defined(HAVE_UNLINKAT) */
res = res ? res : res2;
hdr_path = NULL;
} /* if (unlink_it) */
if (munmap(rb->shared_data, (word_size * sizeof(uint32_t)) << 1) == -1) {
res = res ? res : -errno;
qb_util_perror(LOG_DEBUG, "Cannot munmap shared_data");
}
if (munmap(rb->shared_hdr, sizeof(struct qb_ringbuffer_shared_s)) == -1) {
res = res ? res : -errno;
qb_util_perror(LOG_DEBUG, "Cannot munmap shared_hdr");
}
free(rb);
return res;
}

View File

@ -34,6 +34,7 @@
#endif
#include "rpl_sem.h"
#include "util_int.h"
#include <qb/qbatomic.h>
#include <qb/qbutil.h>
#include <qb/qbrb.h>
@ -81,6 +82,16 @@ struct qb_ringbuffer_s {
void qb_rb_force_close(qb_ringbuffer_t * rb);
/**
* Helper to munmap, and conditionally unlink the file or possibly truncate it.
* @param rb ringbuffer instance.
* @param unlink_it whether the underlying files should be unlinked.
* @param truncate_fallback whether to truncate the files when unlink fails.
* @return 0 (success) or -errno
*/
int32_t qb_rb_close_helper(struct qb_ringbuffer_s * rb, int32_t unlink_it,
int32_t truncate_fallback);
qb_ringbuffer_t *qb_rb_open_2(const char *name, size_t size, uint32_t flags,
size_t shared_user_data_size,
struct qb_rb_notifier *notifier);
@ -95,4 +106,25 @@ union semun {
};
#endif /* HAVE_SEMUN */
/* This function is to be used to "decorate" argument (with an extra
reference level added) to qb_rb_{force_,}_close() so as to avoid trivial
IPC API misuses such as recv-after-close rather than avoiding races in
multi-threaded applications (although it partially helps there, too);
it's debatable whether that should be fixed at higher level in ipc[cs].c */
static inline struct qb_ringbuffer_s *
qb_rb_lastref_and_ret(struct qb_ringbuffer_s ** rb)
{
struct qb_ringbuffer_s *rb_res = *rb;
if (rb_res == NULL) {
return NULL;
}
*rb = NULL;
/* qb_rb_close will get rid of this "last reference" */
qb_atomic_int_set(&rb_res->shared_hdr->ref_count, 1);
return rb_res;
}
#endif /* _RINGBUFFER_H_ */

View File

@ -255,6 +255,55 @@ qb_sys_fd_nonblock_cloexec_set(int32_t fd)
return res;
}
int32_t
qb_sys_unlink_or_truncate(const char *path, int32_t truncate_fallback)
{
int32_t res = 0;
if (unlink(path) == -1) {
res = errno;
qb_util_perror(LOG_DEBUG,
"Unlinking file: %s",
path);
if (res != ENOENT && truncate_fallback) {
res = errno = 0;
if (truncate(path, 0) == -1) {
res = errno;
qb_util_perror(LOG_DEBUG,
"Truncating file: %s", path);
}
}
}
return -res;
}
#if defined(HAVE_OPENAT) && defined(HAVE_UNLINKAT)
int32_t
qb_sys_unlink_or_truncate_at(int32_t dirfd, const char *path,
int32_t truncate_fallback)
{
int32_t fd, res = 0;
if (unlinkat(dirfd, path, 0) == -1) {
res = errno;
qb_util_perror(LOG_DEBUG,
"Unlinking file at dir: %s", path);
if (res != ENOENT && truncate_fallback) {
res = errno = 0;
if ((fd = openat(dirfd, path, O_WRONLY|O_TRUNC)) == -1) {
res = errno;
qb_util_perror(LOG_DEBUG,
"Truncating file at dir: %s",
path);
} else {
close(fd);
}
}
}
return -res;
}
#endif
void
qb_sigpipe_ctl(enum qb_sigpipe_ctl ctl)
{

View File

@ -169,7 +169,12 @@ qb_util_nano_monotonic_hz(void)
uint64_t nano_monotonic_hz;
struct timespec ts;
#if HAVE_CLOCK_GETRES_MONOTONIC
clock_getres(CLOCK_MONOTONIC, &ts);
#else
if (clock_getres(CLOCK_REALTIME, &ts) != 0)
qb_util_perror(LOG_ERR,"CLOCK_REALTIME");
#endif
nano_monotonic_hz =
QB_TIME_NS_IN_SEC / ((ts.tv_sec * QB_TIME_NS_IN_SEC) + ts.tv_nsec);

View File

@ -83,6 +83,25 @@ int32_t qb_sys_circular_mmap(int32_t fd, void **buf, size_t bytes);
*/
int32_t qb_sys_fd_nonblock_cloexec_set(int32_t fd);
/**
* Try to unlink file, and possibly truncate it as a fallback.
* @param path the file to be unlinked or truncated.
* @param truncate_fallback whether to truncate the file when unlink fails.
* @return 0 (success) or -errno
*/
int32_t qb_sys_unlink_or_truncate(const char *path, int32_t truncate_fallback);
#if defined(HAVE_OPENAT) && defined(HAVE_UNLINKAT)
/**
* Try to unlinkat file, and possibly truncate it as a fallback ("at" variant).
* @param path the file to be unlinked or truncated.
* @param truncate_fallback whether to truncate the file when unlink fails.
* @return 0 (success) or -errno
*/
int32_t qb_sys_unlink_or_truncate_at(int32_t dirfd, const char *path,
int32_t truncate_fallback);
#endif
enum qb_sigpipe_ctl {
QB_SIGPIPE_IGNORE,
QB_SIGPIPE_DEFAULT,

View File

@ -33,7 +33,7 @@ make %{?_smp_mflags}
%if 0%{?with_check}
%check
make check
VERBOSE=1 make check
%endif
%install
@ -47,8 +47,9 @@ rm -rf $RPM_BUILD_ROOT/%{_datadir}/doc/libqb
%files
%doc COPYING
%{_sbindir}/qb-blackbox
%{_libdir}/libqb.so.*
%{_mandir}/man8/qb-blackbox.8.gz
%{_sbindir}/qb-blackbox
%package devel
Summary: Development files for %{name}
@ -65,7 +66,6 @@ developing applications that use %{name}.
%{_libdir}/libqb.so
%{_libdir}/pkgconfig/libqb.pc
%{_mandir}/man3/qb*3*
%{_mandir}/man8/qb-blackbox.8.gz
%changelog
* @date@ Autotools generated version <nobody@nowhere.org> - @version@-1-@numcomm@.@alphatag@.@dirty@

View File

@ -23,7 +23,9 @@ CLEANFILES =
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
noinst_PROGRAMS = bmc bmcpt bms rbreader rbwriter \
bench-log format_compare_speed loop
bench-log format_compare_speed loop print_ver
noinst_HEADERS = check_common.h
format_compare_speed_SOURCES = format_compare_speed.c $(top_builddir)/include/qb/qbutil.h
format_compare_speed_LDADD = $(top_builddir)/lib/libqb.la
@ -50,7 +52,7 @@ loop_LDADD = $(top_builddir)/lib/libqb.la
inc_dir = $(top_srcdir)/include/qb
public_headers = $(sort $(patsubst %.in,%,$(subst $(inc_dir)/,,$(shell \
printf 'include $(inc_dir)/Makefile.am\n\n%%.var:\n\t@echo $$($$*)' \
| ${MAKE} --no-print-directory -f- inst_HEADERS.var \
| MAKEFLAGS= ${MAKE} --no-print-directory -f- inst_HEADERS.var \
|| echo $(inc_dir)/qb*.h*))))
auto_c_files = $(patsubst %.h,auto_check_header_%.c,$(public_headers))
CLEANFILES += $(auto_c_files)
@ -105,8 +107,9 @@ TESTS = array.test map.test rb.test log.test blackbox-segfault.sh loop.test ipc.
resources.log: rb.log log.log ipc.log
check_LTLIBRARIES =
check_PROGRAMS = array.test map.test rb.test log.test loop.test ipc.test util.test crash_test_dummy file_change_bytes
check_SCRIPTS = resources.test blackbox-segfault.sh
dist_check_SCRIPTS = resources.test blackbox-segfault.sh
if HAVE_SLOW_TESTS
TESTS += util.test
@ -138,6 +141,13 @@ loop_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
ipc_test_SOURCES = check_ipc.c $(top_builddir)/include/qb/qbipcc.h $(top_builddir)/include/qb/qbipcs.h
ipc_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
ipc_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
if HAVE_FAILURE_INJECTION
ipc_test_LDADD += _failure_injection.la
check_LTLIBRARIES += _failure_injection.la
_failure_injection_la_SOURCES = _failure_injection.c _failure_injection.h
_failure_injection_la_LDFLAGS = -module
endif
log_test_SOURCES = check_log.c $(top_builddir)/include/qb/qblog.h
log_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
@ -145,7 +155,7 @@ log_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
if HAVE_SYSLOG_TESTS
log_test_LDADD += _syslog_override.la
check_LTLIBRARIES = _syslog_override.la
check_LTLIBRARIES += _syslog_override.la
_syslog_override_la_SOURCES = _syslog_override.c _syslog_override.h
_syslog_override_la_LDFLAGS = -module
endif

View File

@ -14,6 +14,7 @@
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
@ -80,7 +81,7 @@ build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = bmc$(EXEEXT) bmcpt$(EXEEXT) bms$(EXEEXT) \
rbreader$(EXEEXT) rbwriter$(EXEEXT) bench-log$(EXEEXT) \
format_compare_speed$(EXEEXT) loop$(EXEEXT)
format_compare_speed$(EXEEXT) loop$(EXEEXT) print_ver$(EXEEXT)
@HAVE_DICT_WORDS_TRUE@@HAVE_SLOW_TESTS_TRUE@am__append_1 = make-log-test.sh
@HAVE_DICT_WORDS_TRUE@@HAVE_SLOW_TESTS_TRUE@am__append_2 = auto_write_logs.c
@HAVE_DICT_WORDS_TRUE@@HAVE_SLOW_TESTS_TRUE@am__append_3 = auto_write_logs.c
@ -98,10 +99,14 @@ noinst_PROGRAMS = bmc$(EXEEXT) bmcpt$(EXEEXT) bms$(EXEEXT) \
@HAVE_CHECK_TRUE@ file_change_bytes$(EXEEXT) $(am__EXEEXT_1)
@HAVE_CHECK_TRUE@@HAVE_SLOW_TESTS_TRUE@am__append_5 = util.test
@HAVE_CHECK_TRUE@@HAVE_SLOW_TESTS_TRUE@am__append_6 = util.test
@HAVE_CHECK_TRUE@@HAVE_SYSLOG_TESTS_TRUE@am__append_7 = _syslog_override.la
@HAVE_CHECK_TRUE@@HAVE_FAILURE_INJECTION_TRUE@am__append_7 = _failure_injection.la
@HAVE_CHECK_TRUE@@HAVE_FAILURE_INJECTION_TRUE@am__append_8 = _failure_injection.la
@HAVE_CHECK_TRUE@@HAVE_SYSLOG_TESTS_TRUE@am__append_9 = _syslog_override.la
@HAVE_CHECK_TRUE@@HAVE_SYSLOG_TESTS_TRUE@am__append_10 = _syslog_override.la
subdir = tests
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(srcdir)/test.conf.in $(top_srcdir)/build-aux/depcomp \
$(srcdir)/test.conf.in $(am__dist_check_SCRIPTS_DIST) \
$(top_srcdir)/build-aux/depcomp $(noinst_HEADERS) \
$(top_srcdir)/build-aux/test-driver
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@ -115,16 +120,26 @@ CONFIG_HEADER = $(top_builddir)/include/config.h \
$(top_builddir)/include/qb/qbconfig.h
CONFIG_CLEAN_FILES = test.conf
CONFIG_CLEAN_VPATH_FILES =
_failure_injection_la_LIBADD =
am___failure_injection_la_SOURCES_DIST = _failure_injection.c \
_failure_injection.h
@HAVE_CHECK_TRUE@@HAVE_FAILURE_INJECTION_TRUE@am__failure_injection_la_OBJECTS = _failure_injection.lo
_failure_injection_la_OBJECTS = $(am__failure_injection_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
_failure_injection_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(_failure_injection_la_LDFLAGS) \
$(LDFLAGS) -o $@
@HAVE_CHECK_TRUE@@HAVE_FAILURE_INJECTION_TRUE@am__failure_injection_la_rpath =
_syslog_override_la_LIBADD =
am___syslog_override_la_SOURCES_DIST = _syslog_override.c \
_syslog_override.h
@HAVE_CHECK_TRUE@@HAVE_SYSLOG_TESTS_TRUE@am__syslog_override_la_OBJECTS = \
@HAVE_CHECK_TRUE@@HAVE_SYSLOG_TESTS_TRUE@ _syslog_override.lo
_syslog_override_la_OBJECTS = $(am__syslog_override_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
_syslog_override_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
$(AM_CFLAGS) $(CFLAGS) $(_syslog_override_la_LDFLAGS) \
@ -182,7 +197,8 @@ am__ipc_test_SOURCES_DIST = check_ipc.c \
$(top_builddir)/include/qb/qbipcs.h
@HAVE_CHECK_TRUE@am_ipc_test_OBJECTS = ipc_test-check_ipc.$(OBJEXT)
ipc_test_OBJECTS = $(am_ipc_test_OBJECTS)
@HAVE_CHECK_TRUE@ipc_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la
@HAVE_CHECK_TRUE@ipc_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \
@HAVE_CHECK_TRUE@ $(am__append_7)
ipc_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(ipc_test_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
@ -191,7 +207,7 @@ am__log_test_SOURCES_DIST = check_log.c \
@HAVE_CHECK_TRUE@am_log_test_OBJECTS = log_test-check_log.$(OBJEXT)
log_test_OBJECTS = $(am_log_test_OBJECTS)
@HAVE_CHECK_TRUE@log_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \
@HAVE_CHECK_TRUE@ $(am__append_7)
@HAVE_CHECK_TRUE@ $(am__append_9)
log_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(log_test_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
@ -216,6 +232,9 @@ map_test_OBJECTS = $(am_map_test_OBJECTS)
map_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(map_test_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
print_ver_SOURCES = print_ver.c
print_ver_OBJECTS = print_ver.$(OBJEXT)
print_ver_LDADD = $(LDADD)
am__rb_test_SOURCES_DIST = check_rb.c \
$(top_builddir)/include/qb/qbrb.h
@HAVE_CHECK_TRUE@am_rb_test_OBJECTS = rb_test-check_rb.$(OBJEXT)
@ -240,6 +259,7 @@ util_test_OBJECTS = $(am_util_test_OBJECTS)
util_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(util_test_CFLAGS) \
$(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
am__dist_check_SCRIPTS_DIST = resources.test blackbox-segfault.sh
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
@ -274,15 +294,17 @@ AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(_syslog_override_la_SOURCES) $(array_test_SOURCES) \
SOURCES = $(_failure_injection_la_SOURCES) \
$(_syslog_override_la_SOURCES) $(array_test_SOURCES) \
$(bench_log_SOURCES) $(nodist_bench_log_SOURCES) \
$(bmc_SOURCES) $(bmcpt_SOURCES) $(bms_SOURCES) \
$(crash_test_dummy_SOURCES) $(file_change_bytes_SOURCES) \
$(format_compare_speed_SOURCES) $(ipc_test_SOURCES) \
$(log_test_SOURCES) $(loop_SOURCES) $(loop_test_SOURCES) \
$(map_test_SOURCES) $(rb_test_SOURCES) $(rbreader_SOURCES) \
$(rbwriter_SOURCES) $(util_test_SOURCES)
DIST_SOURCES = $(am___syslog_override_la_SOURCES_DIST) \
$(map_test_SOURCES) print_ver.c $(rb_test_SOURCES) \
$(rbreader_SOURCES) $(rbwriter_SOURCES) $(util_test_SOURCES)
DIST_SOURCES = $(am___failure_injection_la_SOURCES_DIST) \
$(am___syslog_override_la_SOURCES_DIST) \
$(am__array_test_SOURCES_DIST) $(bench_log_SOURCES) \
$(bmc_SOURCES) $(bmcpt_SOURCES) $(bms_SOURCES) \
$(am__crash_test_dummy_SOURCES_DIST) \
@ -290,13 +312,14 @@ DIST_SOURCES = $(am___syslog_override_la_SOURCES_DIST) \
$(format_compare_speed_SOURCES) $(am__ipc_test_SOURCES_DIST) \
$(am__log_test_SOURCES_DIST) $(loop_SOURCES) \
$(am__loop_test_SOURCES_DIST) $(am__map_test_SOURCES_DIST) \
$(am__rb_test_SOURCES_DIST) $(rbreader_SOURCES) \
print_ver.c $(am__rb_test_SOURCES_DIST) $(rbreader_SOURCES) \
$(rbwriter_SOURCES) $(am__util_test_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(noinst_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
@ -679,6 +702,7 @@ MAINTAINERCLEANFILES = Makefile.in $(am__append_3)
EXTRA_DIST = $(am__append_1) $(am__append_4)
CLEANFILES = $(auto_c_files) $(am__append_2)
AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
noinst_HEADERS = check_common.h
format_compare_speed_SOURCES = format_compare_speed.c $(top_builddir)/include/qb/qbutil.h
format_compare_speed_LDADD = $(top_builddir)/lib/libqb.la
bmc_SOURCES = bmc.c $(top_builddir)/include/qb/qbipcc.h
@ -697,7 +721,7 @@ loop_LDADD = $(top_builddir)/lib/libqb.la
inc_dir = $(top_srcdir)/include/qb
public_headers = $(sort $(patsubst %.in,%,$(subst $(inc_dir)/,,$(shell \
printf 'include $(inc_dir)/Makefile.am\n\n%%.var:\n\t@echo $$($$*)' \
| ${MAKE} --no-print-directory -f- inst_HEADERS.var \
| MAKEFLAGS= ${MAKE} --no-print-directory -f- inst_HEADERS.var \
|| echo $(inc_dir)/qb*.h*))))
auto_c_files = $(patsubst %.h,auto_check_header_%.c,$(public_headers))
@ -705,7 +729,8 @@ auto_c_files = $(patsubst %.h,auto_check_header_%.c,$(public_headers))
bench_log_SOURCES = bench-log.c $(top_builddir)/include/qb/qblog.h
bench_log_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
bench_log_LDADD = $(top_builddir)/lib/libqb.la
@HAVE_CHECK_TRUE@check_SCRIPTS = resources.test blackbox-segfault.sh
@HAVE_CHECK_TRUE@check_LTLIBRARIES = $(am__append_8) $(am__append_10)
@HAVE_CHECK_TRUE@dist_check_SCRIPTS = resources.test blackbox-segfault.sh
@HAVE_CHECK_TRUE@file_change_bytes_SOURCES = file_change_bytes.c
@HAVE_CHECK_TRUE@crash_test_dummy_SOURCES = crash_test_dummy.c $(top_builddir)/include/qb/qblog.h
@HAVE_CHECK_TRUE@crash_test_dummy_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
@ -724,12 +749,14 @@ bench_log_LDADD = $(top_builddir)/lib/libqb.la
@HAVE_CHECK_TRUE@loop_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
@HAVE_CHECK_TRUE@ipc_test_SOURCES = check_ipc.c $(top_builddir)/include/qb/qbipcc.h $(top_builddir)/include/qb/qbipcs.h
@HAVE_CHECK_TRUE@ipc_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
@HAVE_CHECK_TRUE@ipc_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@
@HAVE_CHECK_TRUE@ipc_test_LDADD = $(top_builddir)/lib/libqb.la \
@HAVE_CHECK_TRUE@ @CHECK_LIBS@ $(am__append_7)
@HAVE_CHECK_TRUE@@HAVE_FAILURE_INJECTION_TRUE@_failure_injection_la_SOURCES = _failure_injection.c _failure_injection.h
@HAVE_CHECK_TRUE@@HAVE_FAILURE_INJECTION_TRUE@_failure_injection_la_LDFLAGS = -module
@HAVE_CHECK_TRUE@log_test_SOURCES = check_log.c $(top_builddir)/include/qb/qblog.h
@HAVE_CHECK_TRUE@log_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
@HAVE_CHECK_TRUE@log_test_LDADD = $(top_builddir)/lib/libqb.la \
@HAVE_CHECK_TRUE@ @CHECK_LIBS@ $(am__append_7)
@HAVE_CHECK_TRUE@@HAVE_SYSLOG_TESTS_TRUE@check_LTLIBRARIES = _syslog_override.la
@HAVE_CHECK_TRUE@ @CHECK_LIBS@ $(am__append_9)
@HAVE_CHECK_TRUE@@HAVE_SYSLOG_TESTS_TRUE@_syslog_override_la_SOURCES = _syslog_override.c _syslog_override.h
@HAVE_CHECK_TRUE@@HAVE_SYSLOG_TESTS_TRUE@_syslog_override_la_LDFLAGS = -module
@HAVE_CHECK_TRUE@util_test_SOURCES = check_util.c $(top_builddir)/include/qb/qbutil.h
@ -783,6 +810,9 @@ clean-checkLTLIBRARIES:
rm -f $${locs}; \
}
_failure_injection.la: $(_failure_injection_la_OBJECTS) $(_failure_injection_la_DEPENDENCIES) $(EXTRA__failure_injection_la_DEPENDENCIES)
$(AM_V_CCLD)$(_failure_injection_la_LINK) $(am__failure_injection_la_rpath) $(_failure_injection_la_OBJECTS) $(_failure_injection_la_LIBADD) $(LIBS)
_syslog_override.la: $(_syslog_override_la_OBJECTS) $(_syslog_override_la_DEPENDENCIES) $(EXTRA__syslog_override_la_DEPENDENCIES)
$(AM_V_CCLD)$(_syslog_override_la_LINK) $(am__syslog_override_la_rpath) $(_syslog_override_la_OBJECTS) $(_syslog_override_la_LIBADD) $(LIBS)
@ -856,6 +886,10 @@ map.test$(EXEEXT): $(map_test_OBJECTS) $(map_test_DEPENDENCIES) $(EXTRA_map_test
@rm -f map.test$(EXEEXT)
$(AM_V_CCLD)$(map_test_LINK) $(map_test_OBJECTS) $(map_test_LDADD) $(LIBS)
print_ver$(EXEEXT): $(print_ver_OBJECTS) $(print_ver_DEPENDENCIES) $(EXTRA_print_ver_DEPENDENCIES)
@rm -f print_ver$(EXEEXT)
$(AM_V_CCLD)$(LINK) $(print_ver_OBJECTS) $(print_ver_LDADD) $(LIBS)
rb.test$(EXEEXT): $(rb_test_OBJECTS) $(rb_test_DEPENDENCIES) $(EXTRA_rb_test_DEPENDENCIES)
@rm -f rb.test$(EXEEXT)
$(AM_V_CCLD)$(rb_test_LINK) $(rb_test_OBJECTS) $(rb_test_LDADD) $(LIBS)
@ -875,6 +909,7 @@ util.test$(EXEEXT): $(util_test_OBJECTS) $(util_test_DEPENDENCIES) $(EXTRA_util_
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_failure_injection.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_syslog_override.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array_test-check_array.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench_log-auto_write_logs.Po@am__quote@
@ -890,6 +925,7 @@ mostlyclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_test-check_loop.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map_test-check_map.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print_ver.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rb_test-check_rb.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbreader.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rbwriter.Po@am__quote@
@ -1258,7 +1294,7 @@ check-TESTS:
log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
exit $$?;
recheck: all $(check_LTLIBRARIES) $(check_PROGRAMS) $(check_SCRIPTS)
recheck: all $(check_LTLIBRARIES) $(check_PROGRAMS) $(dist_check_SCRIPTS)
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
bases=`for i in $$bases; do echo $$i; done \
@ -1323,10 +1359,10 @@ distdir: $(DISTFILES)
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_LTLIBRARIES) $(check_PROGRAMS) \
$(check_SCRIPTS)
$(dist_check_SCRIPTS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile $(PROGRAMS)
all-am: Makefile $(PROGRAMS) $(HEADERS)
installdirs:
install: install-am
install-exec: install-exec-am

184
tests/_failure_injection.c Normal file
View File

@ -0,0 +1,184 @@
/*
* Copyright (c) 2016 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Jan Pokorny <jpokorny@redhat.com>
*
* This file is part of libqb.
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "_failure_injection.h"
#include "config.h"
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <dlfcn.h> /* dlsym */
#include <errno.h>
#include <fcntl.h> /* O_CREAT, ... */
#include <stdarg.h>
#include <stdio.h> /* perror */
#include <sys/types.h> /* mode_t, off_t */
/*** unlink (failure injection) ***/
int _fi_unlink_inject_failure = 0;
typedef int (func_unlink)(const char *);
func_unlink unlink;
static int
fake_unlink(const char *pathname)
{
errno = EACCES;
return -1;
}
int
unlink(const char *pathname)
{
static func_unlink *real_unlink;
if (_fi_unlink_inject_failure) {
return fake_unlink(pathname);
} else if (!real_unlink) {
real_unlink = (func_unlink *)
dlsym(RTLD_NEXT, "unlink");
if (!real_unlink) {
perror("dlsym(RTLD_NEXT, \"unlink\"");
real_unlink = fake_unlink;
}
}
return real_unlink(pathname);
}
/*** unlinkat (failure injection) ***/
#if defined(HAVE_UNLINKAT)
typedef int (func_unlinkat)(int, const char *, int);
func_unlinkat unlinkat;
static int
fake_unlinkat(int dirfd, const char *pathname, int flags)
{
errno = EACCES;
return -1;
}
int
unlinkat(int dirfd, const char *pathname, int flags)
{
static func_unlinkat *real_unlinkat;
if (_fi_unlink_inject_failure) {
return fake_unlinkat(dirfd, pathname, flags);
} else if (!real_unlinkat) {
real_unlinkat = (func_unlinkat *)
dlsym(RTLD_NEXT, "unlinkat");
if (!real_unlinkat) {
perror("dlsym(RTLD_NEXT, \"unlinkat\"");
real_unlinkat = fake_unlinkat;
}
}
return real_unlinkat(dirfd, pathname, flags);
}
#endif
/*** truncate (trigger detection) ***/
int _fi_truncate_called = 0;
typedef int (func_truncate)(const char *, off_t);
func_truncate truncate;
static int
fake_truncate(const char *path, off_t length)
{
errno = EIO;
return -1;
}
int
truncate(const char *path, off_t length)
{
static func_truncate *real_truncate;
if (!real_truncate) {
real_truncate = (func_truncate *)
dlsym(RTLD_NEXT, "truncate");
if (!real_truncate) {
perror("dlsym(RTLD_NEXT, \"truncate\"");
real_truncate = fake_truncate;
}
}
_fi_truncate_called++;
return real_truncate(path, length);
}
/*** openat (trigger detection) ***/
int _fi_openat_called = 0;
#if defined(HAVE_UNLINKAT)
typedef int (func_openat)(int, const char *, int, ...);
func_openat openat;
static int
fake_openat(int fd, const char *path, int oflag, ...)
{
errno = EBADF;
return -1;
}
#ifndef O_TMPFILE
# define O_TMPFILE 0
#endif
int
openat(int fd, const char *path, int oflag, ...)
{
static func_openat *real_openat;
int use_mode = 0;
mode_t mode;
va_list ap;
if (!real_openat) {
real_openat = (func_openat *)
dlsym(RTLD_NEXT, "openat");
if (!real_openat) {
perror("dlsym(RTLD_NEXT, \"openat\"");
real_openat = fake_openat;
}
}
_fi_openat_called++;
va_start(ap, oflag);
if (oflag & (O_CREAT | O_TMPFILE)) {
mode = va_arg(ap, mode_t);
use_mode = 1;
}
va_end(ap);
if (use_mode) {
return real_openat(fd, path, oflag, mode);
} else {
return real_openat(fd, path, oflag);
}
}
#endif

View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2016 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Jan Pokorny <jpokorny@redhat.com>
*
* This file is part of libqb.
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QB_FAILURE_INJECTION_H_DEFINED
#define QB_FAILURE_INJECTION_H_DEFINED
extern int _fi_unlink_inject_failure;
extern int _fi_truncate_called;
extern int _fi_openat_called;
#endif

View File

@ -25,6 +25,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>

View File

@ -21,6 +21,7 @@
#include "os_base.h"
#include <signal.h>
#include <qb/qbarray.h>
#include <qb/qbdefs.h>
#include <qb/qblog.h>
#include <qb/qbutil.h>

View File

@ -22,7 +22,8 @@
*/
#include "os_base.h"
#include <check.h>
#include "check_common.h"
#include <qb/qbdefs.h>
#include <qb/qblog.h>
@ -139,21 +140,10 @@ static Suite *array_suite(void)
TCase *tc;
Suite *s = suite_create("qb_array");
tc = tcase_create("limits");
tcase_add_test(tc, test_array_limits);
suite_add_tcase(s, tc);
tc = tcase_create("alloc_free");
tcase_add_test(tc, test_array_alloc_free);
suite_add_tcase(s, tc);
tc = tcase_create("correct_retrieval");
tcase_add_test(tc, test_array_correct_retrieval);
suite_add_tcase(s, tc);
tc = tcase_create("static_memory");
tcase_add_test(tc, test_array_static_memory);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_array_limits);
add_tcase(s, tc, test_array_alloc_free);
add_tcase(s, tc, test_array_correct_retrieval);
add_tcase(s, tc, test_array_static_memory);
return s;
}

69
tests/check_common.h Normal file
View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2016 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Jan Pokorny <jpokorny@redhat.com>
*
* This file is part of libqb.
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QB_CHECK_COMMON_H_DEFINED
#define QB_CHECK_COMMON_H_DEFINED
#include <check.h>
/*
Auxiliary macros
*/
#define JOIN(a, b) a##b
#define _STRINGIFY(arg) #arg
#define STRINGIFY(arg) _STRINGIFY(arg)
/* wide-spread technique, see, e.g.,
http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments
*/
#define VA_ARGS_CNT(...) VA_ARGS_CNT_IMPL(__VA_ARGS__,8,7,6,5,4,3,2,1,_)
#define VA_ARGS_CNT_IMPL(_1,_2,_3,_4,_5,_6,_7,_8,N,...) N
/* add_tcase "overloading" per argument count;
"func" argument is assumed to always starts with "test_", which is skipped
for the purpose of naming the respective test case that's being created */
#define add_tcase_select(cnt) JOIN(add_tcase_, cnt)
#define add_tcase_3(suite, tcase, func) \
do { \
(tcase) = tcase_create(STRINGIFY(func) + sizeof("test")); \
tcase_add_test((tcase), func); \
suite_add_tcase((suite), (tcase)); \
} while (0)
#define add_tcase_4(suite, tcase, func, timeout) \
do { \
(tcase) = tcase_create(STRINGIFY(func) + sizeof("test")); \
tcase_add_test((tcase), func); \
tcase_set_timeout((tcase), (timeout)); \
suite_add_tcase((suite), (tcase)); \
} while (0)
/*
Use-me macros
*/
/* add_tcase(<dest-suite>, <testcase-tmp-storage>, <function>[, <timeout>]) */
#define add_tcase(...) add_tcase_select(VA_ARGS_CNT(__VA_ARGS__))(__VA_ARGS__)
#endif

View File

@ -24,7 +24,8 @@
#include "os_base.h"
#include <sys/wait.h>
#include <signal.h>
#include <check.h>
#include "check_common.h"
#include <qb/qbdefs.h>
#include <qb/qblog.h>
@ -32,9 +33,14 @@
#include <qb/qbipcs.h>
#include <qb/qbloop.h>
#ifdef HAVE_FAILURE_INJECTION
#include "_failure_injection.h"
#endif
static char ipc_name[256];
#define DEFAULT_MAX_MSG_SIZE (8192*16)
#ifndef __clang__
static int CALCULATED_DGRAM_MAX_MSG_SIZE = 0;
#define DGRAM_MAX_MSG_SIZE \
@ -44,6 +50,14 @@ static int CALCULATED_DGRAM_MAX_MSG_SIZE = 0;
#define MAX_MSG_SIZE (ipc_type == QB_IPC_SOCKET ? DGRAM_MAX_MSG_SIZE : DEFAULT_MAX_MSG_SIZE)
#else
/* because of clang's
'variable length array in structure' extension will never be supported;
assign default for SHM as we'll skip test that would use run-time
established value (via qb_ipcc_verify_dgram_max_msg_size), anyway */
static const int MAX_MSG_SIZE = DEFAULT_MAX_MSG_SIZE;
#endif
/* 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
@ -69,7 +83,7 @@ enum my_msg_ids {
/* Test Cases
*
* 1) basic send & recv differnet message sizes
* 1) basic send & recv different message sizes
*
* 2) send message to start dispatch (confirm receipt)
*
@ -81,7 +95,7 @@ enum my_msg_ids {
*
* 6) cleanup
*
* 7) service availabilty
* 7) service availability
*
* 8) multiple services
*/
@ -298,7 +312,7 @@ outq_flush (void *data)
qb_ipcs_destroy(s1);
s1 = NULL;
}
/* is the reference counting is not working, this should fail
/* if the reference counting is not working, this should fail
* for i > 1.
*/
qb_ipcs_event_send(data, "test", 4);
@ -390,8 +404,6 @@ run_ipc_server(void)
};
uint32_t max_size = MAX_MSG_SIZE;
qb_loop_signal_add(my_loop, QB_LOOP_HIGH, SIGSTOP,
NULL, exit_handler, &handle);
qb_loop_signal_add(my_loop, QB_LOOP_HIGH, SIGTERM,
NULL, exit_handler, &handle);
@ -877,7 +889,7 @@ test_ipc_dispatch(void)
verify_graceful_stop(pid);
}
START_TEST(test_ipc_disp_us)
START_TEST(test_ipc_dispatch_us)
{
qb_enter();
ipc_type = QB_IPC_SOCKET;
@ -1143,6 +1155,7 @@ test_ipc_stress_test(void)
verify_graceful_stop(pid);
}
#ifndef __clang__ /* see variable length array in structure' at the top */
START_TEST(test_ipc_stress_test_us)
{
qb_enter();
@ -1153,6 +1166,7 @@ START_TEST(test_ipc_stress_test_us)
qb_leave();
}
END_TEST
#endif
START_TEST(test_ipc_stress_connections_us)
{
@ -1317,8 +1331,14 @@ test_ipc_server_fail(void)
fail_if(conn == NULL);
request_server_exit();
if (_fi_unlink_inject_failure == QB_TRUE) {
_fi_truncate_called = _fi_openat_called = 0;
}
ck_assert_int_eq(QB_FALSE, qb_ipcc_is_connected(conn));
qb_ipcc_disconnect(conn);
if (_fi_unlink_inject_failure == QB_TRUE) {
ck_assert_int_ne(_fi_truncate_called + _fi_openat_called, 0);
}
verify_graceful_stop(pid);
}
@ -1332,7 +1352,7 @@ START_TEST(test_ipc_server_fail_soc)
}
END_TEST
START_TEST(test_ipc_disp_shm)
START_TEST(test_ipc_dispatch_shm)
{
qb_enter();
ipc_type = QB_IPC_SHM;
@ -1394,6 +1414,20 @@ START_TEST(test_ipc_server_fail_shm)
}
END_TEST
#ifdef HAVE_FAILURE_INJECTION
START_TEST(test_ipcc_truncate_when_unlink_fails_shm)
{
qb_enter();
_fi_unlink_inject_failure = QB_TRUE;
ipc_type = QB_IPC_SHM;
set_ipc_name(__func__);
test_ipc_server_fail();
_fi_unlink_inject_failure = QB_FALSE;
qb_leave();
}
END_TEST
#endif
static void
test_ipc_service_ref_count(void)
{
@ -1482,65 +1516,22 @@ make_shm_suite(void)
TCase *tc;
Suite *s = suite_create("shm");
tc = tcase_create("ipc_txrx_shm_timeout");
tcase_add_test(tc, test_ipc_txrx_shm_timeout);
tcase_set_timeout(tc, 30);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_ipc_txrx_shm_timeout, 30);
add_tcase(s, tc, test_ipc_server_fail_shm, 8);
add_tcase(s, tc, test_ipc_txrx_shm_block, 8);
add_tcase(s, tc, test_ipc_txrx_shm_tmo, 8);
add_tcase(s, tc, test_ipc_fc_shm, 8);
add_tcase(s, tc, test_ipc_dispatch_shm, 16);
add_tcase(s, tc, test_ipc_stress_test_shm, 16);
add_tcase(s, tc, test_ipc_bulk_events_shm, 16);
add_tcase(s, tc, test_ipc_exit_shm, 8);
add_tcase(s, tc, test_ipc_event_on_created_shm, 10);
add_tcase(s, tc, test_ipc_service_ref_count_shm, 10);
add_tcase(s, tc, test_ipc_stress_connections_shm, 3600);
tc = tcase_create("ipc_server_fail_shm");
tcase_add_test(tc, test_ipc_server_fail_shm);
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_txrx_shm_block");
tcase_add_test(tc, test_ipc_txrx_shm_block);
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_txrx_shm_tmo");
tcase_add_test(tc, test_ipc_txrx_shm_tmo);
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_fc_shm");
tcase_add_test(tc, test_ipc_fc_shm);
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_dispatch_shm");
tcase_add_test(tc, test_ipc_disp_shm);
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);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_exit_shm");
tcase_add_test(tc, test_ipc_exit_shm);
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_event_on_created_shm");
tcase_add_test(tc, test_ipc_event_on_created_shm);
tcase_set_timeout(tc, 10);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_service_ref_count_shm");
tcase_add_test(tc, test_ipc_service_ref_count_shm);
tcase_set_timeout(tc, 10);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_stress_connections_shm");
tcase_add_test(tc, test_ipc_stress_connections_shm);
tcase_set_timeout(tc, 3600);
suite_add_tcase(s, tc);
#ifdef HAVE_FAILURE_INJECTION
add_tcase(s, tc, test_ipcc_truncate_when_unlink_fails_shm, 8);
#endif
return s;
}
@ -1551,75 +1542,22 @@ make_soc_suite(void)
Suite *s = suite_create("socket");
TCase *tc;
tc = tcase_create("ipc_txrx_us_timeout");
tcase_add_test(tc, test_ipc_txrx_us_timeout);
tcase_set_timeout(tc, 30);
suite_add_tcase(s, 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, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_txrx_us_block");
tcase_add_test(tc, test_ipc_txrx_us_block);
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_txrx_us_tmo");
tcase_add_test(tc, test_ipc_txrx_us_tmo);
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_fc_us");
tcase_add_test(tc, test_ipc_fc_us);
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_exit_us");
tcase_add_test(tc, test_ipc_exit_us);
tcase_set_timeout(tc, 8);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_dispatch_us");
tcase_add_test(tc, test_ipc_disp_us);
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);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_event_on_created_us");
tcase_add_test(tc, test_ipc_event_on_created_us);
tcase_set_timeout(tc, 10);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_disconnect_after_created_us");
tcase_add_test(tc, test_ipc_disconnect_after_created_us);
tcase_set_timeout(tc, 10);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_service_ref_count_us");
tcase_add_test(tc, test_ipc_service_ref_count_us);
tcase_set_timeout(tc, 10);
suite_add_tcase(s, tc);
tc = tcase_create("ipc_stress_connections_us");
tcase_add_test(tc, test_ipc_stress_connections_us);
tcase_set_timeout(tc, 3600);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_ipc_txrx_us_timeout, 30);
add_tcase(s, tc, test_ipc_max_dgram_size, 30);
add_tcase(s, tc, test_ipc_server_fail_soc, 8);
add_tcase(s, tc, test_ipc_txrx_us_block, 8);
add_tcase(s, tc, test_ipc_txrx_us_tmo, 8);
add_tcase(s, tc, test_ipc_fc_us, 8);
add_tcase(s, tc, test_ipc_exit_us, 8);
add_tcase(s, tc, test_ipc_dispatch_us, 16);
#ifndef __clang__ /* see variable length array in structure' at the top */
add_tcase(s, tc, test_ipc_stress_test_us, 60);
#endif
add_tcase(s, tc, test_ipc_bulk_events_us, 16);
add_tcase(s, tc, test_ipc_event_on_created_us, 10);
add_tcase(s, tc, test_ipc_disconnect_after_created_us, 10);
add_tcase(s, tc, test_ipc_service_ref_count_us, 10);
add_tcase(s, tc, test_ipc_stress_connections_us, 3600);
return s;
}

View File

@ -23,7 +23,8 @@
#include "os_base.h"
#include <pthread.h>
#include <check.h>
#include "check_common.h"
#include <qb/qbdefs.h>
#include <qb/qbutil.h>
@ -85,6 +86,14 @@ START_TEST(test_va_serialize)
format_this(buf, "f1:%.5f, f2:%.2f", 23.34109, 23.34109);
ck_assert_str_eq(buf, "f1:23.34109, f2:23.34");
format_this(buf, "%zd", (size_t)13140964);
ck_assert_str_eq(buf, "13140964");
format_this(buf, "%jd", (intmax_t)30627823);
ck_assert_str_eq(buf, "30627823");
format_this(buf, "%td", buf-cmp_buf);
snprintf(cmp_buf, QB_LOG_MAX_LEN, "%td", buf-cmp_buf);
ck_assert_str_eq(buf, cmp_buf);
format_this(buf, ":%s:", "Hello, world!");
ck_assert_str_eq(buf, ":Hello, world!:");
format_this(buf, ":%15s:", "Hello, world!");
@ -717,6 +726,42 @@ START_TEST(test_threaded_logging)
}
END_TEST
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
START_TEST(test_threaded_logging_bad_sched_params)
{
int32_t t;
int32_t rc;
qb_log_init("test", LOG_USER, LOG_EMERG);
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
t = qb_log_custom_open(_test_logger, NULL, NULL, NULL);
rc = qb_log_filter_ctl(t, QB_LOG_FILTER_ADD,
QB_LOG_FILTER_FILE, "*", LOG_INFO);
ck_assert_int_eq(rc, 0);
qb_log_format_set(t, "%b");
rc = qb_log_ctl(t, QB_LOG_CONF_ENABLED, QB_TRUE);
ck_assert_int_eq(rc, 0);
rc = qb_log_ctl(t, QB_LOG_CONF_THREADED, QB_TRUE);
ck_assert_int_eq(rc, 0);
#if defined(SCHED_RR)
#define QB_SCHED SCHED_RR
#elif defined(SCHED_FIFO)
#define QB_SCHED SCHED_FIFO
#else
#define QB_SCHED (-1)
#endif
rc = qb_log_thread_priority_set(QB_SCHED, -1);
ck_assert_int_eq(rc, 0);
rc = qb_log_thread_start();
ck_assert_int_ne(rc, 0);
qb_log_fini();
}
END_TEST
#endif
START_TEST(test_extended_information)
{
int32_t t;
@ -774,6 +819,46 @@ START_TEST(test_extended_information)
}
END_TEST
static const char *tagtest_stringify_tag(uint32_t tag)
{
static char buf[32];
sprintf(buf, "%5d", tag);
return buf;
}
START_TEST(test_zero_tags)
{
int32_t rc;
int32_t t;
qb_log_init("test", LOG_USER, LOG_EMERG);
qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
t = qb_log_custom_open(_test_logger, NULL, NULL, NULL);
rc = qb_log_filter_ctl(t, QB_LOG_FILTER_ADD,
QB_LOG_FILTER_FILE, "*", LOG_INFO);
ck_assert_int_eq(rc, 0);
qb_log_format_set(t, "[%g] %b");
qb_log_tags_stringify_fn_set(tagtest_stringify_tag);
rc = qb_log_ctl(t, QB_LOG_CONF_ENABLED, QB_TRUE);
ck_assert_int_eq(rc, 0);
qb_log_filter_ctl(t, QB_LOG_FILTER_ADD,
QB_LOG_FILTER_FILE, "*", LOG_TRACE);
qb_log_from_external_source("function", "filename", "%s: %d", LOG_DEBUG, 356, 2, "testlog", 2);
ck_assert_str_eq(test_buf, "[ 2] testlog: 2");
qb_log_from_external_source("function", "filename", "%s: %d", LOG_DEBUG, 356, 0, "testlog", 0);
ck_assert_str_eq(test_buf, "[ 2] testlog: 0");
qb_log_fini();
}
END_TEST
#ifdef HAVE_SYSLOG_TESTS
START_TEST(test_syslog)
{
@ -799,51 +884,23 @@ log_suite(void)
TCase *tc;
Suite *s = suite_create("logging");
tc = tcase_create("va_serialize");
tcase_add_test(tc, test_va_serialize);
suite_add_tcase(s, tc);
tc = tcase_create("limits");
tcase_add_test(tc, test_log_stupid_inputs);
suite_add_tcase(s, tc);
tc = tcase_create("basic");
tcase_add_test(tc, test_log_basic);
suite_add_tcase(s, tc);
tc = tcase_create("format");
tcase_add_test(tc, test_log_format);
suite_add_tcase(s, tc);
tc = tcase_create("enable");
tcase_add_test(tc, test_log_enable);
suite_add_tcase(s, tc);
tc = tcase_create("threads");
tcase_add_test(tc, test_log_threads);
tcase_set_timeout(tc, 360);
suite_add_tcase(s, tc);
tc = tcase_create("long_msg");
tcase_add_test(tc, test_log_long_msg);
suite_add_tcase(s, tc);
tc = tcase_create("filter_ft");
tcase_add_test(tc, test_log_filter_fn);
suite_add_tcase(s, tc);
tc = tcase_create("threaded_logging");
tcase_add_test(tc, test_threaded_logging);
suite_add_tcase(s, tc);
tc = tcase_create("extended_information");
tcase_add_test(tc, test_extended_information);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_va_serialize);
add_tcase(s, tc, test_log_stupid_inputs);
add_tcase(s, tc, test_log_basic);
add_tcase(s, tc, test_log_format);
add_tcase(s, tc, test_log_enable);
add_tcase(s, tc, test_log_threads, 360);
add_tcase(s, tc, test_log_long_msg);
add_tcase(s, tc, test_log_filter_fn);
add_tcase(s, tc, test_threaded_logging);
#ifdef HAVE_PTHREAD_SETSCHEDPARAM
add_tcase(s, tc, test_threaded_logging_bad_sched_params);
#endif
add_tcase(s, tc, test_extended_information);
add_tcase(s, tc, test_zero_tags);
#ifdef HAVE_SYSLOG_TESTS
tc = tcase_create("syslog");
tcase_add_test(tc, test_syslog);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_syslog);
#endif
return s;

View File

@ -22,7 +22,8 @@
*/
#include "os_base.h"
#include <check.h>
#include "check_common.h"
#include <qb/qbdefs.h>
#include <qb/qbutil.h>
@ -331,35 +332,13 @@ static Suite *loop_job_suite(void)
TCase *tc;
Suite *s = suite_create("loop_job");
tc = tcase_create("limits");
tcase_add_test(tc, test_loop_job_input);
suite_add_tcase(s, tc);
tc = tcase_create("run_one");
tcase_add_test(tc, test_loop_job_1);
suite_add_tcase(s, tc);
tc = tcase_create("run_recursive");
tcase_add_test(tc, test_loop_job_4);
suite_add_tcase(s, tc);
tc = tcase_create("run_500");
tcase_add_test(tc, test_loop_job_nuts);
tcase_set_timeout(tc, 5);
suite_add_tcase(s, tc);
tc = tcase_create("rate_limit");
tcase_add_test(tc, test_job_rate_limit);
tcase_set_timeout(tc, 5);
suite_add_tcase(s, tc);
tc = tcase_create("add_del");
tcase_add_test(tc, test_job_add_del);
suite_add_tcase(s, tc);
tc = tcase_create("order");
tcase_add_test(tc, test_loop_job_order);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_loop_job_input);
add_tcase(s, tc, test_loop_job_1);
add_tcase(s, tc, test_loop_job_4);
add_tcase(s, tc, test_loop_job_nuts, 5);
add_tcase(s, tc, test_job_rate_limit, 5);
add_tcase(s, tc, test_job_add_del);
add_tcase(s, tc, test_loop_job_order);
return s;
}
@ -710,24 +689,11 @@ loop_timer_suite(void)
TCase *tc;
Suite *s = suite_create("loop_timers");
tc = tcase_create("limits");
tcase_add_test(tc, test_loop_timer_input);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_loop_timer_input);
add_tcase(s, tc, test_loop_timer_basic, 30);
add_tcase(s, tc, test_loop_timer_precision, 30);
add_tcase(s, tc, test_loop_timer_expire_leak, 30);
tc = tcase_create("basic");
tcase_add_test(tc, test_loop_timer_basic);
tcase_set_timeout(tc, 30);
suite_add_tcase(s, tc);
tc = tcase_create("precision");
tcase_add_test(tc, test_loop_timer_precision);
tcase_set_timeout(tc, 30);
suite_add_tcase(s, tc);
tc = tcase_create("expire_leak");
tcase_add_test(tc, test_loop_timer_expire_leak);
tcase_set_timeout(tc, 30);
suite_add_tcase(s, tc);
return s;
}
@ -737,18 +703,9 @@ loop_signal_suite(void)
TCase *tc;
Suite *s = suite_create("loop_signal_suite");
tc = tcase_create("signals");
tcase_add_test(tc, test_loop_sig_handling);
tcase_set_timeout(tc, 10);
suite_add_tcase(s, tc);
tc = tcase_create("sig_only_one");
tcase_add_test(tc, test_loop_sig_only_get_one);
suite_add_tcase(s, tc);
tc = tcase_create("sig_delete");
tcase_add_test(tc, test_loop_sig_delete);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_loop_sig_handling, 10);
add_tcase(s, tc, test_loop_sig_only_get_one);
add_tcase(s, tc, test_loop_sig_delete);
return s;
}

View File

@ -21,7 +21,9 @@
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h"
#include <check.h>
#include "check_common.h"
#include <qb/qbdefs.h>
#include <qb/qblog.h>
#include <qb/qbmap.h>
@ -910,80 +912,28 @@ map_suite(void)
TCase *tc;
Suite *s = suite_create("qb_map");
tc = tcase_create("skiplist_simple");
tcase_add_test(tc, test_skiplist_simple);
suite_add_tcase(s, tc);
tc = tcase_create("hashtable_simple");
tcase_add_test(tc, test_hashtable_simple);
suite_add_tcase(s, tc);
tc = tcase_create("trie_simple");
tcase_add_test(tc, test_trie_simple);
suite_add_tcase(s, tc);
tc = tcase_create("trie_partial_iterate");
tcase_add_test(tc, test_trie_partial_iterate);
suite_add_tcase(s, tc);
tc = tcase_create("skiplist_remove");
tcase_add_test(tc, test_skiplist_remove);
suite_add_tcase(s, tc);
tc = tcase_create("hashtable_remove");
tcase_add_test(tc, test_hashtable_remove);
suite_add_tcase(s, tc);
tc = tcase_create("trie_notifications");
tcase_add_test(tc, test_trie_notifications);
suite_add_tcase(s, tc);
tc = tcase_create("hash_notifications");
tcase_add_test(tc, test_hash_notifications);
suite_add_tcase(s, tc);
tc = tcase_create("skiplist_notifications");
tcase_add_test(tc, test_skiplist_notifications);
suite_add_tcase(s, tc);
tc = tcase_create("skiplist_search");
tcase_add_test(tc, test_skiplist_search);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_skiplist_simple);
add_tcase(s, tc, test_hashtable_simple);
add_tcase(s, tc, test_trie_simple);
add_tcase(s, tc, test_trie_partial_iterate);
add_tcase(s, tc, test_skiplist_remove);
add_tcase(s, tc, test_hashtable_remove);
add_tcase(s, tc, test_trie_notifications);
add_tcase(s, tc, test_hash_notifications);
add_tcase(s, tc, test_skiplist_notifications);
add_tcase(s, tc, test_skiplist_search);
/*
* No hashtable_search as it assumes an ordered
* collection
*/
tc = tcase_create("trie_search");
tcase_add_test(tc, test_trie_search);
suite_add_tcase(s, tc);
tc = tcase_create("skiplist_traverse");
tcase_add_test(tc, test_skiplist_traverse);
suite_add_tcase(s, tc);
tc = tcase_create("hashtable_traverse");
tcase_add_test(tc, test_hashtable_traverse);
suite_add_tcase(s, tc);
tc = tcase_create("trie_traverse");
tcase_add_test(tc, test_trie_traverse);
suite_add_tcase(s, tc);
tc = tcase_create("skiplist_load");
tcase_add_test(tc, test_skiplist_load);
tcase_set_timeout(tc, 30);
suite_add_tcase(s, tc);
tc = tcase_create("hashtable_load");
tcase_add_test(tc, test_hashtable_load);
tcase_set_timeout(tc, 30);
suite_add_tcase(s, tc);
tc = tcase_create("trie_load");
tcase_add_test(tc, test_trie_load);
tcase_set_timeout(tc, 30);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_trie_search);
add_tcase(s, tc, test_skiplist_traverse);
add_tcase(s, tc, test_hashtable_traverse);
add_tcase(s, tc, test_trie_traverse);
add_tcase(s, tc, test_skiplist_load, 30);
add_tcase(s, tc, test_hashtable_load, 30);
add_tcase(s, tc, test_trie_load, 30);
return s;
}

View File

@ -25,7 +25,8 @@
#include <stdlib.h>
#include <syslog.h>
#include <errno.h>
#include <check.h>
#include "check_common.h"
#include <qb/qbdefs.h>
#include <qb/qbrb.h>
@ -193,21 +194,10 @@ static Suite *rb_suite(void)
TCase *tc;
Suite *s = suite_create("ringbuffer");
tc = tcase_create("test01");
tcase_add_test(tc, test_ring_buffer1);
suite_add_tcase(s, tc);
tc = tcase_create("test02");
tcase_add_test(tc, test_ring_buffer2);
suite_add_tcase(s, tc);
tc = tcase_create("test03");
tcase_add_test(tc, test_ring_buffer3);
suite_add_tcase(s, tc);
tc = tcase_create("test04");
tcase_add_test(tc, test_ring_buffer4);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_ring_buffer1);
add_tcase(s, tc, test_ring_buffer2);
add_tcase(s, tc, test_ring_buffer3);
add_tcase(s, tc, test_ring_buffer4);
return s;
}

View File

@ -22,7 +22,8 @@
*/
#include "os_base.h"
#include <check.h>
#include "check_common.h"
#include <qb/qbdefs.h>
#include <qb/qbutil.h>
@ -159,13 +160,8 @@ static Suite *util_suite(void)
TCase *tc;
Suite *s = suite_create("qb_util");
tc = tcase_create("overwrite");
tcase_add_test(tc, test_check_overwrite);
suite_add_tcase(s, tc);
tc = tcase_create("normal");
tcase_add_test(tc, test_check_normal);
suite_add_tcase(s, tc);
add_tcase(s, tc, test_check_overwrite);
add_tcase(s, tc, test_check_normal);
return s;
}

42
tests/print_ver.c Normal file
View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2016 Red Hat, Inc.
*
* All rights reserved.
*
* Author: Jan Pokorny <jpokorny@redhat.com>
*
* This file is part of libqb.
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os_base.h" /* instead of assert.h & stdio.h + defines VERSION */
#include <qb/qbconfig.h> /* QB_VER_{MAJOR,MINOR,MICRO,REST} + QB_VER_STR */
#include <qb/qbdefs.h> /* QB_PP_STRINGIFY */
int
main(void)
{
printf("%s consists of: %d, %d, %d, %s\n", QB_VER_STR,
QB_VER_MAJOR, QB_VER_MINOR, QB_VER_MICRO, QB_VER_REST);
return 0;
}
/* make version components emitted during "make check" for easy inspection;
semicolon intentionally omitted so as to avoid unnecessary message
source diagnostics (bug or feature?) with some GCC versions (5.3.1) */
#define MSG QB_PP_STRINGIFY( \
GCC warning QB_PP_STRINGIFY(VERSION parsed as: QB_VER_STR))
_Pragma(MSG)

View File

@ -1,20 +1,30 @@
#!/bin/sh
RETURN=0
for d in /dev/shm /var/run
do
ls $d/qb-test* 2>/dev/null
if [ $? -eq 0 ]
then
for d in /dev/shm /var/run; do
leftovers=$(find $d -name qb-test* -size +0c 2>/dev/null | wc -l)
if [ "${leftovers}" -gt 0 ]; then
echo
echo "Error: shared memory segments not closed/unlinked"
echo
RETURN=1
fi
leftovers="$(find $d -name qb-test* -size 0c 2>/dev/null)"
if [ "$(printf '%s\n' "${leftovers}" | wc -l)" -eq 6 ]; then
echo
echo "There were some empty leftovers (expected), removing them"
echo "${leftovers}" | tee /dev/stderr | xargs rm
echo
elif [ -n "${leftovers}" ]; then
echo
echo "Error: unexpected number of empty leftovers"
echo "${leftovers}"
echo
RETURN=1
fi
done
ps aux | grep -v grep | grep lt-check
if [ $? -eq 0 ]
then
ps aux | grep -v grep | grep -E 'lt-.*\.test'
if [ $? -eq 0 ]; then
echo "test program frozen"
RETURN=1
fi