Merge branch 'master' of ctdb into 'master' of samba
authorStefan Metzmacher <metze@samba.org>
Wed, 13 Nov 2013 13:17:32 +0000 (14:17 +0100)
committerMichael Adam <obnox@samba.org>
Wed, 13 Nov 2013 13:18:52 +0000 (14:18 +0100)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Michael Adam <obnox@samba.org>
786 files changed:
ctdb/.bzrignore [new file with mode: 0644]
ctdb/.gitignore [new file with mode: 0644]
ctdb/COPYING [new file with mode: 0644]
ctdb/Makefile.in [new file with mode: 0755]
ctdb/NEWS [new file with mode: 0644]
ctdb/README [new file with mode: 0644]
ctdb/README.Coding [new file with mode: 0644]
ctdb/aclocal.m4 [new file with mode: 0644]
ctdb/autogen.sh [new file with mode: 0755]
ctdb/client/ctdb_client.c [new file with mode: 0644]
ctdb/common/cmdline.c [new file with mode: 0644]
ctdb/common/ctdb_fork.c [new file with mode: 0644]
ctdb/common/ctdb_io.c [new file with mode: 0644]
ctdb/common/ctdb_logging.c [new file with mode: 0644]
ctdb/common/ctdb_ltdb.c [new file with mode: 0644]
ctdb/common/ctdb_message.c [new file with mode: 0644]
ctdb/common/ctdb_util.c [new file with mode: 0644]
ctdb/common/rb_tree.c [new file with mode: 0644]
ctdb/common/rb_tree.h [new file with mode: 0644]
ctdb/common/system_aix.c [new file with mode: 0644]
ctdb/common/system_common.c [new file with mode: 0644]
ctdb/common/system_freebsd.c [new file with mode: 0644]
ctdb/common/system_gnu.c [new file with mode: 0644]
ctdb/common/system_kfreebsd.c [new file with mode: 0644]
ctdb/common/system_linux.c [new file with mode: 0644]
ctdb/config.guess [new file with mode: 0644]
ctdb/config.mk [new file with mode: 0644]
ctdb/config.sub [new file with mode: 0644]
ctdb/config/README [new file with mode: 0644]
ctdb/config/ctdb-crash-cleanup.sh [new file with mode: 0755]
ctdb/config/ctdb.init [new file with mode: 0755]
ctdb/config/ctdb.service [new file with mode: 0644]
ctdb/config/ctdb.sudoers [new file with mode: 0644]
ctdb/config/ctdb.sysconfig [new file with mode: 0644]
ctdb/config/ctdbd_wrapper [new file with mode: 0755]
ctdb/config/debug-hung-script.sh [new file with mode: 0755]
ctdb/config/debug_locks.sh [new file with mode: 0644]
ctdb/config/events.d/00.ctdb [new file with mode: 0755]
ctdb/config/events.d/01.reclock [new file with mode: 0755]
ctdb/config/events.d/10.interface [new file with mode: 0755]
ctdb/config/events.d/11.natgw [new file with mode: 0755]
ctdb/config/events.d/11.routing [new file with mode: 0755]
ctdb/config/events.d/13.per_ip_routing [new file with mode: 0755]
ctdb/config/events.d/20.multipathd [new file with mode: 0755]
ctdb/config/events.d/31.clamd [new file with mode: 0755]
ctdb/config/events.d/40.fs_use [new file with mode: 0644]
ctdb/config/events.d/40.vsftpd [new file with mode: 0755]
ctdb/config/events.d/41.httpd [new file with mode: 0755]
ctdb/config/events.d/49.winbind [new file with mode: 0755]
ctdb/config/events.d/50.samba [new file with mode: 0755]
ctdb/config/events.d/60.ganesha [new file with mode: 0755]
ctdb/config/events.d/60.nfs [new file with mode: 0755]
ctdb/config/events.d/62.cnfs [new file with mode: 0755]
ctdb/config/events.d/70.iscsi [new file with mode: 0755]
ctdb/config/events.d/91.lvs [new file with mode: 0755]
ctdb/config/events.d/99.timeout [new file with mode: 0755]
ctdb/config/events.d/README [new file with mode: 0644]
ctdb/config/functions [new file with mode: 0755]
ctdb/config/gcore_trace.sh [new file with mode: 0755]
ctdb/config/nfs-rpc-checks.d/10.statd.check [new file with mode: 0644]
ctdb/config/nfs-rpc-checks.d/20.nfsd.check [new file with mode: 0644]
ctdb/config/nfs-rpc-checks.d/30.lockd.check [new file with mode: 0644]
ctdb/config/nfs-rpc-checks.d/40.mountd.check [new file with mode: 0644]
ctdb/config/nfs-rpc-checks.d/50.rquotad.check [new file with mode: 0644]
ctdb/config/notify.d.README [new file with mode: 0755]
ctdb/config/notify.sh [new file with mode: 0755]
ctdb/config/statd-callout [new file with mode: 0755]
ctdb/configure.ac [new file with mode: 0644]
ctdb/configure.rpm [new file with mode: 0755]
ctdb/ctdb.pc.in [new file with mode: 0644]
ctdb/doc/Makefile [new file with mode: 0644]
ctdb/doc/ctdb-tunables.7.xml [new file with mode: 0644]
ctdb/doc/ctdb.1.xml [new file with mode: 0644]
ctdb/doc/ctdb.7.xml [new file with mode: 0644]
ctdb/doc/ctdbd.1.xml [new file with mode: 0644]
ctdb/doc/ctdbd.conf.5.xml [new file with mode: 0644]
ctdb/doc/ctdbd_wrapper.1.xml [new file with mode: 0644]
ctdb/doc/examples/README [new file with mode: 0644]
ctdb/doc/examples/cluster.conf [new file with mode: 0644]
ctdb/doc/examples/natgw.conf [new file with mode: 0644]
ctdb/doc/ltdbtool.1.xml [new file with mode: 0644]
ctdb/doc/onnode.1.xml [new file with mode: 0644]
ctdb/doc/ping_pong.1.xml [new file with mode: 0644]
ctdb/doc/readonlyrecords.txt [new file with mode: 0644]
ctdb/doc/recovery-process.txt [new file with mode: 0644]
ctdb/ib/README.txt [new file with mode: 0644]
ctdb/ib/config.m4 [new file with mode: 0644]
ctdb/ib/ibw_ctdb.c [new file with mode: 0644]
ctdb/ib/ibw_ctdb.h [new file with mode: 0644]
ctdb/ib/ibw_ctdb_init.c [new file with mode: 0644]
ctdb/ib/ibwrapper.c [new file with mode: 0644]
ctdb/ib/ibwrapper.h [new file with mode: 0644]
ctdb/ib/ibwrapper_internal.h [new file with mode: 0644]
ctdb/ib/ibwrapper_test.c [new file with mode: 0644]
ctdb/include/cmdline.h [new file with mode: 0644]
ctdb/include/ctdb.h [new file with mode: 0644]
ctdb/include/ctdb_client.h [new file with mode: 0644]
ctdb/include/ctdb_private.h [new file with mode: 0644]
ctdb/include/ctdb_protocol.h [new file with mode: 0644]
ctdb/include/ctdb_typesafe_cb.h [new file with mode: 0644]
ctdb/include/idtree.h [new file with mode: 0644]
ctdb/include/includes.h [new file with mode: 0644]
ctdb/install-sh [new file with mode: 0755]
ctdb/lib/popt/CHANGES [new file with mode: 0644]
ctdb/lib/popt/COPYING [new file with mode: 0644]
ctdb/lib/popt/README [new file with mode: 0644]
ctdb/lib/popt/findme.c [new file with mode: 0644]
ctdb/lib/popt/findme.h [new file with mode: 0644]
ctdb/lib/popt/libpopt.m4 [new file with mode: 0644]
ctdb/lib/popt/popt.c [new file with mode: 0644]
ctdb/lib/popt/popt.h [new file with mode: 0644]
ctdb/lib/popt/poptconfig.c [new file with mode: 0644]
ctdb/lib/popt/popthelp.c [new file with mode: 0644]
ctdb/lib/popt/poptint.h [new file with mode: 0644]
ctdb/lib/popt/poptparse.c [new file with mode: 0644]
ctdb/lib/popt/samba.m4 [new file with mode: 0644]
ctdb/lib/popt/system.h [new file with mode: 0644]
ctdb/lib/replace/.checker_innocent [new file with mode: 0644]
ctdb/lib/replace/Makefile [new file with mode: 0644]
ctdb/lib/replace/README [new file with mode: 0644]
ctdb/lib/replace/autoconf-2.60.m4 [new file with mode: 0644]
ctdb/lib/replace/configure [new file with mode: 0755]
ctdb/lib/replace/crypt.c [new file with mode: 0644]
ctdb/lib/replace/crypt.m4 [new file with mode: 0644]
ctdb/lib/replace/dlfcn.c [new file with mode: 0644]
ctdb/lib/replace/dlfcn.m4 [new file with mode: 0644]
ctdb/lib/replace/getaddrinfo.c [new file with mode: 0644]
ctdb/lib/replace/getaddrinfo.h [new file with mode: 0644]
ctdb/lib/replace/getifaddrs.c [new file with mode: 0644]
ctdb/lib/replace/hdr_replace.h [new file with mode: 0644]
ctdb/lib/replace/inet_aton.c [new file with mode: 0644]
ctdb/lib/replace/inet_ntoa.c [new file with mode: 0644]
ctdb/lib/replace/inet_ntop.c [new file with mode: 0644]
ctdb/lib/replace/inet_pton.c [new file with mode: 0644]
ctdb/lib/replace/install-sh [new file with mode: 0755]
ctdb/lib/replace/libreplace.m4 [new file with mode: 0644]
ctdb/lib/replace/libreplace_cc.m4 [new file with mode: 0644]
ctdb/lib/replace/libreplace_ld.m4 [new file with mode: 0644]
ctdb/lib/replace/libreplace_macros.m4 [new file with mode: 0644]
ctdb/lib/replace/libreplace_network.m4 [new file with mode: 0644]
ctdb/lib/replace/poll.c [new file with mode: 0644]
ctdb/lib/replace/repdir.m4 [new file with mode: 0644]
ctdb/lib/replace/repdir_getdents.c [new file with mode: 0644]
ctdb/lib/replace/repdir_getdirentries.c [new file with mode: 0644]
ctdb/lib/replace/replace-test.h [new file with mode: 0644]
ctdb/lib/replace/replace-testsuite.h [new file with mode: 0644]
ctdb/lib/replace/replace.c [new file with mode: 0644]
ctdb/lib/replace/replace.h [new file with mode: 0644]
ctdb/lib/replace/snprintf.c [new file with mode: 0644]
ctdb/lib/replace/socket.c [new file with mode: 0644]
ctdb/lib/replace/socketpair.c [new file with mode: 0644]
ctdb/lib/replace/strptime.c [new file with mode: 0644]
ctdb/lib/replace/strptime.m4 [new file with mode: 0644]
ctdb/lib/replace/system/README [new file with mode: 0644]
ctdb/lib/replace/system/aio.h [new file with mode: 0644]
ctdb/lib/replace/system/capability.h [new file with mode: 0644]
ctdb/lib/replace/system/config.m4 [new file with mode: 0644]
ctdb/lib/replace/system/dir.h [new file with mode: 0644]
ctdb/lib/replace/system/filesys.h [new file with mode: 0644]
ctdb/lib/replace/system/glob.h [new file with mode: 0644]
ctdb/lib/replace/system/gssapi.h [new file with mode: 0644]
ctdb/lib/replace/system/iconv.h [new file with mode: 0644]
ctdb/lib/replace/system/kerberos.h [new file with mode: 0644]
ctdb/lib/replace/system/locale.h [new file with mode: 0644]
ctdb/lib/replace/system/network.h [new file with mode: 0644]
ctdb/lib/replace/system/passwd.h [new file with mode: 0644]
ctdb/lib/replace/system/readline.h [new file with mode: 0644]
ctdb/lib/replace/system/select.h [new file with mode: 0644]
ctdb/lib/replace/system/shmem.h [new file with mode: 0644]
ctdb/lib/replace/system/syslog.h [new file with mode: 0644]
ctdb/lib/replace/system/terminal.h [new file with mode: 0644]
ctdb/lib/replace/system/time.h [new file with mode: 0644]
ctdb/lib/replace/system/wait.h [new file with mode: 0644]
ctdb/lib/replace/system/wscript_configure [new file with mode: 0644]
ctdb/lib/replace/test/getifaddrs.c [new file with mode: 0644]
ctdb/lib/replace/test/incoherent_mmap.c [new file with mode: 0644]
ctdb/lib/replace/test/main.c [new file with mode: 0644]
ctdb/lib/replace/test/os2_delete.c [new file with mode: 0644]
ctdb/lib/replace/test/shared_mmap.c [new file with mode: 0644]
ctdb/lib/replace/test/shared_mremap.c [new file with mode: 0644]
ctdb/lib/replace/test/snprintf.c [new file with mode: 0644]
ctdb/lib/replace/test/strptime.c [new file with mode: 0644]
ctdb/lib/replace/test/testsuite.c [new file with mode: 0644]
ctdb/lib/replace/timegm.c [new file with mode: 0644]
ctdb/lib/replace/timegm.m4 [new file with mode: 0644]
ctdb/lib/replace/win32.m4 [new file with mode: 0644]
ctdb/lib/replace/win32_replace.h [new file with mode: 0644]
ctdb/lib/replace/wscript [new file with mode: 0644]
ctdb/lib/replace/xattr.c [new file with mode: 0644]
ctdb/lib/socket_wrapper/config.m4 [new file with mode: 0644]
ctdb/lib/socket_wrapper/socket_wrapper.c [new file with mode: 0644]
ctdb/lib/socket_wrapper/socket_wrapper.h [new file with mode: 0644]
ctdb/lib/socket_wrapper/testsuite.c [new file with mode: 0644]
ctdb/lib/socket_wrapper/wscript [new file with mode: 0644]
ctdb/lib/socket_wrapper/wscript_build [new file with mode: 0644]
ctdb/lib/talloc/ABI/pytalloc-util-2.0.6.sigs [new file with mode: 0644]
ctdb/lib/talloc/ABI/pytalloc-util-2.0.7.sigs [new file with mode: 0644]
ctdb/lib/talloc/ABI/pytalloc-util-2.0.8.sigs [new file with mode: 0644]
ctdb/lib/talloc/ABI/talloc-2.0.2.sigs [new file with mode: 0644]
ctdb/lib/talloc/ABI/talloc-2.0.3.sigs [new file with mode: 0644]
ctdb/lib/talloc/ABI/talloc-2.0.4.sigs [new file with mode: 0644]
ctdb/lib/talloc/ABI/talloc-2.0.5.sigs [new file with mode: 0644]
ctdb/lib/talloc/ABI/talloc-2.0.6.sigs [new file with mode: 0644]
ctdb/lib/talloc/ABI/talloc-2.0.7.sigs [new file with mode: 0644]
ctdb/lib/talloc/ABI/talloc-2.0.8.sigs [new file with mode: 0644]
ctdb/lib/talloc/NEWS [new file with mode: 0644]
ctdb/lib/talloc/compat/talloc_compat1.c [new file with mode: 0644]
ctdb/lib/talloc/compat/talloc_compat1.m4 [new file with mode: 0644]
ctdb/lib/talloc/compat/talloc_compat1.mk [new file with mode: 0644]
ctdb/lib/talloc/doc/context.png [new file with mode: 0644]
ctdb/lib/talloc/doc/context_tree.png [new file with mode: 0644]
ctdb/lib/talloc/doc/mainpage.dox [new file with mode: 0644]
ctdb/lib/talloc/doc/stealing.png [new file with mode: 0644]
ctdb/lib/talloc/doc/tutorial_bestpractices.dox [new file with mode: 0644]
ctdb/lib/talloc/doc/tutorial_context.dox [new file with mode: 0644]
ctdb/lib/talloc/doc/tutorial_debugging.dox [new file with mode: 0644]
ctdb/lib/talloc/doc/tutorial_destructors.dox [new file with mode: 0644]
ctdb/lib/talloc/doc/tutorial_dts.dox [new file with mode: 0644]
ctdb/lib/talloc/doc/tutorial_introduction.dox [new file with mode: 0644]
ctdb/lib/talloc/doc/tutorial_pools.dox [new file with mode: 0644]
ctdb/lib/talloc/doc/tutorial_stealing.dox [new file with mode: 0644]
ctdb/lib/talloc/doxy.config [new file with mode: 0644]
ctdb/lib/talloc/install-sh [new file with mode: 0755]
ctdb/lib/talloc/libtalloc.m4 [new file with mode: 0644]
ctdb/lib/talloc/pytalloc-util.pc.in [new file with mode: 0644]
ctdb/lib/talloc/pytalloc.c [new file with mode: 0644]
ctdb/lib/talloc/pytalloc.h [new file with mode: 0644]
ctdb/lib/talloc/pytalloc_util.c [new file with mode: 0644]
ctdb/lib/talloc/talloc.3.xml [new file with mode: 0644]
ctdb/lib/talloc/talloc.c [new file with mode: 0644]
ctdb/lib/talloc/talloc.h [new file with mode: 0644]
ctdb/lib/talloc/talloc.i [new file with mode: 0644]
ctdb/lib/talloc/talloc.pc.in [new file with mode: 0644]
ctdb/lib/talloc/talloc_guide.txt [new file with mode: 0644]
ctdb/lib/talloc/talloc_testsuite.h [new file with mode: 0644]
ctdb/lib/talloc/testsuite.c [new file with mode: 0644]
ctdb/lib/talloc/testsuite_main.c [new file with mode: 0644]
ctdb/lib/talloc/web/index.html [new file with mode: 0644]
ctdb/lib/talloc/wscript [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.1.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.10.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.11.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.2.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.3.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.4.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.5.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.6.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.7.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.8.sigs [new file with mode: 0644]
ctdb/lib/tdb/ABI/tdb-1.2.9.sigs [new file with mode: 0644]
ctdb/lib/tdb/common/check.c [new file with mode: 0644]
ctdb/lib/tdb/common/dump.c [new file with mode: 0644]
ctdb/lib/tdb/common/error.c [new file with mode: 0644]
ctdb/lib/tdb/common/freelist.c [new file with mode: 0644]
ctdb/lib/tdb/common/freelistcheck.c [new file with mode: 0644]
ctdb/lib/tdb/common/hash.c [new file with mode: 0644]
ctdb/lib/tdb/common/io.c [new file with mode: 0644]
ctdb/lib/tdb/common/lock.c [new file with mode: 0644]
ctdb/lib/tdb/common/open.c [new file with mode: 0644]
ctdb/lib/tdb/common/rescue.c [new file with mode: 0644]
ctdb/lib/tdb/common/summary.c [new file with mode: 0644]
ctdb/lib/tdb/common/tdb.c [new file with mode: 0644]
ctdb/lib/tdb/common/tdb_private.h [new file with mode: 0644]
ctdb/lib/tdb/common/transaction.c [new file with mode: 0644]
ctdb/lib/tdb/common/traverse.c [new file with mode: 0644]
ctdb/lib/tdb/docs/README [new file with mode: 0644]
ctdb/lib/tdb/docs/mainpage.dox [new file with mode: 0644]
ctdb/lib/tdb/docs/tdb.magic [new file with mode: 0644]
ctdb/lib/tdb/docs/tracing.txt [new file with mode: 0644]
ctdb/lib/tdb/doxy.config [new file with mode: 0644]
ctdb/lib/tdb/include/tdb.h [new file with mode: 0644]
ctdb/lib/tdb/libtdb.m4 [new file with mode: 0644]
ctdb/lib/tdb/manpages/tdbbackup.8.xml [new file with mode: 0644]
ctdb/lib/tdb/manpages/tdbdump.8.xml [new file with mode: 0644]
ctdb/lib/tdb/manpages/tdbrestore.8.xml [new file with mode: 0644]
ctdb/lib/tdb/manpages/tdbtool.8.xml [new file with mode: 0644]
ctdb/lib/tdb/pytdb.c [new file with mode: 0644]
ctdb/lib/tdb/python/tdbdump.py [new file with mode: 0644]
ctdb/lib/tdb/python/tests/simple.py [new file with mode: 0644]
ctdb/lib/tdb/tdb.pc.in [new file with mode: 0644]
ctdb/lib/tdb/test/external-agent.c [new file with mode: 0644]
ctdb/lib/tdb/test/external-agent.h [new file with mode: 0644]
ctdb/lib/tdb/test/jenkins-be-hash.tdb [new file with mode: 0644]
ctdb/lib/tdb/test/jenkins-le-hash.tdb [new file with mode: 0644]
ctdb/lib/tdb/test/lock-tracking.c [new file with mode: 0644]
ctdb/lib/tdb/test/lock-tracking.h [new file with mode: 0644]
ctdb/lib/tdb/test/logging.c [new file with mode: 0644]
ctdb/lib/tdb/test/logging.h [new file with mode: 0644]
ctdb/lib/tdb/test/old-nohash-be.tdb [new file with mode: 0644]
ctdb/lib/tdb/test/old-nohash-le.tdb [new file with mode: 0644]
ctdb/lib/tdb/test/run-3G-file.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-bad-tdb-header.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-check.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-corrupt.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-die-during-transaction.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-endian.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-incompatible.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-nested-transactions.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-nested-traverse.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-no-lock-during-traverse.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-oldhash.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-open-during-transaction.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-readonly-check.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-rescue-find_entry.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-rescue.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-rwlock-check.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-summary.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-transaction-expand.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-traverse-in-transaction.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-wronghash-fail.c [new file with mode: 0644]
ctdb/lib/tdb/test/run-zero-append.c [new file with mode: 0644]
ctdb/lib/tdb/test/run.c [new file with mode: 0644]
ctdb/lib/tdb/test/rwlock-be.tdb [new file with mode: 0644]
ctdb/lib/tdb/test/rwlock-le.tdb [new file with mode: 0644]
ctdb/lib/tdb/test/tap-interface.h [new file with mode: 0644]
ctdb/lib/tdb/test/tap-to-subunit.h [new file with mode: 0644]
ctdb/lib/tdb/test/tdb.corrupt [new file with mode: 0644]
ctdb/lib/tdb/tools/tdbbackup.c [new file with mode: 0644]
ctdb/lib/tdb/tools/tdbdump.c [new file with mode: 0644]
ctdb/lib/tdb/tools/tdbrestore.c [new file with mode: 0644]
ctdb/lib/tdb/tools/tdbtest.c [new file with mode: 0644]
ctdb/lib/tdb/tools/tdbtool.c [new file with mode: 0644]
ctdb/lib/tdb/tools/tdbtorture.c [new file with mode: 0644]
ctdb/lib/tdb/web/index.html [new file with mode: 0644]
ctdb/lib/tdb/wscript [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.10.sigs [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.11.sigs [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.12.sigs [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.13.sigs [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.14.sigs [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.15.sigs [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.16.sigs [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.17.sigs [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.18.sigs [new file with mode: 0644]
ctdb/lib/tevent/ABI/tevent-0.9.9.sigs [new file with mode: 0644]
ctdb/lib/tevent/bindings.py [new file with mode: 0644]
ctdb/lib/tevent/doc/mainpage.dox [new file with mode: 0644]
ctdb/lib/tevent/doc/tutorials.dox [new file with mode: 0644]
ctdb/lib/tevent/doxy.config [new file with mode: 0644]
ctdb/lib/tevent/libtevent.m4 [new file with mode: 0644]
ctdb/lib/tevent/pytevent.c [new file with mode: 0644]
ctdb/lib/tevent/release-script.sh [new file with mode: 0755]
ctdb/lib/tevent/testsuite.c [new file with mode: 0644]
ctdb/lib/tevent/tevent.c [new file with mode: 0644]
ctdb/lib/tevent/tevent.h [new file with mode: 0644]
ctdb/lib/tevent/tevent.pc.in [new file with mode: 0644]
ctdb/lib/tevent/tevent.py [new file with mode: 0644]
ctdb/lib/tevent/tevent_debug.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_epoll.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_fd.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_immediate.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_internal.h [new file with mode: 0644]
ctdb/lib/tevent/tevent_liboop.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_poll.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_queue.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_req.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_select.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_signal.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_standard.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_timed.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_util.c [new file with mode: 0644]
ctdb/lib/tevent/tevent_util.h [new file with mode: 0644]
ctdb/lib/tevent/tevent_wakeup.c [new file with mode: 0644]
ctdb/lib/tevent/wscript [new file with mode: 0755]
ctdb/lib/util/db_wrap.c [new file with mode: 0644]
ctdb/lib/util/db_wrap.h [new file with mode: 0644]
ctdb/lib/util/debug.c [new file with mode: 0644]
ctdb/lib/util/debug.h [new file with mode: 0644]
ctdb/lib/util/dlinklist.h [new file with mode: 0644]
ctdb/lib/util/fault.c [new file with mode: 0644]
ctdb/lib/util/fault.m4 [new file with mode: 0644]
ctdb/lib/util/idtree.c [new file with mode: 0644]
ctdb/lib/util/signal.c [new file with mode: 0644]
ctdb/lib/util/signal.m4 [new file with mode: 0644]
ctdb/lib/util/strlist.c [new file with mode: 0644]
ctdb/lib/util/substitute.c [new file with mode: 0644]
ctdb/lib/util/util.c [new file with mode: 0644]
ctdb/lib/util/util.h [new file with mode: 0644]
ctdb/lib/util/util_file.c [new file with mode: 0644]
ctdb/lib/util/util_time.c [new file with mode: 0644]
ctdb/packaging/RPM/ctdb.spec.in [new file with mode: 0644]
ctdb/packaging/RPM/makerpms.sh [new file with mode: 0755]
ctdb/packaging/maketarball.sh [new file with mode: 0755]
ctdb/packaging/mkversion.sh [new file with mode: 0755]
ctdb/server/ctdb_banning.c [new file with mode: 0644]
ctdb/server/ctdb_call.c [new file with mode: 0644]
ctdb/server/ctdb_control.c [new file with mode: 0644]
ctdb/server/ctdb_daemon.c [new file with mode: 0644]
ctdb/server/ctdb_freeze.c [new file with mode: 0644]
ctdb/server/ctdb_keepalive.c [new file with mode: 0644]
ctdb/server/ctdb_lock.c [new file with mode: 0644]
ctdb/server/ctdb_lock_helper.c [new file with mode: 0644]
ctdb/server/ctdb_logging.c [new file with mode: 0644]
ctdb/server/ctdb_ltdb_server.c [new file with mode: 0644]
ctdb/server/ctdb_monitor.c [new file with mode: 0644]
ctdb/server/ctdb_persistent.c [new file with mode: 0644]
ctdb/server/ctdb_recover.c [new file with mode: 0644]
ctdb/server/ctdb_recoverd.c [new file with mode: 0644]
ctdb/server/ctdb_server.c [new file with mode: 0644]
ctdb/server/ctdb_serverids.c [new file with mode: 0644]
ctdb/server/ctdb_statistics.c [new file with mode: 0644]
ctdb/server/ctdb_takeover.c [new file with mode: 0644]
ctdb/server/ctdb_traverse.c [new file with mode: 0644]
ctdb/server/ctdb_tunables.c [new file with mode: 0644]
ctdb/server/ctdb_update_record.c [new file with mode: 0644]
ctdb/server/ctdb_uptime.c [new file with mode: 0644]
ctdb/server/ctdb_vacuum.c [new file with mode: 0644]
ctdb/server/ctdbd.c [new file with mode: 0644]
ctdb/server/eventscript.c [new file with mode: 0644]
ctdb/tcp/ctdb_tcp.h [new file with mode: 0644]
ctdb/tcp/tcp_connect.c [new file with mode: 0644]
ctdb/tcp/tcp_init.c [new file with mode: 0644]
ctdb/tcp/tcp_io.c [new file with mode: 0644]
ctdb/tests/INSTALL [new file with mode: 0755]
ctdb/tests/README [new file with mode: 0644]
ctdb/tests/TODO [new file with mode: 0644]
ctdb/tests/complex/11_ctdb_delip_removes_ip.sh [new file with mode: 0755]
ctdb/tests/complex/31_nfs_tickle.sh [new file with mode: 0755]
ctdb/tests/complex/32_cifs_tickle.sh [new file with mode: 0755]
ctdb/tests/complex/33_gratuitous_arp.sh [new file with mode: 0755]
ctdb/tests/complex/41_failover_ping_discrete.sh [new file with mode: 0755]
ctdb/tests/complex/42_failover_ssh_hostname.sh [new file with mode: 0755]
ctdb/tests/complex/43_failover_nfs_basic.sh [new file with mode: 0755]
ctdb/tests/complex/44_failover_nfs_oneway.sh [new file with mode: 0755]
ctdb/tests/complex/45_failover_nfs_kill.sh [new file with mode: 0755]
ctdb/tests/complex/README [new file with mode: 0644]
ctdb/tests/complex/scripts/local.bash [new file with mode: 0644]
ctdb/tests/events.d/00.test [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.003.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.004.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.005.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.006.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.007.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.008.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.021.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.022.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.init.023.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.monitor.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.monitor.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.monitor.003.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.monitor.004.sh [new file with mode: 0755]
ctdb/tests/eventscripts/00.ctdb.monitor.005.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.init.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.init.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.003.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.004.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.005.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.006.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.007.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.008.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.009.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.010.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.011.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.012.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.013.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.014.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.015.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.monitor.016.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.multi.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.releaseip.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.releaseip.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.releaseip.010.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.releaseip.011.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.startup.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.startup.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.takeip.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.takeip.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/10.interface.takeip.003.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.003.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.004.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.005.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.006.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.007.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.008.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.009.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.010.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.011.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.012.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.013.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.014.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.015.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.016.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.017.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.018.sh [new file with mode: 0755]
ctdb/tests/eventscripts/13.per_ip_routing.019.sh [new file with mode: 0755]
ctdb/tests/eventscripts/20.multipathd.monitor.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/20.multipathd.monitor.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/20.multipathd.monitor.003.sh [new file with mode: 0755]
ctdb/tests/eventscripts/20.multipathd.monitor.004.sh [new file with mode: 0755]
ctdb/tests/eventscripts/40.vsftpd.monitor.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/41.httpd.monitor.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/49.winbind.monitor.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/49.winbind.monitor.050.sh [new file with mode: 0755]
ctdb/tests/eventscripts/49.winbind.monitor.051.sh [new file with mode: 0755]
ctdb/tests/eventscripts/49.winbind.monitor.101.sh [new file with mode: 0755]
ctdb/tests/eventscripts/49.winbind.monitor.102.sh [new file with mode: 0755]
ctdb/tests/eventscripts/50.samba.monitor.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/50.samba.monitor.050.sh [new file with mode: 0755]
ctdb/tests/eventscripts/50.samba.monitor.051.sh [new file with mode: 0755]
ctdb/tests/eventscripts/50.samba.monitor.101.sh [new file with mode: 0755]
ctdb/tests/eventscripts/50.samba.monitor.103.sh [new file with mode: 0755]
ctdb/tests/eventscripts/50.samba.monitor.104.sh [new file with mode: 0755]
ctdb/tests/eventscripts/50.samba.monitor.105.sh [new file with mode: 0755]
ctdb/tests/eventscripts/50.samba.monitor.106.sh [new file with mode: 0755]
ctdb/tests/eventscripts/50.samba.monitor.107.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.ganesha.monitor.101.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.ganesha.monitor.131.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.ganesha.monitor.141.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.101.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.102.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.103.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.104.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.111.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.112.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.113.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.114.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.121.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.122.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.131.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.132.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.141.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.142.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.151.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.152.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.153.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.161.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.monitor.162.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.multi.001.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.multi.002.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.multi.003.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.multi.004.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.multi.005.sh [new file with mode: 0755]
ctdb/tests/eventscripts/60.nfs.multi.006.sh [new file with mode: 0755]
ctdb/tests/eventscripts/README [new file with mode: 0644]
ctdb/tests/eventscripts/etc-ctdb/events.d [new symlink]
ctdb/tests/eventscripts/etc-ctdb/functions [new symlink]
ctdb/tests/eventscripts/etc-ctdb/nfs-rpc-checks.d [new symlink]
ctdb/tests/eventscripts/etc-ctdb/public_addresses [new file with mode: 0644]
ctdb/tests/eventscripts/etc-ctdb/rc.local [new file with mode: 0755]
ctdb/tests/eventscripts/etc-ctdb/statd-callout [new file with mode: 0755]
ctdb/tests/eventscripts/etc/init.d/nfs [new file with mode: 0755]
ctdb/tests/eventscripts/etc/init.d/nfslock [new file with mode: 0755]
ctdb/tests/eventscripts/etc/samba/smb.conf [new file with mode: 0644]
ctdb/tests/eventscripts/etc/sysconfig/ctdb [new file with mode: 0644]
ctdb/tests/eventscripts/etc/sysconfig/nfs [new file with mode: 0644]
ctdb/tests/eventscripts/scripts/local.sh [new file with mode: 0644]
ctdb/tests/eventscripts/stubs/ctdb [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/date [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/ethtool [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/exportfs [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/free [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/ip [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/iptables [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/kill [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/killall [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/multipath [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/net [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/netstat [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/nmap [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/pidof [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/pkill [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/ps [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/rpc.lockd [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/rpc.mountd [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/rpc.rquotad [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/rpc.statd [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/rpcinfo [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/service [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/sleep [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/tdbdump [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/tdbtool [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/testparm [new file with mode: 0755]
ctdb/tests/eventscripts/stubs/wbinfo [new file with mode: 0755]
ctdb/tests/onnode/0001.sh [new file with mode: 0755]
ctdb/tests/onnode/0002.sh [new file with mode: 0755]
ctdb/tests/onnode/0003.sh [new file with mode: 0755]
ctdb/tests/onnode/0004.sh [new file with mode: 0755]
ctdb/tests/onnode/0005.sh [new file with mode: 0755]
ctdb/tests/onnode/0006.sh [new file with mode: 0755]
ctdb/tests/onnode/0070.sh [new file with mode: 0755]
ctdb/tests/onnode/0071.sh [new file with mode: 0755]
ctdb/tests/onnode/0072.sh [new file with mode: 0755]
ctdb/tests/onnode/0075.sh [new file with mode: 0755]
ctdb/tests/onnode/0080.sh [new file with mode: 0755]
ctdb/tests/onnode/0081.sh [new file with mode: 0755]
ctdb/tests/onnode/0090.sh [new file with mode: 0755]
ctdb/tests/onnode/0091.sh [new file with mode: 0755]
ctdb/tests/onnode/README [new file with mode: 0644]
ctdb/tests/onnode/nodes [new file with mode: 0644]
ctdb/tests/onnode/scripts/local.sh [new file with mode: 0644]
ctdb/tests/onnode/stubs/ctdb [new file with mode: 0755]
ctdb/tests/onnode/stubs/onnode-buggy-001 [new file with mode: 0755]
ctdb/tests/onnode/stubs/ssh [new file with mode: 0755]
ctdb/tests/recover.sh [new file with mode: 0755]
ctdb/tests/run_cluster_tests.sh [new symlink]
ctdb/tests/run_tests.sh [new file with mode: 0755]
ctdb/tests/scripts/common.sh [new file with mode: 0644]
ctdb/tests/scripts/integration.bash [new file with mode: 0644]
ctdb/tests/scripts/run_tests [new file with mode: 0755]
ctdb/tests/scripts/test_wrap [new file with mode: 0755]
ctdb/tests/scripts/unit.sh [new file with mode: 0644]
ctdb/tests/simple/00_ctdb_init.sh [new file with mode: 0755]
ctdb/tests/simple/00_ctdb_onnode.sh [new file with mode: 0755]
ctdb/tests/simple/01_ctdb_version.sh [new file with mode: 0755]
ctdb/tests/simple/02_ctdb_listvars.sh [new file with mode: 0755]
ctdb/tests/simple/03_ctdb_getvar.sh [new file with mode: 0755]
ctdb/tests/simple/04_ctdb_setvar.sh [new file with mode: 0755]
ctdb/tests/simple/05_ctdb_listnodes.sh [new file with mode: 0755]
ctdb/tests/simple/06_ctdb_getpid.sh [new file with mode: 0755]
ctdb/tests/simple/07_ctdb_process_exists.sh [new file with mode: 0755]
ctdb/tests/simple/08_ctdb_isnotrecmaster.sh [new file with mode: 0755]
ctdb/tests/simple/09_ctdb_ping.sh [new file with mode: 0755]
ctdb/tests/simple/11_ctdb_ip.sh [new file with mode: 0755]
ctdb/tests/simple/12_ctdb_getdebug.sh [new file with mode: 0755]
ctdb/tests/simple/13_ctdb_setdebug.sh [new file with mode: 0755]
ctdb/tests/simple/14_ctdb_statistics.sh [new file with mode: 0755]
ctdb/tests/simple/15_ctdb_statisticsreset.sh [new file with mode: 0755]
ctdb/tests/simple/16_ctdb_config_add_ip.sh [new file with mode: 0755]
ctdb/tests/simple/17_ctdb_config_delete_ip.sh [new file with mode: 0755]
ctdb/tests/simple/18_ctdb_reloadips.sh [new file with mode: 0755]
ctdb/tests/simple/20_delip_iface_gc.sh [new file with mode: 0755]
ctdb/tests/simple/23_ctdb_moveip.sh [new file with mode: 0755]
ctdb/tests/simple/24_ctdb_getdbmap.sh [new file with mode: 0755]
ctdb/tests/simple/25_dumpmemory.sh [new file with mode: 0755]
ctdb/tests/simple/26_ctdb_config_check_error_on_unreachable_ctdb.sh [new file with mode: 0755]
ctdb/tests/simple/31_ctdb_disable.sh [new file with mode: 0755]
ctdb/tests/simple/32_ctdb_enable.sh [new file with mode: 0755]
ctdb/tests/simple/41_ctdb_stop.sh [new file with mode: 0755]
ctdb/tests/simple/42_ctdb_continue.sh [new file with mode: 0755]
ctdb/tests/simple/43_stop_recmaster_yield.sh [new file with mode: 0755]
ctdb/tests/simple/51_ctdb_bench.sh [new file with mode: 0755]
ctdb/tests/simple/52_ctdb_fetch.sh [new file with mode: 0755]
ctdb/tests/simple/53_ctdb_transaction.sh [new file with mode: 0755]
ctdb/tests/simple/54_ctdb_transaction_recovery.sh [new file with mode: 0755]
ctdb/tests/simple/60_recoverd_missing_ip.sh [new file with mode: 0755]
ctdb/tests/simple/70_recoverpdbbyseqnum.sh [new file with mode: 0755]
ctdb/tests/simple/71_ctdb_wipedb.sh [new file with mode: 0755]
ctdb/tests/simple/72_update_record_persistent.sh [new file with mode: 0755]
ctdb/tests/simple/73_tunable_NoIPTakeover.sh [new file with mode: 0755]
ctdb/tests/simple/75_readonly_records_basic.sh [new file with mode: 0755]
ctdb/tests/simple/76_ctdb_pdb_recovery.sh [new file with mode: 0755]
ctdb/tests/simple/77_ctdb_db_recovery.sh [new file with mode: 0755]
ctdb/tests/simple/80_ctdb_traverse.sh [new file with mode: 0755]
ctdb/tests/simple/99_daemons_shutdown.sh [new file with mode: 0755]
ctdb/tests/simple/README [new file with mode: 0644]
ctdb/tests/src/ctdb_bench.c [new file with mode: 0644]
ctdb/tests/src/ctdb_fetch.c [new file with mode: 0644]
ctdb/tests/src/ctdb_fetch_one.c [new file with mode: 0644]
ctdb/tests/src/ctdb_fetch_readonly_loop.c [new file with mode: 0644]
ctdb/tests/src/ctdb_fetch_readonly_once.c [new file with mode: 0644]
ctdb/tests/src/ctdb_functest.c [new file with mode: 0644]
ctdb/tests/src/ctdb_lock_tdb.c [new file with mode: 0644]
ctdb/tests/src/ctdb_persistent.c [new file with mode: 0644]
ctdb/tests/src/ctdb_porting_tests.c [new file with mode: 0644]
ctdb/tests/src/ctdb_randrec.c [new file with mode: 0644]
ctdb/tests/src/ctdb_store.c [new file with mode: 0644]
ctdb/tests/src/ctdb_takeover_tests.c [new file with mode: 0644]
ctdb/tests/src/ctdb_test.c [new file with mode: 0644]
ctdb/tests/src/ctdb_test_stubs.c [new file with mode: 0644]
ctdb/tests/src/ctdb_trackingdb_test.c [new file with mode: 0644]
ctdb/tests/src/ctdb_transaction.c [new file with mode: 0644]
ctdb/tests/src/ctdb_traverse.c [new file with mode: 0644]
ctdb/tests/src/ctdb_update_record.c [new file with mode: 0644]
ctdb/tests/src/ctdb_update_record_persistent.c [new file with mode: 0644]
ctdb/tests/src/ctdbd_test.c [new file with mode: 0644]
ctdb/tests/src/rb_perftest.c [new file with mode: 0644]
ctdb/tests/src/rb_test.c [new file with mode: 0644]
ctdb/tests/takeover/README [new file with mode: 0644]
ctdb/tests/takeover/det.001.sh [new file with mode: 0755]
ctdb/tests/takeover/det.002.sh [new file with mode: 0755]
ctdb/tests/takeover/det.003.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.001.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.002.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.003.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.004.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.005.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.006.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.007.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.008.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.009.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.010.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.011.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.012.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.013.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.014.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.015.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.016.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.017.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.018.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.019.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.020.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.021.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.022.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.023.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.024.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.025.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.026.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.027.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.028.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.029.sh [new file with mode: 0755]
ctdb/tests/takeover/lcp2.030.sh [new file with mode: 0755]
ctdb/tests/takeover/nondet.001.sh [new file with mode: 0755]
ctdb/tests/takeover/nondet.002.sh [new file with mode: 0755]
ctdb/tests/takeover/nondet.003.sh [new file with mode: 0755]
ctdb/tests/takeover/scripts/local.sh [new file with mode: 0644]
ctdb/tests/takeover/simulation/README [new file with mode: 0644]
ctdb/tests/takeover/simulation/ctdb_takeover.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/hey_jude.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/ip_groups1.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/ip_groups2.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/ip_groups3.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/ip_groups4.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/ip_groups5.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/mgmt_simple.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/node_group.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/node_group_extra.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/node_group_simple.py [new file with mode: 0755]
ctdb/tests/takeover/simulation/nondet_path_01.py [new file with mode: 0755]
ctdb/tests/test_check_tcp_ports.sh [new file with mode: 0755]
ctdb/tests/tool/README [new file with mode: 0644]
ctdb/tests/tool/func.parse_nodestring.001.sh [new file with mode: 0755]
ctdb/tests/tool/func.parse_nodestring.002.sh [new file with mode: 0755]
ctdb/tests/tool/func.parse_nodestring.003.sh [new file with mode: 0755]
ctdb/tests/tool/scripts/local.sh [new file with mode: 0644]
ctdb/tests/tool/stubby.getcapabilities.001.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.getcapabilities.002.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.getcapabilities.003.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.lvs.001.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.lvsmaster.001.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.lvsmaster.002.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.natgwlist.001.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.natgwlist.002.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.natgwlist.003.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.natgwlist.004.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.natgwlist.005.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.nodestatus.001.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.nodestatus.002.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.nodestatus.003.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.nodestatus.004.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.nodestatus.005.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.status.001.sh [new file with mode: 0755]
ctdb/tests/tool/stubby.status.002.sh [new file with mode: 0755]
ctdb/tests/tool/testcases/stubby.nodestatus.005.sh [new file with mode: 0755]
ctdb/tools/ctdb.c [new file with mode: 0644]
ctdb/tools/ctdb_diagnostics [new file with mode: 0755]
ctdb/tools/ctdb_vacuum.c [new file with mode: 0644]
ctdb/tools/ltdbtool.c [new file with mode: 0644]
ctdb/tools/onnode [new file with mode: 0755]
ctdb/utils/nagios/README [new file with mode: 0644]
ctdb/utils/nagios/check_ctdb [new file with mode: 0644]
ctdb/utils/ping_pong/ping_pong.c [new file with mode: 0644]
ctdb/utils/pmda/Install [new file with mode: 0644]
ctdb/utils/pmda/README [new file with mode: 0644]
ctdb/utils/pmda/Remove [new file with mode: 0644]
ctdb/utils/pmda/config.m4 [new file with mode: 0644]
ctdb/utils/pmda/domain.h [new file with mode: 0644]
ctdb/utils/pmda/help [new file with mode: 0644]
ctdb/utils/pmda/pmda_ctdb.c [new file with mode: 0644]
ctdb/utils/pmda/pmns [new file with mode: 0644]
ctdb/utils/pmda/root [new file with mode: 0644]
ctdb/utils/scsi_io/scsi_io.c [new file with mode: 0644]
ctdb/utils/smnotify/smnotify.c [new file with mode: 0644]
ctdb/utils/smnotify/smnotify.x [new file with mode: 0644]
ctdb/web/bar1.jpg [new file with mode: 0644]
ctdb/web/building.html [new file with mode: 0644]
ctdb/web/clamd.html [new file with mode: 0644]
ctdb/web/configuring.html [new file with mode: 0644]
ctdb/web/ctdblogo.png [new file with mode: 0644]
ctdb/web/documentation.html [new file with mode: 0644]
ctdb/web/download.html [new file with mode: 0644]
ctdb/web/footer.html [new file with mode: 0644]
ctdb/web/ftp.html [new file with mode: 0644]
ctdb/web/header.html [new file with mode: 0644]
ctdb/web/index.html [new file with mode: 0644]
ctdb/web/iscsi.html [new file with mode: 0644]
ctdb/web/nfs.html [new file with mode: 0644]
ctdb/web/prerequisites.html [new file with mode: 0644]
ctdb/web/samba.html [new file with mode: 0644]
ctdb/web/testing.html [new file with mode: 0644]

diff --git a/ctdb/.bzrignore b/ctdb/.bzrignore
new file mode 100644 (file)
index 0000000..6560aa4
--- /dev/null
@@ -0,0 +1,24 @@
+config.status
+Makefile
+bin
+config.log
+push.sh
+ctdb_test
+config.cache
+configure
+config.h
+config.h.in
+nodes-ssh.txt
+TAGS
+ctdb-0
+ctdb-1
+ctdb-2
+ctdb-3
+nodes.txt
+TAGS
+web/packages
+rec.lock
+test.db
+sock.1
+sock.3
+sock.4
diff --git a/ctdb/.gitignore b/ctdb/.gitignore
new file mode 100644 (file)
index 0000000..9e8c581
--- /dev/null
@@ -0,0 +1,34 @@
+*.[oa]
+*~
+*.swp
+config.status
+configure
+ctdb.pc
+publish*.sh
+push*.sh
+web/packages
+TAGS
+tags
+bin
+Makefile
+config.h
+config.h.in
+config.log
+utils/smnotify/gen_smnotify.c
+utils/smnotify/gen_xdr.c
+utils/smnotify/smnotify.h
+nodes.txt
+public_addresses.txt
+rec.lock
+test.db
+tests/bin
+tests/events.d/00.ctdb_test_trigger
+tests/var
+tests/takeover/ctdb_takeover.pyc
+tests/eventscripts/var
+tests/eventscripts/etc/iproute2
+tests/eventscripts/etc-ctdb/policy_routing
+include/ctdb_version.h
+packaging/RPM/ctdb.spec
+doc/*.[1-7]
+doc/*.[1-7].html
diff --git a/ctdb/COPYING b/ctdb/COPYING
new file mode 100644 (file)
index 0000000..94a9ed0
--- /dev/null
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/ctdb/Makefile.in b/ctdb/Makefile.in
new file mode 100755 (executable)
index 0000000..55b21b7
--- /dev/null
@@ -0,0 +1,408 @@
+#!gmake
+
+
+CC = @CC@
+AR = ar
+ARFLAGS = cru
+RANLIB = ranlib
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datarootdir = @datarootdir@
+includedir = @includedir@
+docdir = @docdir@
+libdir = @libdir@
+bindir = @bindir@
+sbindir = @sbindir@
+mandir = @mandir@
+localstatedir = @localstatedir@
+logdir = @LOGDIR@
+sockpath = @SOCKPATH@
+VPATH = @srcdir@:@tdbdir@:@tallocdir@:@libreplacedir@:@poptdir@:@teventdir@:
+srcdir = @srcdir@
+etcdir = @sysconfdir@
+builddir = @builddir@
+DESTDIR = /
+EXTRA_OBJ=@EXTRA_OBJ@
+XSLTPROC = /usr/bin/xsltproc
+INSTALLCMD = @INSTALL@
+
+POPT_LIBS = @POPT_LIBS@
+POPT_CFLAGS = @POPT_CFLAGS@
+POPT_OBJ = @POPT_OBJ@
+
+TALLOC_LIBS = @TALLOC_LIBS@
+TALLOC_CFLAGS = @TALLOC_CFLAGS@
+TALLOC_OBJ = @TALLOC_OBJ@
+
+TEVENT_LIBS = @TEVENT_LIBS@
+TEVENT_CFLAGS = @TEVENT_CFLAGS@
+TEVENT_OBJ = @TEVENT_OBJ@
+
+TDB_LIBS = @TDB_LIBS@
+TDB_CFLAGS = @TDB_CFLAGS@
+TDB_OBJ = @TDB_OBJ@
+
+REPLACE_OBJ = @LIBREPLACEOBJ@
+
+SOCKET_WRAPPER_OBJ = @SOCKET_WRAPPER_OBJS@
+
+PMDA_LIBS = -lpcp -lpcp_pmda
+PMDA_INSTALL = @CTDB_PMDA_INSTALL@
+PMDA_DEST_DIR = /var/lib/pcp/pmdas/ctdb
+
+WRAPPER=@
+ifeq ($(V),1)
+WRAPPER=
+endif
+ifeq ($(VERBOSE),1)
+WRAPPER=
+endif
+
+ifeq ($(CC),gcc)
+EXTRA_CFLAGS=-Wno-format-zero-length -Wno-deprecated-declarations -fPIC
+endif
+
+CFLAGS=@CPPFLAGS@ -g -I$(srcdir)/include -Iinclude -Ilib -Ilib/util -I$(srcdir) \
+       $(TALLOC_CFLAGS) $(TEVENT_CFLAGS) $(TDB_CFLAGS) -I@libreplacedir@ \
+       -DVARDIR=\"$(localstatedir)\" -DETCDIR=\"$(etcdir)\" \
+       -DCTDB_VARDIR=\"$(localstatedir)/lib/ctdb\" \
+       -DLOGDIR=\"$(logdir)\" -DBINDIR=\"$(bindir)\" \
+       -DSOCKPATH=\"$(sockpath)\" \
+       -DUSE_MMAP=1 @CFLAGS@ $(POPT_CFLAGS) \
+       $(EXTRA_CFLAGS)
+
+LDSHFLAGS=-fPIC -shared
+#LDSHFLAGS=-fPIC -shared -Wl,-Bsymbolic -Wl,-z,relo -Wl,-Bsymbolic-funtions -Wl,--as-needed -Wl,-z,defs
+SHLD=${CC} ${CFLAGS} ${LDSHFLAGS} -o $@
+
+LIB_FLAGS=@LDFLAGS@ -Llib @LIBS@ $(POPT_LIBS) $(TALLOC_LIBS) $(TEVENT_LIBS) $(TDB_LIBS) \
+                 @INFINIBAND_LIBS@ @CTDB_PCAP_LDFLAGS@
+
+CTDB_VERSION_H = include/ctdb_version.h
+
+UTIL_OBJ = lib/util/idtree.o lib/util/db_wrap.o lib/util/strlist.o lib/util/util.o \
+       lib/util/util_time.o lib/util/util_file.o lib/util/fault.o lib/util/substitute.o \
+       lib/util/signal.o
+
+CTDB_COMMON_OBJ =  common/ctdb_io.o common/ctdb_util.o \
+       common/ctdb_ltdb.o common/ctdb_message.o common/cmdline.o  \
+       lib/util/debug.o common/rb_tree.o @CTDB_SYSTEM_OBJ@ common/system_common.o \
+       common/ctdb_logging.o common/ctdb_fork.o
+
+CTDB_TCP_OBJ = tcp/tcp_connect.o tcp/tcp_io.o tcp/tcp_init.o
+
+CTDB_EXTERNAL_OBJ = $(POPT_OBJ) $(TALLOC_OBJ) $(TDB_OBJ) \
+       $(REPLACE_OBJ) $(EXTRA_OBJ) $(TEVENT_OBJ) $(SOCKET_WRAPPER_OBJ)
+
+CTDB_CLIENT_OBJ = client/ctdb_client.o \
+       $(CTDB_COMMON_OBJ) $(UTIL_OBJ) $(CTDB_EXTERNAL_OBJ)
+
+CTDB_SERVER_OBJ = server/ctdbd.o server/ctdb_daemon.o \
+       server/ctdb_recoverd.o server/ctdb_recover.o server/ctdb_freeze.o \
+       server/ctdb_tunables.o server/ctdb_monitor.o server/ctdb_server.o \
+       server/ctdb_control.o server/ctdb_call.o server/ctdb_ltdb_server.o \
+       server/ctdb_traverse.o server/eventscript.o server/ctdb_takeover.o \
+       server/ctdb_serverids.o server/ctdb_persistent.o \
+       server/ctdb_keepalive.o server/ctdb_logging.o server/ctdb_uptime.o \
+       server/ctdb_vacuum.o server/ctdb_banning.o server/ctdb_statistics.o \
+       server/ctdb_update_record.o server/ctdb_lock.o \
+       $(CTDB_CLIENT_OBJ) $(CTDB_TCP_OBJ) @INFINIBAND_WRAPPER_OBJ@
+
+TEST_BINS=tests/bin/ctdb_bench tests/bin/ctdb_fetch tests/bin/ctdb_fetch_one \
+       tests/bin/ctdb_fetch_readonly_once tests/bin/ctdb_fetch_readonly_loop \
+       tests/bin/ctdb_store tests/bin/ctdb_trackingdb_test \
+       tests/bin/ctdb_randrec tests/bin/ctdb_persistent \
+       tests/bin/ctdb_traverse tests/bin/rb_test tests/bin/ctdb_transaction \
+       tests/bin/ctdb_takeover_tests tests/bin/ctdb_update_record \
+       tests/bin/ctdb_update_record_persistent \
+       tests/bin/ctdb_functest tests/bin/ctdb_stubtest \
+       tests/bin/ctdb_porting_tests tests/bin/ctdb_lock_tdb \
+       @INFINIBAND_BINS@
+
+BINS = bin/ctdb @CTDB_SCSI_IO@ bin/smnotify bin/ping_pong bin/ltdbtool \
+       bin/ctdb_lock_helper @CTDB_PMDA@
+
+SBINS = bin/ctdbd
+
+DIRS = lib bin tests/bin
+
+.SUFFIXES: .c .o .h
+
+all: showflags dirs $(CTDB_VERSION_H) $(CTDB_SERVER_OBJ) $(CTDB_CLIENT_OBJ) $(BINS) $(SBINS) $(TEST_BINS)
+
+showflags:
+       @echo 'ctdb will be compiled with flags:'
+       @echo '  CFLAGS = $(CFLAGS)'
+       @echo '  LIBS = $(LIB_FLAGS)'
+
+showlayout::
+       @echo "ctdb will be installed into:"
+       @echo "  prefix:      $(prefix)"
+       @echo "  bindir:      $(bindir)"
+       @echo "  sbindir:     $(sbindir)"
+       @echo "  libdir:      $(libdir)"
+       @echo "  vardir:      $(localstatedir)"
+       @echo "  logdir:      $(logdir)"
+       @echo "  mandir:      $(mandir)"
+       @echo "  etcdir:      $(etcdir)"
+
+.c.o:
+       @echo Compiling $*.c
+       @mkdir -p `dirname $@`
+       $(WRAPPER) $(CC) $(CFLAGS) -c $< -o $@
+
+dirs:
+       $(WRAPPER) mkdir -p $(DIRS)
+
+$(CTDB_VERSION_H):
+       @echo Generating $@
+       $(WRAPPER) ./packaging/mkversion.sh
+
+bin/ctdbd: $(CTDB_SERVER_OBJ)
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ $(CTDB_SERVER_OBJ) $(LIB_FLAGS)
+
+bin/scsi_io: $(CTDB_CLIENT_OBJ) utils/scsi_io/scsi_io.o 
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ utils/scsi_io/scsi_io.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+bin/ctdb: $(CTDB_CLIENT_OBJ) tools/ctdb.o tools/ctdb_vacuum.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tools/ctdb.o tools/ctdb_vacuum.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+bin/ltdbtool: tools/ltdbtool.o $(TDB_OBJ)
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ $+ $(TDB_LIBS) $(LIB_FLAGS)
+
+bin/ctdb_lock_helper: server/ctdb_lock_helper.o lib/util/util_file.o $(CTDB_EXTERNAL_OBJ)
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ server/ctdb_lock_helper.o lib/util/util_file.o $(CTDB_EXTERNAL_OBJ) $(TDB_LIBS) $(LIB_FLAGS)
+
+bin/smnotify: utils/smnotify/gen_xdr.o utils/smnotify/gen_smnotify.o utils/smnotify/smnotify.o $(POPT_OBJ)
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ utils/smnotify/smnotify.o utils/smnotify/gen_xdr.o utils/smnotify/gen_smnotify.o $(POPT_OBJ) $(LIB_FLAGS)
+
+utils/smnotify/smnotify.o: utils/smnotify/smnotify.c utils/smnotify/smnotify.h
+
+utils/smnotify/smnotify.h:  utils/smnotify/smnotify.x
+       @echo Generating $@
+       $(WRAPPER) rpcgen -h utils/smnotify/smnotify.x > utils/smnotify/smnotify.h
+
+utils/smnotify/gen_xdr.c: utils/smnotify/smnotify.x utils/smnotify/smnotify.h
+       @echo Generating $@
+       $(WRAPPER) rpcgen -c utils/smnotify/smnotify.x | grep -Ev '^[[:space:]]+register int32_t \*buf;' > utils/smnotify/gen_xdr.c 
+
+utils/smnotify/gen_smnotify.c: utils/smnotify/smnotify.x utils/smnotify/smnotify.h
+       @echo Generating $@
+       $(WRAPPER) rpcgen -l utils/smnotify/smnotify.x > utils/smnotify/gen_smnotify.c 
+
+bin/ping_pong: utils/ping_pong/ping_pong.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ utils/ping_pong/ping_pong.o $(LIB_FLAGS)
+
+bin/pmdactdb: $(CTDB_CLIENT_OBJ) utils/pmda/pmda_ctdb.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ utils/pmda/pmda_ctdb.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS) $(PMDA_LIBS)
+
+tests/bin/rb_test: $(CTDB_CLIENT_OBJ) tests/src/rb_test.o 
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/rb_test.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_bench: $(CTDB_CLIENT_OBJ) tests/src/ctdb_bench.o 
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_bench.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_fetch: $(CTDB_CLIENT_OBJ) tests/src/ctdb_fetch.o 
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_fetch.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_fetch_one: $(CTDB_CLIENT_OBJ) tests/src/ctdb_fetch_one.o 
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_fetch_one.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_fetch_readonly_once: tests/src/ctdb_fetch_readonly_once.o $(CTDB_CLIENT_OBJ)
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_fetch_readonly_once.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_fetch_readonly_loop: $(CTDB_CLIENT_OBJ) tests/src/ctdb_fetch_readonly_loop.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_fetch_readonly_loop.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_trackingdb_test: $(CTDB_CLIENT_OBJ) tests/src/ctdb_trackingdb_test.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_trackingdb_test.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_update_record: $(CTDB_CLIENT_OBJ) tests/src/ctdb_update_record.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_update_record.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_update_record_persistent: $(CTDB_CLIENT_OBJ) tests/src/ctdb_update_record_persistent.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_update_record_persistent.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_store: $(CTDB_CLIENT_OBJ) tests/src/ctdb_store.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_store.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_traverse: $(CTDB_CLIENT_OBJ) tests/src/ctdb_traverse.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_traverse.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_randrec: $(CTDB_CLIENT_OBJ) tests/src/ctdb_randrec.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_randrec.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_persistent: $(CTDB_CLIENT_OBJ) tests/src/ctdb_persistent.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_persistent.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_porting_tests: $(CTDB_CLIENT_OBJ) tests/src/ctdb_porting_tests.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_porting_tests.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_transaction: $(CTDB_CLIENT_OBJ) tests/src/ctdb_transaction.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_transaction.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+CTDB_SERVER_MOST_OBJ = $(CTDB_SERVER_OBJ:server/ctdbd.o=)
+CTDBD_TEST_C = $(CTDB_SERVER_MOST_OBJ:.o=.c) tests/src/ctdbd_test.c
+
+CTDB_TEST_C =  $(CTDB_CLIENT_OBJ:.o=.c) tools/ctdb.c tools/ctdb_vacuum.c tests/src/ctdb_test_stubs.c
+
+CTDB_TEST_OBJ =  $(TALLOC_OBJ) $(TDB_OBJ) \
+       @CTDB_SYSTEM_OBJ@ $(REPLACE_OBJ) $(EXTRA_OBJ) $(TEVENT_OBJ) $(SOCKET_WRAPPER_OBJ)
+
+tests/src/ctdb_takeover_tests.o: tests/src/ctdb_takeover_tests.c $(CTDBD_TEST_C)
+
+tests/bin/ctdb_takeover_tests: $(CTDB_TEST_OBJ) tests/src/ctdb_takeover_tests.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ tests/src/ctdb_takeover_tests.o $(CTDB_TEST_OBJ) $(LIB_FLAGS)
+
+tests/src/ctdb_functest.o: tests/src/ctdb_functest.c tests/src/ctdb_test.c $(CTDB_TEST_C)
+
+tests/bin/ctdb_functest: tests/src/ctdb_functest.o $(CTDB_TEST_OBJ) 
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ $^ $(POPT_OBJ) $(LIB_FLAGS)
+
+tests/src/ctdb_test.o: tests/src/ctdb_test.c $(CTDB_TEST_C)
+
+tests/bin/ctdb_stubtest: tests/src/ctdb_test.o $(CTDB_TEST_OBJ)
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ $^ $(POPT_OBJ) $(LIB_FLAGS)
+
+tests/bin/ctdb_lock_tdb: tests/src/ctdb_lock_tdb.o $(CTDB_CLIENT_OBJ)
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ $^ $(LIB_FLAGS)
+
+tests/bin/ibwrapper_test: $(CTDB_CLIENT_OBJ) ib/ibwrapper_test.o
+       @echo Linking $@
+       $(WRAPPER) $(CC) $(CFLAGS) -o $@ ib/ibwrapper_test.o $(CTDB_CLIENT_OBJ) $(LIB_FLAGS)
+
+manpages:
+       $(MAKE) -C doc
+
+clean:
+       rm -f *.o */*.o */*.a */*/*.o */*~
+       rm -f utils/smnotify/gen_xdr.c
+       rm -f $(BINS) $(SBINS) $(TEST_BINS)
+
+distclean: clean
+       rm -f *~ */*~
+       rm -rf bin
+       rm -f config.log config.status config.cache config.h
+       rm -f Makefile
+
+install: all manpages $(PMDA_INSTALL)
+       mkdir -p $(DESTDIR)$(libdir)/pkgconfig
+       mkdir -p $(DESTDIR)$(bindir)
+       mkdir -p $(DESTDIR)$(sbindir)
+       mkdir -p $(DESTDIR)$(includedir)
+       mkdir -p $(DESTDIR)$(etcdir)/ctdb
+       mkdir -p $(DESTDIR)$(etcdir)/ctdb/events.d
+       mkdir -p $(DESTDIR)$(etcdir)/ctdb/nfs-rpc-checks.d
+       mkdir -p $(DESTDIR)$(etcdir)/sudoers.d/
+       mkdir -p $(DESTDIR)$(etcdir)/ctdb/notify.d
+       mkdir -p $(DESTDIR)$(localstatedir)/lib/ctdb
+       mkdir -p $(DESTDIR)$(localstatedir)/run/ctdb
+       mkdir -p $(DESTDIR)$(logdir)
+       ${INSTALLCMD} -m 644 ctdb.pc $(DESTDIR)$(libdir)/pkgconfig
+       ${INSTALLCMD} -m 755 bin/ctdb $(DESTDIR)$(bindir)
+       ${INSTALLCMD} -m 755 bin/ctdbd $(DESTDIR)$(sbindir)
+       ${INSTALLCMD} -m 755 bin/smnotify $(DESTDIR)$(bindir)
+       $(INSTALLCMD) -m 755 bin/ping_pong $(DESTDIR)$(bindir)
+       $(INSTALLCMD) -m 755 bin/ltdbtool $(DESTDIR)$(bindir)
+       $(INSTALLCMD) -m 755 bin/ctdb_lock_helper $(DESTDIR)$(bindir)
+       ${INSTALLCMD} -m 644 include/ctdb.h $(DESTDIR)$(includedir)
+       ${INSTALLCMD} -m 644 include/ctdb_client.h $(DESTDIR)$(includedir)
+       ${INSTALLCMD} -m 644 include/ctdb_protocol.h $(DESTDIR)$(includedir)
+       ${INSTALLCMD} -m 644 include/ctdb_private.h $(DESTDIR)$(includedir) # for samba3
+       ${INSTALLCMD} -m 644 include/ctdb_typesafe_cb.h $(DESTDIR)$(includedir)
+       ${INSTALLCMD} -m 440 config/ctdb.sudoers $(DESTDIR)$(etcdir)/sudoers.d/ctdb
+       ${INSTALLCMD} -m 644 config/functions $(DESTDIR)$(etcdir)/ctdb
+       ${INSTALLCMD} -m 755 config/statd-callout $(DESTDIR)$(etcdir)/ctdb
+       ${INSTALLCMD} -m 755 config/ctdbd_wrapper $(DESTDIR)$(sbindir)
+       ${INSTALLCMD} -m 755 config/events.d/00.ctdb $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/01.reclock $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/10.interface $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/11.natgw $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/11.routing $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/13.per_ip_routing $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 644 config/events.d/20.multipathd $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 644 config/events.d/31.clamd $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/40.vsftpd $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 644 config/events.d/40.fs_use $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/41.httpd $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/49.winbind $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/50.samba $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/60.nfs $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/60.ganesha $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/62.cnfs $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/70.iscsi $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 755 config/events.d/91.lvs $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 644 config/events.d/99.timeout $(DESTDIR)$(etcdir)/ctdb/events.d
+       ${INSTALLCMD} -m 644 config/nfs-rpc-checks.d/10.statd.check $(DESTDIR)$(etcdir)/ctdb/nfs-rpc-checks.d/
+       ${INSTALLCMD} -m 644 config/nfs-rpc-checks.d/20.nfsd.check $(DESTDIR)$(etcdir)/ctdb/nfs-rpc-checks.d/
+       ${INSTALLCMD} -m 644 config/nfs-rpc-checks.d/30.lockd.check $(DESTDIR)$(etcdir)/ctdb/nfs-rpc-checks.d/
+       ${INSTALLCMD} -m 644 config/nfs-rpc-checks.d/40.mountd.check $(DESTDIR)$(etcdir)/ctdb/nfs-rpc-checks.d/
+       ${INSTALLCMD} -m 644 config/nfs-rpc-checks.d/50.rquotad.check $(DESTDIR)$(etcdir)/ctdb/nfs-rpc-checks.d/
+       ${INSTALLCMD} -m 755 tools/ctdb_diagnostics $(DESTDIR)$(bindir)
+       ${INSTALLCMD} -m 755 tools/onnode $(DESTDIR)$(bindir)
+       if [ -f doc/ctdb.1 ];then ${INSTALLCMD} -d $(DESTDIR)$(mandir)/man1; fi
+       if [ -f doc/ctdb.1 ];then ${INSTALLCMD} -m 644 doc/ctdb.1 $(DESTDIR)$(mandir)/man1; fi
+       if [ -f doc/ctdbd.1 ];then ${INSTALLCMD} -m 644 doc/ctdbd.1 $(DESTDIR)$(mandir)/man1; fi
+       if [ -f doc/onnode.1 ];then ${INSTALLCMD} -m 644 doc/onnode.1 $(DESTDIR)$(mandir)/man1; fi
+       if [ -f doc/ltdbtool.1 ]; then ${INSTALLCMD} -m 644 doc/ltdbtool.1 $(DESTDIR)$(mandir)/man1; fi
+       if [ -f doc/ping_pong.1 ];then ${INSTALLCMD} -m 644 doc/ping_pong.1 $(DESTDIR)$(mandir)/man1; fi
+       ${INSTALLCMD} -m 755 config/notify.sh $(DESTDIR)$(etcdir)/ctdb
+       ${INSTALLCMD} -m 755 config/debug-hung-script.sh $(DESTDIR)$(etcdir)/ctdb
+       ${INSTALLCMD} -m 755 config/ctdb-crash-cleanup.sh $(DESTDIR)$(etcdir)/ctdb
+       ${INSTALLCMD} -m 755 config/gcore_trace.sh $(DESTDIR)$(etcdir)/ctdb
+       ${INSTALLCMD} -m 755 config/debug_locks.sh $(DESTDIR)$(etcdir)/ctdb
+
+install_pmda:
+       $(INSTALLCMD) -m 755 -d $(DESTDIR)$(PMDA_DEST_DIR)
+       $(INSTALLCMD) -m 755 utils/pmda/Install utils/pmda/Remove $(DESTDIR)$(PMDA_DEST_DIR)
+       $(INSTALLCMD) -m 644 utils/pmda/pmns utils/pmda/domain.h utils/pmda/help utils/pmda/README $(DESTDIR)$(PMDA_DEST_DIR)
+       $(INSTALLCMD) -m 755 bin/pmdactdb $(DESTDIR)$(PMDA_DEST_DIR)
+
+# Should use $(datarootdir) but older autoconfs don't do this.  :-(
+install_tests: all
+       tests/INSTALL --destdir=$(DESTDIR) --datarootdir=$(prefix)/share --libdir=$(libdir) --bindir=$(bindir) --etcdir=$(etcdir)
+
+test: all
+       tests/run_tests.sh -V tests/var
+
+test_cluster: all
+       tests/run_cluster_tests.sh
+
+valgrindtest: all
+       VALGRIND="valgrind -q --trace-children=yes" tests/run_tests.sh
+
+ctags:
+       find . -name "*.[ch]" | xargs ctags
+
+etags:
+       find . -name "*.[ch]" | xargs etags
+
+realdistclean: distclean
+       rm -f configure config.h.in ctdb.pc
diff --git a/ctdb/NEWS b/ctdb/NEWS
new file mode 100644 (file)
index 0000000..ae4cff6
--- /dev/null
+++ b/ctdb/NEWS
@@ -0,0 +1,316 @@
+Changes in CTDB 2.5
+===================
+
+User-visible changes
+--------------------
+
+* The default location of the ctdbd socket is now:
+
+    /var/run/ctdb/ctdbd.socket
+
+  If you currently set CTDB_SOCKET in configuration then unsetting it
+  will probably do what you want.
+
+* The default location of CTDB TDB databases is now:
+
+    /var/lib/ctdb
+
+  If you only set CTDB_DBDIR (to the old default of /var/ctdb) then
+  you probably want to move your databases to /var/lib/ctdb, drop your
+  setting of CTDB_DBDIR and just use the default.
+
+  To maintain the database files in /var/ctdb you will need to set
+  CTDB_DBDIR, CTDB_DBDIR_PERSISTENT and CTDB_DBDIR_STATE, since all of
+  these have moved.
+
+* Use of CTDB_OPTIONS to set ctdbd command-line options is no longer
+  supported.  Please use individual configuration variables instead.
+
+* Obsolete tunables VacuumDefaultInterval, VacuumMinInterval and
+  VacuumMaxInterval have been removed.  Setting them had no effect but
+  if you now try to set them in a configuration files via CTDB_SET_X=Y
+  then CTDB will not start.
+
+* Much improved manual pages.  Added new manpages ctdb(7),
+  ctdbd.conf(5), ctdb-tunables(7).  Still some work to do.
+
+* Most CTDB-specific configuration can now be set in
+  /etc/ctdb/ctdbd.conf.
+
+  This avoids cluttering distribution-specific configuration files,
+  such as /etc/sysconfig/ctdb.  It also means that we can say: see
+  ctdbd.conf(5) for more details.  :-)
+
+* Configuration variable NFS_SERVER_MODE is deprecated and has been
+  replaced by CTDB_NFS_SERVER_MODE.  See ctdbd.conf(5) for more
+  details.
+
+* "ctdb reloadips" is much improved and should be used for reloading
+  the public IP configuration.
+
+  This commands attempts to yield much more predictable IP allocations
+  than using sequences of delip and addip commands.  See ctdb(1) for
+  details.
+
+* Ability to pass comma-separated string to ctdb(1) tool commands via
+  the -n option is now documented and works for most commands.  See
+  ctdb(1) for details.
+
+* "ctdb rebalancenode" is now a debugging command and should not be
+  used in normal operation.  See ctdb(1) for details.
+
+* "ctdb ban 0" is now invalid.
+
+  This was documented as causing a permanent ban.  However, this was
+  not implemented and caused an "unban" instead.  To avoid confusion,
+  0 is now an invalid ban duration.  To administratively "ban" a node
+  use "ctdb stop" instead.
+
+* The systemd configuration now puts the PID file in /run/ctdb (rather
+  than /run/ctdbd) for consistency with the initscript and other uses
+  of /var/run/ctdb.
+
+Important bug fixes
+-------------------
+
+* Traverse regression fixed.
+
+* The default recovery method for persistent databases has been
+  changed to use database sequence numbers instead of doing
+  record-by-record recovery (using record sequence numbers).  This
+  fixes issues including registry corruption.
+
+* Banned nodes are no longer told to run the "ipreallocated" event
+  during a takeover run, when in fallback mode with nodes that don't
+  support the IPREALLOCATED control.
+
+Important internal changes
+--------------------------
+
+* Persistent transactions are now compatible with Samba and work
+  reliably.
+
+* The recovery master role has been made more stable by resetting the
+  priority time each time a node becomes inactive.  This means that
+  nodes that are active for a long time are more likely to retain the
+  recovery master role.
+
+* The incomplete libctdb library has been removed.
+
+* Test suite now starts ctdbd with the --sloppy-start option to speed
+  up startup.  However, this should not be done in production.
+
+
+Changes in CTDB 2.4
+===================
+
+User-visible changes
+--------------------
+
+* A missing network interface now causes monitoring to fail and the
+  node to become unhealthy.
+
+* Changed ctdb command's default control timeout from 3s to 10s.
+
+* debug-hung-script.sh now includes the output of "ctdb scriptstatus"
+  to provide more information.
+
+Important bug fixes
+-------------------
+
+* Starting CTDB daemon by running ctdbd directly should not remove
+  existing unix socket unconditionally.
+
+* ctdbd once again successfully kills client processes on releasing
+  public IPs.  It was checking for them as tracked child processes
+  and not finding them, so wasn't killing them.
+
+* ctdbd_wrapper now exports CTDB_SOCKET so that child processes of
+  ctdbd (such as uses of ctdb in eventscripts) use the correct socket.
+
+* Always use Jenkins hash when creating volatile databases.  There
+  were a few places where TDBs would be attached with the wrong flags.
+
+* Vacuuming code fixes in CTDB 2.2 introduced bugs in the new code
+  which led to header corruption for empty records.  This resulted
+  in inconsistent headers on two nodes and a request for such a record
+  keeps bouncing between nodes indefinitely and logs "High hopcount"
+  messages in the log. This also caused performance degradation.
+
+* ctdbd was losing log messages at shutdown because they weren't being
+  given time to flush.  ctdbd now sleeps for a second during shutdown
+  to allow time to flush log messages.
+
+* Improved socket handling introduced in CTDB 2.2 caused ctdbd to
+  process a large number of packets available on single FD before
+  polling other FDs.  Use fixed size queue buffers to allow fair
+  scheduling across multiple FDs.
+
+Important internal changes
+--------------------------
+
+* A node that fails to take/release multiple IPs will only incur a
+  single banning credit.  This makes a brief failure less likely to
+  cause node to be banned.
+
+* ctdb killtcp has been changed to read connections from stdin and
+  10.interface now uses this feature to improve the time taken to kill
+  connections.
+
+* Improvements to hot records statistics in ctdb dbstatistics.
+
+* Recovery daemon now assembles up-to-date node flags information
+  from remote nodes before checking if any flags are inconsistent and
+  forcing a recovery.
+
+* ctdbd no longer creates multiple lock sub-processes for the same
+  key.  This reduces the number of lock sub-processes substantially.
+
+* Changed the nfsd RPC check failure policy to failover quickly
+  instead of trying to repair a node first by restarting NFS.  Such
+  restarts would often hang if the cause of the RPC check failure was
+  the cluster filesystem or storage.
+
+* Logging improvements relating to high hopcounts and sticky records.
+
+* Make sure lower level tdb messages are logged correctly.
+
+* CTDB commands disable/enable/stop/continue are now resilient to
+  individual control failures and retry in case of failures.
+
+
+Changes in CTDB 2.3
+===================
+
+User-visible changes
+--------------------
+
+* 2 new configuration variables for 60.nfs eventscript:
+
+  - CTDB_MONITOR_NFS_THREAD_COUNT
+  - CTDB_NFS_DUMP_STUCK_THREADS
+
+  See ctdb.sysconfig for details.
+
+* Removed DeadlockTimeout tunable.  To enable debug of locking issues set
+
+   CTDB_DEBUG_LOCKS=/etc/ctdb/debug_locks.sh
+
+* In overall statistics and database statistics, lock buckets have been
+  updated to use following timings:
+
+   < 1ms, < 10ms, < 100ms, < 1s, < 2s, < 4s, < 8s, < 16s, < 32s, < 64s, >= 64s
+
+* Initscript is now simplified with most CTDB-specific functionality
+  split out to ctdbd_wrapper, which is used to start and stop ctdbd.
+
+* Add systemd support.
+
+* CTDB subprocesses are now given informative names to allow them to
+  be easily distinguished when using programs like "top" or "perf".
+
+Important bug fixes
+-------------------
+
+* ctdb tool should not exit from a retry loop if a control times out
+  (e.g. under high load).  This simple fix will stop an exit from the
+  retry loop on any error.
+
+* When updating flags on all nodes, use the correct updated flags.  This
+  should avoid wrong flag change messages in the logs.
+
+* The recovery daemon will not ban other nodes if the current node
+  is banned.
+
+* ctdb dbstatistics command now correctly outputs database statistics.
+
+* Fixed a panic with overlapping shutdowns (regression in 2.2).
+
+* Fixed 60.ganesha "monitor" event (regression in 2.2).
+
+* Fixed a buffer overflow in the "reloadips" implementation.
+
+* Fixed segmentation faults in ping_pong (called with incorrect
+  argument) and test binaries (called when ctdbd not running).
+
+Important internal changes
+--------------------------
+
+* The recovery daemon on stopped or banned node will stop participating in any
+  cluster activity.
+
+* Improve cluster wide database traverse by sending the records directly from
+  traverse child process to requesting node.
+
+* TDB checking and dropping of all IPs moved from initscript to "init"
+  event in 00.ctdb.
+
+* To avoid "rogue IPs" the release IP callback now fails if the
+  released IP is still present on an interface.
+
+
+Changes in CTDB 2.2
+===================
+
+User-visible changes
+--------------------
+
+* The "stopped" event has been removed.
+
+  The "ipreallocated" event is now run when a node is stopped.  Use
+  this instead of "stopped".
+
+* New --pidfile option for ctdbd, used by initscript
+
+* The 60.nfs eventscript now uses configuration files in
+  /etc/ctdb/nfs-rpc-checks.d/ for timeouts and actions instead of
+  hardcoding them into the script.
+
+* Notification handler scripts can now be dropped into /etc/ctdb/notify.d/.
+
+* The NoIPTakeoverOnDisabled tunable has been renamed to
+  NoIPHostOnAllDisabled and now works properly when set on individual
+  nodes.
+
+* New ctdb subcommand "runstate" prints the current internal runstate.
+  Runstates are used for serialising startup.
+
+Important bug fixes
+-------------------
+
+* The Unix domain socket is now set to non-blocking after the
+  connection succeeds.  This avoids connections failing with EAGAIN
+  and not being retried.
+
+* Fetching from the log ringbuffer now succeeds if the buffer is full.
+
+* Fix a severe recovery bug that can lead to data corruption for SMB clients.
+
+* The statd-callout script now runs as root via sudo.
+
+* "ctdb delip" no longer fails if it is unable to move the IP.
+
+* A race in the ctdb tool's ipreallocate code was fixed.  This fixes
+  potential bugs in the "disable", "enable", "stop", "continue",
+  "ban", "unban", "ipreallocate" and "sync" commands.
+
+* The monitor cancellation code could sometimes hang indefinitely.
+  This could cause "ctdb stop" and "ctdb shutdown" to fail.
+
+Important internal changes
+--------------------------
+
+* The socket I/O handling has been optimised to improve performance.
+
+* IPs will not be assigned to nodes during CTDB initialisation.  They
+  will only be assigned to nodes that are in the "running" runstate.
+
+* Improved database locking code.  One improvement is to use a
+  standalone locking helper executable - the avoids creating many
+  forked copies of ctdbd and potentially running a node out of memory.
+
+* New control CTDB_CONTROL_IPREALLOCATED is now used to generate
+  "ipreallocated" events.
+
+* Message handlers are now indexed, providing a significant
+  performance improvement.
diff --git a/ctdb/README b/ctdb/README
new file mode 100644 (file)
index 0000000..3099a6d
--- /dev/null
@@ -0,0 +1,8 @@
+This is the release version of CTDB, a clustered implementation of TDB
+database used by Samba and other projects to store temporary data.
+
+This software is freely distributable under the GNU public license,
+a copy of which you should have received with this software (in a file
+called COPYING).
+
+For documentation on CTDB, please visit CTDB website http://ctdb.samba.org.
diff --git a/ctdb/README.Coding b/ctdb/README.Coding
new file mode 100644 (file)
index 0000000..fd52dbe
--- /dev/null
@@ -0,0 +1,236 @@
+##
+## Coding conventions in the Samba 3.0 tree
+##
+
+===========
+Quick Start
+===========
+
+Coding style guidelines are about reducing the number of unnecessary
+reformatting patches and making things easier developers to work together.
+You don't have to like them or even agree with them, but once put in place
+we all have to abide by them (or vote to change them).  However, coding
+style should never outweigh coding itself and so the the guidelines
+described here are hopefully easier enough to follow as they are very
+common and supported by tools and editors.
+
+The basic style, also mentioned in the SAMBA_4_0/prog_guide.txt is the
+Linux kernel coding style (See Documentation/CodingStyle in the kernel
+source tree).  The closely matches what most Samba developers use already
+anyways.
+
+But to save you the trouble of reading the Linux kernel style guide, here
+are the highlights.
+
+
+* Maximum Line Width is 80 Characters
+  The reason is not for people with low-res screens but rather sticking
+  to 80 columns prevents you from easily nesting more than one level of
+  if statements or other code blocks.  Use source/script/count_80_col.pl
+  to check your changes.
+
+* Use 8 Space Tabs to Indent
+  No whitespace filler.
+
+* No Trailing Whitespace
+  Use source/script/strip_trail_ws.pl to clean you files before committing.
+
+* Follow the K&R guidelines.  We won't go throw them all here.  You have
+  a copy of "The C Programming Language" anyways right?  You can also use
+  the format_indent.sh script found in source/script/ if all else fails.
+
+
+
+============
+Editor Hints
+============
+
+Emacs
+-----
+Add the follow to your $HOME/.emacs file:
+
+  (add-hook 'c-mode-hook
+       (lambda ()
+               (c-set-style "linux")
+               (c-toggle-auto-state)))
+
+
+Vi
+--
+(Thanks to SATOH Fumiyasu <fumiyas@osstech.jp> for these hints):
+
+For the basic vi editor including with all variants of *nix, add the 
+following to $HOME/.exrc:
+
+  set tabstop=8
+  set shiftwidth=8
+
+For Vim, the following settings in $HOME/.vimrc will also deal with 
+displaying trailing whitespace:
+
+  if has("syntax") && (&t_Co > 2 || has("gui_running"))
+       syntax on
+       function! ActivateInvisibleCharIndicator()
+               syntax match TrailingSpace "[ \t]\+$" display containedin=ALL
+               highlight TrailingSpace ctermbg=Red
+       endf
+       autocmd BufNewFile,BufRead * call ActivateInvisibleCharIndicator()
+  endif
+  " Show tabs, trailing whitespace, and continued lines visually
+  set list listchars=tab:»·,trail:·,extends:…
+
+  " highlight overly long lines same as TODOs.
+  set textwidth=80
+  autocmd BufNewFile,BufRead *.c,*.h exec 'match Todo /\%>' . &textwidth . 'v.\+/'
+
+
+=========================
+FAQ & Statement Reference
+=========================
+
+Comments
+--------
+
+Comments should always use the standard C syntax.  I.e. /* ... */.  C++ 
+style comments are not currently allowed.
+
+
+Indention & Whitespace & 80 columns
+-----------------------------------
+
+To avoid confusion, indentations are to be 8 character with tab (not 
+8 ' ' characters.  When wrapping parameters for function calls, 
+alignment parameter list with the first parameter on the previous line.
+Use tabs to get as close as possible and then fill in the final 7 
+characters or less with whitespace.  For example,
+
+       var1 = foo(arg1, arg2,
+                  arg3);
+
+The previous example is intended to illustrate alignment of function 
+parameters across lines and not as encourage for gratuitous line 
+splitting.  Never split a line before columns 70 - 79 unless you
+have a really good reason.  Be smart about formatting.
+
+
+If, switch, & Code blocks
+-------------------------
+
+Always follow an 'if' keyword with a space but don't include additional
+spaces following or preceding the parentheses in the conditional.
+This is good:
+
+       if (x == 1)
+
+This is bad:
+
+       if ( x == 1 )
+
+Yes we have a lot of code that uses the second form and we are trying 
+to clean it up without being overly intrusive.
+
+Note that this is a rule about parentheses following keywords and not
+functions.  Don't insert a space between the name and left parentheses when 
+invoking functions.
+
+Braces for code blocks used by for, if, switch, while, do..while, etc...
+should begin on the same line as the statement keyword and end on a line 
+of their own.  NOTE: Functions are different and the beginning left brace
+should begin on a line of its own.
+
+If the beginning statement has to be broken across lines due to length,
+the beginning brace should be on a line of its own.
+
+The exception to the ending rule is when the closing brace is followed by 
+another language keyword such as else or the closing while in a do..while 
+loop.
+
+Good examples:
+
+       if (x == 1) {
+               printf("good\n");
+       }
+
+       for (x=1;
+            x<10;
+            x++)
+       {
+               print("%d\n", x);
+       }
+
+       do {
+               printf("also good\n");
+       } while (1);
+
+Bad examples:
+
+       while (1)
+       {
+               print("I'm in a loop!\n"); }
+       
+
+Goto
+----
+
+While many people have been academically taught that goto's are fundamentally
+evil, then can greatly enhance readability and reduce memory leaks when used
+as the single exit point from a function.  But in no Samba world what so ever 
+is a goto outside of a function or block of code a good idea.
+
+Good Examples:
+
+int function foo(int y)
+{
+       int *z = NULL;
+       int ret = 0;
+
+       if ( y < 10 ) {
+               z = malloc(sizeof(int)*y);
+               if (!z) {
+                       ret = 1;
+                       goto done;
+               }
+       }
+
+       print("Allocated %d elements.\n", y);
+
+ done: 
+       if (z)
+               free(z);
+
+       return ret;
+}
+
+
+Checking Pointer Values
+-----------------------
+
+When invoking functions that return pointer values, either of the following 
+are acceptable.  Use you best judgement and choose the more readable option.
+Remember that many other people will review it.
+
+       if ((x = malloc(sizeof(short)*10)) == NULL ) {
+               fprintf(stderr, "Unable to alloc memory!\n");
+       }
+
+or
+
+       x = malloc(sizeof(short)*10);
+       if (!x) {
+               fprintf(stderr, "Unable to alloc memory!\n");
+       }
+
+
+Primitive Data Types
+--------------------
+
+Samba has large amounts of historical code which makes use of data types 
+commonly supported by the C99 standard. However, at the time such types 
+as boolean and exact width integers did not exist and Samba developers 
+were forced to provide their own.  Now that these types are guaranteed to 
+be available either as part of the compiler C99 support or from lib/replace/, 
+new code should adhere to the following conventions:
+
+  * Booleans are of type "bool" (not BOOL)
+  * Boolean values are "true" and "false" (not True or False)
+  * Exact width integers are of type [u]int[8|16|32|64]_t
diff --git a/ctdb/aclocal.m4 b/ctdb/aclocal.m4
new file mode 100644 (file)
index 0000000..5605e47
--- /dev/null
@@ -0,0 +1 @@
+m4_include(libreplace.m4)
diff --git a/ctdb/autogen.sh b/ctdb/autogen.sh
new file mode 100755 (executable)
index 0000000..12603d2
--- /dev/null
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+rm -rf autom4te.cache
+rm -f configure config.h.in ctdb.pc
+
+IPATHS="-I libreplace -I lib/replace -I ../libreplace -I ../replace"
+IPATHS="$IPATHS -I lib/talloc -I talloc -I ../talloc"
+IPATHS="$IPATHS -I lib/tdb -I tdb -I ../tdb"
+IPATHS="$IPATHS -I lib/popt -I popt -I ../popt"
+IPATHS="$IPATHS -I lib/tevent"
+
+autoheader $IPATHS || exit 1
+autoconf $IPATHS || exit 1
+
+rm -rf autom4te.cache
+
+echo "Now run ./configure and then make."
+exit 0
+
diff --git a/ctdb/client/ctdb_client.c b/ctdb/client/ctdb_client.c
new file mode 100644 (file)
index 0000000..fddbd02
--- /dev/null
@@ -0,0 +1,4877 @@
+/* 
+   ctdb daemon code
+
+   Copyright (C) Andrew Tridgell  2007
+   Copyright (C) Ronnie Sahlberg  2007
+
+   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
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+   
+   This program 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 General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "db_wrap.h"
+#include "tdb.h"
+#include "lib/util/dlinklist.h"
+#include "system/network.h"
+#include "system/filesys.h"
+#include "system/locale.h"
+#include <stdlib.h>
+#include "../include/ctdb_private.h"
+#include "lib/util/dlinklist.h"
+
+pid_t ctdbd_pid;
+
+/*
+  allocate a packet for use in client<->daemon communication
+ */
+struct ctdb_req_header *_ctdbd_allocate_pkt(struct ctdb_context *ctdb,
+                                           TALLOC_CTX *mem_ctx, 
+                                           enum ctdb_operation operation, 
+                                           size_t length, size_t slength,
+                                           const char *type)
+{
+       int size;
+       struct ctdb_req_header *hdr;
+
+       length = MAX(length, slength);
+       size = (length+(CTDB_DS_ALIGNMENT-1)) & ~(CTDB_DS_ALIGNMENT-1);
+
+       hdr = (struct ctdb_req_header *)talloc_zero_size(mem_ctx, size);
+       if (hdr == NULL) {
+               DEBUG(DEBUG_ERR,("Unable to allocate packet for operation %u of length %u\n",
+                        operation, (unsigned)length));
+               return NULL;
+       }
+       talloc_set_name_const(hdr, type);
+       hdr->length       = length;
+       hdr->operation    = operation;
+       hdr->ctdb_magic   = CTDB_MAGIC;
+       hdr->ctdb_version = CTDB_VERSION;
+       hdr->srcnode      = ctdb->pnn;
+       if (ctdb->vnn_map) {
+               hdr->generation = ctdb->vnn_map->generation;
+       }
+
+       return hdr;
+}
+
+/*
+  local version of ctdb_call
+*/
+int ctdb_call_local(struct ctdb_db_context *ctdb_db, struct ctdb_call *call,
+                   struct ctdb_ltdb_header *header, TALLOC_CTX *mem_ctx,
+                   TDB_DATA *data, bool updatetdb)
+{
+       struct ctdb_call_info *c;
+       struct ctdb_registered_call *fn;
+       struct ctdb_context *ctdb = ctdb_db->ctdb;
+       
+       c = talloc(ctdb, struct ctdb_call_info);
+       CTDB_NO_MEMORY(ctdb, c);
+
+       c->key = call->key;
+       c->call_data = &call->call_data;
+       c->record_data.dptr = talloc_memdup(c, data->dptr, data->dsize);
+       c->record_data.dsize = data->dsize;
+       CTDB_NO_MEMORY(ctdb, c->record_data.dptr);
+       c->new_data = NULL;
+       c->reply_data = NULL;
+       c->status = 0;
+       c->header = header;
+
+       for (fn=ctdb_db->calls;fn;fn=fn->next) {
+               if (fn->id == call->call_id) break;
+       }
+       if (fn == NULL) {
+               ctdb_set_error(ctdb, "Unknown call id %u\n", call->call_id);
+               talloc_free(c);
+               return -1;
+       }
+
+       if (fn->fn(c) != 0) {
+               ctdb_set_error(ctdb, "ctdb_call %u failed\n", call->call_id);
+               talloc_free(c);
+               return -1;
+       }
+
+       /* we need to force the record to be written out if this was a remote access */
+       if (c->new_data == NULL) {
+               c->new_data = &c->record_data;
+       }
+
+       if (c->new_data && updatetdb) {
+               /* XXX check that we always have the lock here? */
+               if (ctdb_ltdb_store(ctdb_db, call->key, header, *c->new_data) != 0) {
+                       ctdb_set_error(ctdb, "ctdb_call tdb_store failed\n");
+                       talloc_free(c);
+                       return -1;
+               }
+       }
+
+       if (c->reply_data) {
+               call->reply_data = *c->reply_data;
+
+               talloc_steal(call, call->reply_data.dptr);
+               talloc_set_name_const(call->reply_data.dptr, __location__);
+       } else {
+               call->reply_data.dptr = NULL;
+               call->reply_data.dsize = 0;
+       }
+       call->status = c->status;
+
+       talloc_free(c);
+
+       return 0;
+}
+
+
+/*
+  queue a packet for sending from client to daemon
+*/
+static int ctdb_client_queue_pkt(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
+{
+       return ctdb_queue_send(ctdb->daemon.queue, (uint8_t *)hdr, hdr->length);
+}
+
+
+/*
+  called when a CTDB_REPLY_CALL packet comes in in the client
+
+  This packet comes in response to a CTDB_REQ_CALL request packet. It
+  contains any reply data from the call
+*/
+static void ctdb_client_reply_call(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
+{
+       struct ctdb_reply_call *c = (struct ctdb_reply_call *)hdr;
+       struct ctdb_client_call_state *state;
+
+       state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_call_state);
+       if (state == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
+               return;
+       }
+
+       if (hdr->reqid != state->reqid) {
+               /* we found a record  but it was the wrong one */
+               DEBUG(DEBUG_ERR, ("Dropped client call reply with reqid:%u\n",hdr->reqid));
+               return;
+       }
+
+       state->call->reply_data.dptr = c->data;
+       state->call->reply_data.dsize = c->datalen;
+       state->call->status = c->status;
+
+       talloc_steal(state, c);
+
+       state->state = CTDB_CALL_DONE;
+
+       if (state->async.fn) {
+               state->async.fn(state);
+       }
+}
+
+static void ctdb_client_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr);
+
+/*
+  this is called in the client, when data comes in from the daemon
+ */
+void ctdb_client_read_cb(uint8_t *data, size_t cnt, void *args)
+{
+       struct ctdb_context *ctdb = talloc_get_type(args, struct ctdb_context);
+       struct ctdb_req_header *hdr = (struct ctdb_req_header *)data;
+       TALLOC_CTX *tmp_ctx;
+
+       /* place the packet as a child of a tmp_ctx. We then use
+          talloc_free() below to free it. If any of the calls want
+          to keep it, then they will steal it somewhere else, and the
+          talloc_free() will be a no-op */
+       tmp_ctx = talloc_new(ctdb);
+       talloc_steal(tmp_ctx, hdr);
+
+       if (cnt == 0) {
+               DEBUG(DEBUG_CRIT,("Daemon has exited - shutting down client\n"));
+               exit(1);
+       }
+
+       if (cnt < sizeof(*hdr)) {
+               DEBUG(DEBUG_CRIT,("Bad packet length %u in client\n", (unsigned)cnt));
+               goto done;
+       }
+       if (cnt != hdr->length) {
+               ctdb_set_error(ctdb, "Bad header length %u expected %u in client\n", 
+                              (unsigned)hdr->length, (unsigned)cnt);
+               goto done;
+       }
+
+       if (hdr->ctdb_magic != CTDB_MAGIC) {
+               ctdb_set_error(ctdb, "Non CTDB packet rejected in client\n");
+               goto done;
+       }
+
+       if (hdr->ctdb_version != CTDB_VERSION) {
+               ctdb_set_error(ctdb, "Bad CTDB version 0x%x rejected in client\n", hdr->ctdb_version);
+               goto done;
+       }
+
+       switch (hdr->operation) {
+       case CTDB_REPLY_CALL:
+               ctdb_client_reply_call(ctdb, hdr);
+               break;
+
+       case CTDB_REQ_MESSAGE:
+               ctdb_request_message(ctdb, hdr);
+               break;
+
+       case CTDB_REPLY_CONTROL:
+               ctdb_client_reply_control(ctdb, hdr);
+               break;
+
+       default:
+               DEBUG(DEBUG_CRIT,("bogus operation code:%u\n",hdr->operation));
+       }
+
+done:
+       talloc_free(tmp_ctx);
+}
+
+/*
+  connect to a unix domain socket
+*/
+int ctdb_socket_connect(struct ctdb_context *ctdb)
+{
+       struct sockaddr_un addr;
+
+       memset(&addr, 0, sizeof(addr));
+       addr.sun_family = AF_UNIX;
+       strncpy(addr.sun_path, ctdb->daemon.name, sizeof(addr.sun_path));
+
+       ctdb->daemon.sd = socket(AF_UNIX, SOCK_STREAM, 0);
+       if (ctdb->daemon.sd == -1) {
+               DEBUG(DEBUG_ERR,(__location__ " Failed to open client socket. Errno:%s(%d)\n", strerror(errno), errno));
+               return -1;
+       }
+
+       if (connect(ctdb->daemon.sd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+               close(ctdb->daemon.sd);
+               ctdb->daemon.sd = -1;
+               DEBUG(DEBUG_ERR,(__location__ " Failed to connect client socket to daemon. Errno:%s(%d)\n", strerror(errno), errno));
+               return -1;
+       }
+
+       set_nonblocking(ctdb->daemon.sd);
+       set_close_on_exec(ctdb->daemon.sd);
+       
+       ctdb->daemon.queue = ctdb_queue_setup(ctdb, ctdb, ctdb->daemon.sd, 
+                                             CTDB_DS_ALIGNMENT, 
+                                             ctdb_client_read_cb, ctdb, "to-ctdbd");
+       return 0;
+}
+
+
+struct ctdb_record_handle {
+       struct ctdb_db_context *ctdb_db;
+       TDB_DATA key;
+       TDB_DATA *data;
+       struct ctdb_ltdb_header header;
+};
+
+
+/*
+  make a recv call to the local ctdb daemon - called from client context
+
+  This is called when the program wants to wait for a ctdb_call to complete and get the 
+  results. This call will block unless the call has already completed.
+*/
+int ctdb_call_recv(struct ctdb_client_call_state *state, struct ctdb_call *call)
+{
+       if (state == NULL) {
+               return -1;
+       }
+
+       while (state->state < CTDB_CALL_DONE) {
+               event_loop_once(state->ctdb_db->ctdb->ev);
+       }
+       if (state->state != CTDB_CALL_DONE) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_call_recv failed\n"));
+               talloc_free(state);
+               return -1;
+       }
+
+       if (state->call->reply_data.dsize) {
+               call->reply_data.dptr = talloc_memdup(state->ctdb_db,
+                                                     state->call->reply_data.dptr,
+                                                     state->call->reply_data.dsize);
+               call->reply_data.dsize = state->call->reply_data.dsize;
+       } else {
+               call->reply_data.dptr = NULL;
+               call->reply_data.dsize = 0;
+       }
+       call->status = state->call->status;
+       talloc_free(state);
+
+       return call->status;
+}
+
+
+
+
+/*
+  destroy a ctdb_call in client
+*/
+static int ctdb_client_call_destructor(struct ctdb_client_call_state *state)   
+{
+       ctdb_reqid_remove(state->ctdb_db->ctdb, state->reqid);
+       return 0;
+}
+
+/*
+  construct an event driven local ctdb_call
+
+  this is used so that locally processed ctdb_call requests are processed
+  in an event driven manner
+*/
+static struct ctdb_client_call_state *ctdb_client_call_local_send(struct ctdb_db_context *ctdb_db, 
+                                                                 struct ctdb_call *call,
+                                                                 struct ctdb_ltdb_header *header,
+                                                                 TDB_DATA *data)
+{
+       struct ctdb_client_call_state *state;
+       struct ctdb_context *ctdb = ctdb_db->ctdb;
+       int ret;
+
+       state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
+       CTDB_NO_MEMORY_NULL(ctdb, state);
+       state->call = talloc_zero(state, struct ctdb_call);
+       CTDB_NO_MEMORY_NULL(ctdb, state->call);
+
+       talloc_steal(state, data->dptr);
+
+       state->state   = CTDB_CALL_DONE;
+       *(state->call) = *call;
+       state->ctdb_db = ctdb_db;
+
+       ret = ctdb_call_local(ctdb_db, state->call, header, state, data, true);
+       if (ret != 0) {
+               DEBUG(DEBUG_DEBUG,("ctdb_call_local() failed, ignoring return code %d\n", ret));
+       }
+
+       return state;
+}
+
+/*
+  make a ctdb call to the local daemon - async send. Called from client context.
+
+  This constructs a ctdb_call request and queues it for processing. 
+  This call never blocks.
+*/
+struct ctdb_client_call_state *ctdb_call_send(struct ctdb_db_context *ctdb_db, 
+                                             struct ctdb_call *call)
+{
+       struct ctdb_client_call_state *state;
+       struct ctdb_context *ctdb = ctdb_db->ctdb;
+       struct ctdb_ltdb_header header;
+       TDB_DATA data;
+       int ret;
+       size_t len;
+       struct ctdb_req_call *c;
+
+       /* if the domain socket is not yet open, open it */
+       if (ctdb->daemon.sd==-1) {
+               ctdb_socket_connect(ctdb);
+       }
+
+       ret = ctdb_ltdb_lock(ctdb_db, call->key);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " Failed to get chainlock\n"));
+               return NULL;
+       }
+
+       ret = ctdb_ltdb_fetch(ctdb_db, call->key, &header, ctdb_db, &data);
+
+       if ((call->flags & CTDB_IMMEDIATE_MIGRATION) && (header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
+               ret = -1;
+       }
+
+       if (ret == 0 && header.dmaster == ctdb->pnn) {
+               state = ctdb_client_call_local_send(ctdb_db, call, &header, &data);
+               talloc_free(data.dptr);
+               ctdb_ltdb_unlock(ctdb_db, call->key);
+               return state;
+       }
+
+       ctdb_ltdb_unlock(ctdb_db, call->key);
+       talloc_free(data.dptr);
+
+       state = talloc_zero(ctdb_db, struct ctdb_client_call_state);
+       if (state == NULL) {
+               DEBUG(DEBUG_ERR, (__location__ " failed to allocate state\n"));
+               return NULL;
+       }
+       state->call = talloc_zero(state, struct ctdb_call);
+       if (state->call == NULL) {
+               DEBUG(DEBUG_ERR, (__location__ " failed to allocate state->call\n"));
+               return NULL;
+       }
+
+       len = offsetof(struct ctdb_req_call, data) + call->key.dsize + call->call_data.dsize;
+       c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CALL, len, struct ctdb_req_call);
+       if (c == NULL) {
+               DEBUG(DEBUG_ERR, (__location__ " failed to allocate packet\n"));
+               return NULL;
+       }
+
+       state->reqid     = ctdb_reqid_new(ctdb, state);
+       state->ctdb_db = ctdb_db;
+       talloc_set_destructor(state, ctdb_client_call_destructor);
+
+       c->hdr.reqid     = state->reqid;
+       c->flags         = call->flags;
+       c->db_id         = ctdb_db->db_id;
+       c->callid        = call->call_id;
+       c->hopcount      = 0;
+       c->keylen        = call->key.dsize;
+       c->calldatalen   = call->call_data.dsize;
+       memcpy(&c->data[0], call->key.dptr, call->key.dsize);
+       memcpy(&c->data[call->key.dsize], 
+              call->call_data.dptr, call->call_data.dsize);
+       *(state->call)              = *call;
+       state->call->call_data.dptr = &c->data[call->key.dsize];
+       state->call->key.dptr       = &c->data[0];
+
+       state->state  = CTDB_CALL_WAIT;
+
+
+       ctdb_client_queue_pkt(ctdb, &c->hdr);
+
+       return state;
+}
+
+
+/*
+  full ctdb_call. Equivalent to a ctdb_call_send() followed by a ctdb_call_recv()
+*/
+int ctdb_call(struct ctdb_db_context *ctdb_db, struct ctdb_call *call)
+{
+       struct ctdb_client_call_state *state;
+
+       state = ctdb_call_send(ctdb_db, call);
+       return ctdb_call_recv(state, call);
+}
+
+
+/*
+  tell the daemon what messaging srvid we will use, and register the message
+  handler function in the client
+*/
+int ctdb_client_set_message_handler(struct ctdb_context *ctdb, uint64_t srvid, 
+                            ctdb_msg_fn_t handler,
+                            void *private_data)
+{
+       int res;
+       int32_t status;
+
+       res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_REGISTER_SRVID, 0, 
+                          tdb_null, NULL, NULL, &status, NULL, NULL);
+       if (res != 0 || status != 0) {
+               DEBUG(DEBUG_ERR,("Failed to register srvid %llu\n", (unsigned long long)srvid));
+               return -1;
+       }
+
+       /* also need to register the handler with our own ctdb structure */
+       return ctdb_register_message_handler(ctdb, ctdb, srvid, handler, private_data);
+}
+
+/*
+  tell the daemon we no longer want a srvid
+*/
+int ctdb_client_remove_message_handler(struct ctdb_context *ctdb, uint64_t srvid, void *private_data)
+{
+       int res;
+       int32_t status;
+
+       res = ctdb_control(ctdb, CTDB_CURRENT_NODE, srvid, CTDB_CONTROL_DEREGISTER_SRVID, 0, 
+                          tdb_null, NULL, NULL, &status, NULL, NULL);
+       if (res != 0 || status != 0) {
+               DEBUG(DEBUG_ERR,("Failed to deregister srvid %llu\n", (unsigned long long)srvid));
+               return -1;
+       }
+
+       /* also need to register the handler with our own ctdb structure */
+       ctdb_deregister_message_handler(ctdb, srvid, private_data);
+       return 0;
+}
+
+/*
+ * check server ids
+ */
+int ctdb_client_check_message_handlers(struct ctdb_context *ctdb, uint64_t *ids, uint32_t num,
+                                      uint8_t *result)
+{
+       TDB_DATA indata, outdata;
+       int res;
+       int32_t status;
+       int i;
+
+       indata.dptr = (uint8_t *)ids;
+       indata.dsize = num * sizeof(*ids);
+
+       res = ctdb_control(ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_CHECK_SRVIDS, 0,
+                          indata, ctdb, &outdata, &status, NULL, NULL);
+       if (res != 0 || status != 0) {
+               DEBUG(DEBUG_ERR, (__location__ " failed to check srvids\n"));
+               return -1;
+       }
+
+       if (outdata.dsize != num*sizeof(uint8_t)) {
+               DEBUG(DEBUG_ERR, (__location__ " expected %lu bytes, received %zi bytes\n",
+                                 (long unsigned int)num*sizeof(uint8_t),
+                                 outdata.dsize));
+               talloc_free(outdata.dptr);
+               return -1;
+       }
+
+       for (i=0; i<num; i++) {
+               result[i] = outdata.dptr[i];
+       }
+
+       talloc_free(outdata.dptr);
+       return 0;
+}
+
+/*
+  send a message - from client context
+ */
+int ctdb_client_send_message(struct ctdb_context *ctdb, uint32_t pnn,
+                     uint64_t srvid, TDB_DATA data)
+{
+       struct ctdb_req_message *r;
+       int len, res;
+
+       len = offsetof(struct ctdb_req_message, data) + data.dsize;
+       r = ctdbd_allocate_pkt(ctdb, ctdb, CTDB_REQ_MESSAGE, 
+                              len, struct ctdb_req_message);
+       CTDB_NO_MEMORY(ctdb, r);
+
+       r->hdr.destnode  = pnn;
+       r->srvid         = srvid;
+       r->datalen       = data.dsize;
+       memcpy(&r->data[0], data.dptr, data.dsize);
+       
+       res = ctdb_client_queue_pkt(ctdb, &r->hdr);
+       talloc_free(r);
+       return res;
+}
+
+
+/*
+  cancel a ctdb_fetch_lock operation, releasing the lock
+ */
+static int fetch_lock_destructor(struct ctdb_record_handle *h)
+{
+       ctdb_ltdb_unlock(h->ctdb_db, h->key);
+       return 0;
+}
+
+/*
+  force the migration of a record to this node
+ */
+static int ctdb_client_force_migration(struct ctdb_db_context *ctdb_db, TDB_DATA key)
+{
+       struct ctdb_call call;
+       ZERO_STRUCT(call);
+       call.call_id = CTDB_NULL_FUNC;
+       call.key = key;
+       call.flags = CTDB_IMMEDIATE_MIGRATION;
+       return ctdb_call(ctdb_db, &call);
+}
+
+/*
+  try to fetch a readonly copy of a record
+ */
+static int
+ctdb_client_fetch_readonly(struct ctdb_db_context *ctdb_db, TDB_DATA key, TALLOC_CTX *mem_ctx, struct ctdb_ltdb_header **hdr, TDB_DATA *data)
+{
+       int ret;
+
+       struct ctdb_call call;
+       ZERO_STRUCT(call);
+
+       call.call_id = CTDB_FETCH_WITH_HEADER_FUNC;
+       call.call_data.dptr = NULL;
+       call.call_data.dsize = 0;
+       call.key = key;
+       call.flags = CTDB_WANT_READONLY;
+       ret = ctdb_call(ctdb_db, &call);
+
+       if (ret != 0) {
+               return -1;
+       }
+       if (call.reply_data.dsize < sizeof(struct ctdb_ltdb_header)) {
+               return -1;
+       }
+
+       *hdr = talloc_memdup(mem_ctx, &call.reply_data.dptr[0], sizeof(struct ctdb_ltdb_header));
+       if (*hdr == NULL) {
+               talloc_free(call.reply_data.dptr);
+               return -1;
+       }
+
+       data->dsize = call.reply_data.dsize - sizeof(struct ctdb_ltdb_header);
+       data->dptr  = talloc_memdup(mem_ctx, &call.reply_data.dptr[sizeof(struct ctdb_ltdb_header)], data->dsize);
+       if (data->dptr == NULL) {
+               talloc_free(call.reply_data.dptr);
+               talloc_free(hdr);
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  get a lock on a record, and return the records data. Blocks until it gets the lock
+ */
+struct ctdb_record_handle *ctdb_fetch_lock(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx, 
+                                          TDB_DATA key, TDB_DATA *data)
+{
+       int ret;
+       struct ctdb_record_handle *h;
+
+       /*
+         procedure is as follows:
+
+         1) get the chain lock. 
+         2) check if we are dmaster
+         3) if we are the dmaster then return handle 
+         4) if not dmaster then ask ctdb daemon to make us dmaster, and wait for
+            reply from ctdbd
+         5) when we get the reply, goto (1)
+        */
+
+       h = talloc_zero(mem_ctx, struct ctdb_record_handle);
+       if (h == NULL) {
+               return NULL;
+       }
+
+       h->ctdb_db = ctdb_db;
+       h->key     = key;
+       h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
+       if (h->key.dptr == NULL) {
+               talloc_free(h);
+               return NULL;
+       }
+       h->data    = data;
+
+       DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: key=%*.*s\n", (int)key.dsize, (int)key.dsize, 
+                (const char *)key.dptr));
+
+again:
+       /* step 1 - get the chain lock */
+       ret = ctdb_ltdb_lock(ctdb_db, key);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
+               talloc_free(h);
+               return NULL;
+       }
+
+       DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: got chain lock\n"));
+
+       talloc_set_destructor(h, fetch_lock_destructor);
+
+       ret = ctdb_ltdb_fetch(ctdb_db, key, &h->header, h, data);
+
+       /* when torturing, ensure we test the remote path */
+       if ((ctdb_db->ctdb->flags & CTDB_FLAG_TORTURE) &&
+           random() % 5 == 0) {
+               h->header.dmaster = (uint32_t)-1;
+       }
+
+
+       DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: done local fetch\n"));
+
+       if (ret != 0 || h->header.dmaster != ctdb_db->ctdb->pnn) {
+               ctdb_ltdb_unlock(ctdb_db, key);
+               ret = ctdb_client_force_migration(ctdb_db, key);
+               if (ret != 0) {
+                       DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
+                       talloc_free(h);
+                       return NULL;
+               }
+               goto again;
+       }
+
+       DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: we are dmaster - done\n"));
+       return h;
+}
+
+/*
+  get a readonly lock on a record, and return the records data. Blocks until it gets the lock
+ */
+struct ctdb_record_handle *
+ctdb_fetch_readonly_lock(
+       struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx, 
+       TDB_DATA key, TDB_DATA *data,
+       int read_only)
+{
+       int ret;
+       struct ctdb_record_handle *h;
+       struct ctdb_ltdb_header *roheader = NULL;
+
+       h = talloc_zero(mem_ctx, struct ctdb_record_handle);
+       if (h == NULL) {
+               return NULL;
+       }
+
+       h->ctdb_db = ctdb_db;
+       h->key     = key;
+       h->key.dptr = talloc_memdup(h, key.dptr, key.dsize);
+       if (h->key.dptr == NULL) {
+               talloc_free(h);
+               return NULL;
+       }
+       h->data    = data;
+
+       data->dptr = NULL;
+       data->dsize = 0;
+
+
+again:
+       talloc_free(roheader);
+       roheader = NULL;
+
+       talloc_free(data->dptr);
+       data->dptr = NULL;
+       data->dsize = 0;
+
+       /* Lock the record/chain */
+       ret = ctdb_ltdb_lock(ctdb_db, key);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
+               talloc_free(h);
+               return NULL;
+       }
+
+       talloc_set_destructor(h, fetch_lock_destructor);
+
+       /* Check if record exists yet in the TDB */
+       ret = ctdb_ltdb_fetch_with_header(ctdb_db, key, &h->header, h, data);
+       if (ret != 0) {
+               ctdb_ltdb_unlock(ctdb_db, key);
+               ret = ctdb_client_force_migration(ctdb_db, key);
+               if (ret != 0) {
+                       DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
+                       talloc_free(h);
+                       return NULL;
+               }
+               goto again;
+       }
+
+       /* if this is a request for read/write and we have delegations
+          we have to revoke all delegations first
+       */
+       if ((read_only == 0) 
+       &&  (h->header.dmaster == ctdb_db->ctdb->pnn)
+       &&  (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
+               ctdb_ltdb_unlock(ctdb_db, key);
+               ret = ctdb_client_force_migration(ctdb_db, key);
+               if (ret != 0) {
+                       DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
+                       talloc_free(h);
+                       return NULL;
+               }
+               goto again;
+       }
+
+       /* if we are dmaster, just return the handle */
+       if (h->header.dmaster == ctdb_db->ctdb->pnn) {
+               return h;
+       }
+
+       if (read_only != 0) {
+               TDB_DATA rodata = {NULL, 0};
+
+               if ((h->header.flags & CTDB_REC_RO_HAVE_READONLY)
+               ||  (h->header.flags & CTDB_REC_RO_HAVE_DELEGATIONS)) {
+                       return h;
+               }
+
+               ctdb_ltdb_unlock(ctdb_db, key);
+               ret = ctdb_client_fetch_readonly(ctdb_db, key, h, &roheader, &rodata);
+               if (ret != 0) {
+                       DEBUG(DEBUG_ERR,("ctdb_fetch_readonly_lock:  failed. force migration and try again\n"));
+                       ret = ctdb_client_force_migration(ctdb_db, key);
+                       if (ret != 0) {
+                               DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
+                               talloc_free(h);
+                               return NULL;
+                       }
+
+                       goto again;
+               }
+
+               if (!(roheader->flags&CTDB_REC_RO_HAVE_READONLY)) {
+                       ret = ctdb_client_force_migration(ctdb_db, key);
+                       if (ret != 0) {
+                               DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
+                               talloc_free(h);
+                               return NULL;
+                       }
+
+                       goto again;
+               }
+
+               ret = ctdb_ltdb_lock(ctdb_db, key);
+               if (ret != 0) {
+                       DEBUG(DEBUG_ERR, (__location__ " failed to lock ltdb record\n"));
+                       talloc_free(h);
+                       return NULL;
+               }
+
+               ret = ctdb_ltdb_fetch_with_header(ctdb_db, key, &h->header, h, data);
+               if (ret != 0) {
+                       ctdb_ltdb_unlock(ctdb_db, key);
+
+                       ret = ctdb_client_force_migration(ctdb_db, key);
+                       if (ret != 0) {
+                               DEBUG(DEBUG_DEBUG,("ctdb_fetch_readonly_lock: force_migration failed\n"));
+                               talloc_free(h);
+                               return NULL;
+                       }
+
+                       goto again;
+               }
+
+               return h;
+       }
+
+       /* we are not dmaster and this was not a request for a readonly lock
+        * so unlock the record, migrate it and try again
+        */
+       ctdb_ltdb_unlock(ctdb_db, key);
+       ret = ctdb_client_force_migration(ctdb_db, key);
+       if (ret != 0) {
+               DEBUG(DEBUG_DEBUG,("ctdb_fetch_lock: force_migration failed\n"));
+               talloc_free(h);
+               return NULL;
+       }
+       goto again;
+}
+
+/*
+  store some data to the record that was locked with ctdb_fetch_lock()
+*/
+int ctdb_record_store(struct ctdb_record_handle *h, TDB_DATA data)
+{
+       if (h->ctdb_db->persistent) {
+               DEBUG(DEBUG_ERR, (__location__ " ctdb_record_store prohibited for persistent dbs\n"));
+               return -1;
+       }
+
+       return ctdb_ltdb_store(h->ctdb_db, h->key, &h->header, data);
+}
+
+/*
+  non-locking fetch of a record
+ */
+int ctdb_fetch(struct ctdb_db_context *ctdb_db, TALLOC_CTX *mem_ctx, 
+              TDB_DATA key, TDB_DATA *data)
+{
+       struct ctdb_call call;
+       int ret;
+
+       call.call_id = CTDB_FETCH_FUNC;
+       call.call_data.dptr = NULL;
+       call.call_data.dsize = 0;
+       call.key = key;
+
+       ret = ctdb_call(ctdb_db, &call);
+
+       if (ret == 0) {
+               *data = call.reply_data;
+               talloc_steal(mem_ctx, data->dptr);
+       }
+
+       return ret;
+}
+
+
+
+/*
+   called when a control completes or timesout to invoke the callback
+   function the user provided
+*/
+static void invoke_control_callback(struct event_context *ev, struct timed_event *te, 
+       struct timeval t, void *private_data)
+{
+       struct ctdb_client_control_state *state;
+       TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+       int ret;
+
+       state = talloc_get_type(private_data, struct ctdb_client_control_state);
+       talloc_steal(tmp_ctx, state);
+
+       ret = ctdb_control_recv(state->ctdb, state, state,
+                       NULL, 
+                       NULL, 
+                       NULL);
+       if (ret != 0) {
+               DEBUG(DEBUG_DEBUG,("ctdb_control_recv() failed, ignoring return code %d\n", ret));
+       }
+
+       talloc_free(tmp_ctx);
+}
+
+/*
+  called when a CTDB_REPLY_CONTROL packet comes in in the client
+
+  This packet comes in response to a CTDB_REQ_CONTROL request packet. It
+  contains any reply data from the control
+*/
+static void ctdb_client_reply_control(struct ctdb_context *ctdb, 
+                                     struct ctdb_req_header *hdr)
+{
+       struct ctdb_reply_control *c = (struct ctdb_reply_control *)hdr;
+       struct ctdb_client_control_state *state;
+
+       state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_client_control_state);
+       if (state == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " reqid %u not found\n", hdr->reqid));
+               return;
+       }
+
+       if (hdr->reqid != state->reqid) {
+               /* we found a record  but it was the wrong one */
+               DEBUG(DEBUG_ERR, ("Dropped orphaned reply control with reqid:%u\n",hdr->reqid));
+               return;
+       }
+
+       state->outdata.dptr = c->data;
+       state->outdata.dsize = c->datalen;
+       state->status = c->status;
+       if (c->errorlen) {
+               state->errormsg = talloc_strndup(state, 
+                                                (char *)&c->data[c->datalen], 
+                                                c->errorlen);
+       }
+
+       /* state->outdata now uses resources from c so we dont want c
+          to just dissappear from under us while state is still alive
+       */
+       talloc_steal(state, c);
+
+       state->state = CTDB_CONTROL_DONE;
+
+       /* if we had a callback registered for this control, pull the response
+          and call the callback.
+       */
+       if (state->async.fn) {
+               event_add_timed(ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
+       }
+}
+
+
+/*
+  destroy a ctdb_control in client
+*/
+static int ctdb_client_control_destructor(struct ctdb_client_control_state *state)
+{
+       ctdb_reqid_remove(state->ctdb, state->reqid);
+       return 0;
+}
+
+
+/* time out handler for ctdb_control */
+static void control_timeout_func(struct event_context *ev, struct timed_event *te, 
+       struct timeval t, void *private_data)
+{
+       struct ctdb_client_control_state *state = talloc_get_type(private_data, struct ctdb_client_control_state);
+
+       DEBUG(DEBUG_ERR,(__location__ " control timed out. reqid:%u opcode:%u "
+                        "dstnode:%u\n", state->reqid, state->c->opcode,
+                        state->c->hdr.destnode));
+
+       state->state = CTDB_CONTROL_TIMEOUT;
+
+       /* if we had a callback registered for this control, pull the response
+          and call the callback.
+       */
+       if (state->async.fn) {
+               event_add_timed(state->ctdb->ev, state, timeval_zero(), invoke_control_callback, state);
+       }
+}
+
+/* async version of send control request */
+struct ctdb_client_control_state *ctdb_control_send(struct ctdb_context *ctdb, 
+               uint32_t destnode, uint64_t srvid, 
+               uint32_t opcode, uint32_t flags, TDB_DATA data, 
+               TALLOC_CTX *mem_ctx,
+               struct timeval *timeout,
+               char **errormsg)
+{
+       struct ctdb_client_control_state *state;
+       size_t len;
+       struct ctdb_req_control *c;
+       int ret;
+
+       if (errormsg) {
+               *errormsg = NULL;
+       }
+
+       /* if the domain socket is not yet open, open it */
+       if (ctdb->daemon.sd==-1) {
+               ctdb_socket_connect(ctdb);
+       }
+
+       state = talloc_zero(mem_ctx, struct ctdb_client_control_state);
+       CTDB_NO_MEMORY_NULL(ctdb, state);
+
+       state->ctdb       = ctdb;
+       state->reqid      = ctdb_reqid_new(ctdb, state);
+       state->state      = CTDB_CONTROL_WAIT;
+       state->errormsg   = NULL;
+
+       talloc_set_destructor(state, ctdb_client_control_destructor);
+
+       len = offsetof(struct ctdb_req_control, data) + data.dsize;
+       c = ctdbd_allocate_pkt(ctdb, state, CTDB_REQ_CONTROL, 
+                              len, struct ctdb_req_control);
+       state->c            = c;        
+       CTDB_NO_MEMORY_NULL(ctdb, c);
+       c->hdr.reqid        = state->reqid;
+       c->hdr.destnode     = destnode;
+       c->opcode           = opcode;
+       c->client_id        = 0;
+       c->flags            = flags;
+       c->srvid            = srvid;
+       c->datalen          = data.dsize;
+       if (data.dsize) {
+               memcpy(&c->data[0], data.dptr, data.dsize);
+       }
+
+       /* timeout */
+       if (timeout && !timeval_is_zero(timeout)) {
+               event_add_timed(ctdb->ev, state, *timeout, control_timeout_func, state);
+       }
+
+       ret = ctdb_client_queue_pkt(ctdb, &(c->hdr));
+       if (ret != 0) {
+               talloc_free(state);
+               return NULL;
+       }
+
+       if (flags & CTDB_CTRL_FLAG_NOREPLY) {
+               talloc_free(state);
+               return NULL;
+       }
+
+       return state;
+}
+
+
+/* async version of receive control reply */
+int ctdb_control_recv(struct ctdb_context *ctdb, 
+               struct ctdb_client_control_state *state, 
+               TALLOC_CTX *mem_ctx,
+               TDB_DATA *outdata, int32_t *status, char **errormsg)
+{
+       TALLOC_CTX *tmp_ctx;
+
+       if (status != NULL) {
+               *status = -1;
+       }
+       if (errormsg != NULL) {
+               *errormsg = NULL;
+       }
+
+       if (state == NULL) {
+               return -1;
+       }
+
+       /* prevent double free of state */
+       tmp_ctx = talloc_new(ctdb);
+       talloc_steal(tmp_ctx, state);
+
+       /* loop one event at a time until we either timeout or the control
+          completes.
+       */
+       while (state->state == CTDB_CONTROL_WAIT) {
+               event_loop_once(ctdb->ev);
+       }
+
+       if (state->state != CTDB_CONTROL_DONE) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control_recv failed\n"));
+               if (state->async.fn) {
+                       state->async.fn(state);
+               }
+               talloc_free(tmp_ctx);
+               return -1;
+       }
+
+       if (state->errormsg) {
+               DEBUG(DEBUG_ERR,("ctdb_control error: '%s'\n", state->errormsg));
+               if (errormsg) {
+                       (*errormsg) = talloc_move(mem_ctx, &state->errormsg);
+               }
+               if (state->async.fn) {
+                       state->async.fn(state);
+               }
+               talloc_free(tmp_ctx);
+               return -1;
+       }
+
+       if (outdata) {
+               *outdata = state->outdata;
+               outdata->dptr = talloc_memdup(mem_ctx, outdata->dptr, outdata->dsize);
+       }
+
+       if (status) {
+               *status = state->status;
+       }
+
+       if (state->async.fn) {
+               state->async.fn(state);
+       }
+
+       talloc_free(tmp_ctx);
+       return 0;
+}
+
+
+
+/*
+  send a ctdb control message
+  timeout specifies how long we should wait for a reply.
+  if timeout is NULL we wait indefinitely
+ */
+int ctdb_control(struct ctdb_context *ctdb, uint32_t destnode, uint64_t srvid, 
+                uint32_t opcode, uint32_t flags, TDB_DATA data, 
+                TALLOC_CTX *mem_ctx, TDB_DATA *outdata, int32_t *status,
+                struct timeval *timeout,
+                char **errormsg)
+{
+       struct ctdb_client_control_state *state;
+
+       state = ctdb_control_send(ctdb, destnode, srvid, opcode, 
+                       flags, data, mem_ctx,
+                       timeout, errormsg);
+
+       /* FIXME: Error conditions in ctdb_control_send return NULL without
+        * setting errormsg.  So, there is no way to distinguish between sucess
+        * and failure when CTDB_CTRL_FLAG_NOREPLY is set */
+       if (flags & CTDB_CTRL_FLAG_NOREPLY) {
+               if (status != NULL) {
+                       *status = 0;
+               }
+               return 0;
+       }
+
+       return ctdb_control_recv(ctdb, state, mem_ctx, outdata, status, 
+                       errormsg);
+}
+
+
+
+
+/*
+  a process exists call. Returns 0 if process exists, -1 otherwise
+ */
+int ctdb_ctrl_process_exists(struct ctdb_context *ctdb, uint32_t destnode, pid_t pid)
+{
+       int ret;
+       TDB_DATA data;
+       int32_t status;
+
+       data.dptr = (uint8_t*)&pid;
+       data.dsize = sizeof(pid);
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_PROCESS_EXISTS, 0, data, 
+                          NULL, NULL, &status, NULL, NULL);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for process_exists failed\n"));
+               return -1;
+       }
+
+       return status;
+}
+
+/*
+  get remote statistics
+ */
+int ctdb_ctrl_statistics(struct ctdb_context *ctdb, uint32_t destnode, struct ctdb_statistics *status)
+{
+       int ret;
+       TDB_DATA data;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_STATISTICS, 0, tdb_null, 
+                          ctdb, &data, &res, NULL, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for statistics failed\n"));
+               return -1;
+       }
+
+       if (data.dsize != sizeof(struct ctdb_statistics)) {
+               DEBUG(DEBUG_ERR,(__location__ " Wrong statistics size %u - expected %u\n",
+                        (unsigned)data.dsize, (unsigned)sizeof(struct ctdb_statistics)));
+                     return -1;
+       }
+
+       *status = *(struct ctdb_statistics *)data.dptr;
+       talloc_free(data.dptr);
+                       
+       return 0;
+}
+
+/*
+ * get db statistics
+ */
+int ctdb_ctrl_dbstatistics(struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
+                          TALLOC_CTX *mem_ctx, struct ctdb_db_statistics **dbstat)
+{
+       int ret;
+       TDB_DATA indata, outdata;
+       int32_t res;
+       struct ctdb_db_statistics *wire, *s;
+       char *ptr;
+       int i;
+
+       indata.dptr = (uint8_t *)&dbid;
+       indata.dsize = sizeof(dbid);
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DB_STATISTICS,
+                          0, indata, ctdb, &outdata, &res, NULL, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for dbstatistics failed\n"));
+               return -1;
+       }
+
+       if (outdata.dsize < offsetof(struct ctdb_db_statistics, hot_keys_wire)) {
+               DEBUG(DEBUG_ERR,(__location__ " Wrong dbstatistics size %zi - expected >= %lu\n",
+                                outdata.dsize,
+                                (long unsigned int)sizeof(struct ctdb_statistics)));
+               return -1;
+       }
+
+       s = talloc_zero(mem_ctx, struct ctdb_db_statistics);
+       if (s == NULL) {
+               talloc_free(outdata.dptr);
+               CTDB_NO_MEMORY(ctdb, s);
+       }
+
+       wire = (struct ctdb_db_statistics *)outdata.dptr;
+       *s = *wire;
+       ptr = &wire->hot_keys_wire[0];
+       for (i=0; i<wire->num_hot_keys; i++) {
+               s->hot_keys[i].key.dptr = talloc_size(mem_ctx, s->hot_keys[i].key.dsize);
+               if (s->hot_keys[i].key.dptr == NULL) {
+                       talloc_free(outdata.dptr);
+                       CTDB_NO_MEMORY(ctdb, s->hot_keys[i].key.dptr);
+               }
+
+               memcpy(s->hot_keys[i].key.dptr, ptr, s->hot_keys[i].key.dsize);
+               ptr += wire->hot_keys[i].key.dsize;
+       }
+
+       talloc_free(outdata.dptr);
+       *dbstat = s;
+       return 0;
+}
+
+/*
+  shutdown a remote ctdb node
+ */
+int ctdb_ctrl_shutdown(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+{
+       struct ctdb_client_control_state *state;
+
+       state = ctdb_control_send(ctdb, destnode, 0, 
+                          CTDB_CONTROL_SHUTDOWN, 0, tdb_null, 
+                          NULL, &timeout, NULL);
+       if (state == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for shutdown failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  get vnn map from a remote node
+ */
+int ctdb_ctrl_getvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_vnn_map **vnnmap)
+{
+       int ret;
+       TDB_DATA outdata;
+       int32_t res;
+       struct ctdb_vnn_map_wire *map;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GETVNNMAP, 0, tdb_null, 
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getvnnmap failed\n"));
+               return -1;
+       }
+       
+       map = (struct ctdb_vnn_map_wire *)outdata.dptr;
+       if (outdata.dsize < offsetof(struct ctdb_vnn_map_wire, map) ||
+           outdata.dsize != map->size*sizeof(uint32_t) + offsetof(struct ctdb_vnn_map_wire, map)) {
+               DEBUG(DEBUG_ERR,("Bad vnn map size received in ctdb_ctrl_getvnnmap\n"));
+               return -1;
+       }
+
+       (*vnnmap) = talloc(mem_ctx, struct ctdb_vnn_map);
+       CTDB_NO_MEMORY(ctdb, *vnnmap);
+       (*vnnmap)->generation = map->generation;
+       (*vnnmap)->size       = map->size;
+       (*vnnmap)->map        = talloc_array(*vnnmap, uint32_t, map->size);
+
+       CTDB_NO_MEMORY(ctdb, (*vnnmap)->map);
+       memcpy((*vnnmap)->map, map->map, sizeof(uint32_t)*map->size);
+       talloc_free(outdata.dptr);
+                   
+       return 0;
+}
+
+
+/*
+  get the recovery mode of a remote node
+ */
+struct ctdb_client_control_state *
+ctdb_ctrl_getrecmode_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
+{
+       return ctdb_control_send(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_RECMODE, 0, tdb_null, 
+                          mem_ctx, &timeout, NULL);
+}
+
+int ctdb_ctrl_getrecmode_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmode)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmode_recv failed\n"));
+               return -1;
+       }
+
+       if (recmode) {
+               *recmode = (uint32_t)res;
+       }
+
+       return 0;
+}
+
+int ctdb_ctrl_getrecmode(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmode)
+{
+       struct ctdb_client_control_state *state;
+
+       state = ctdb_ctrl_getrecmode_send(ctdb, mem_ctx, timeout, destnode);
+       return ctdb_ctrl_getrecmode_recv(ctdb, mem_ctx, state, recmode);
+}
+
+
+
+
+/*
+  set the recovery mode of a remote node
+ */
+int ctdb_ctrl_setrecmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmode)
+{
+       int ret;
+       TDB_DATA data;
+       int32_t res;
+
+       data.dsize = sizeof(uint32_t);
+       data.dptr = (unsigned char *)&recmode;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_SET_RECMODE, 0, data, 
+                          NULL, NULL, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmode failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+
+
+/*
+  get the recovery master of a remote node
+ */
+struct ctdb_client_control_state *
+ctdb_ctrl_getrecmaster_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, 
+                       struct timeval timeout, uint32_t destnode)
+{
+       return ctdb_control_send(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_RECMASTER, 0, tdb_null, 
+                          mem_ctx, &timeout, NULL);
+}
+
+int ctdb_ctrl_getrecmaster_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, uint32_t *recmaster)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_getrecmaster_recv failed\n"));
+               return -1;
+       }
+
+       if (recmaster) {
+               *recmaster = (uint32_t)res;
+       }
+
+       return 0;
+}
+
+int ctdb_ctrl_getrecmaster(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t *recmaster)
+{
+       struct ctdb_client_control_state *state;
+
+       state = ctdb_ctrl_getrecmaster_send(ctdb, mem_ctx, timeout, destnode);
+       return ctdb_ctrl_getrecmaster_recv(ctdb, mem_ctx, state, recmaster);
+}
+
+
+/*
+  set the recovery master of a remote node
+ */
+int ctdb_ctrl_setrecmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t recmaster)
+{
+       int ret;
+       TDB_DATA data;
+       int32_t res;
+
+       ZERO_STRUCT(data);
+       data.dsize = sizeof(uint32_t);
+       data.dptr = (unsigned char *)&recmaster;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_SET_RECMASTER, 0, data, 
+                          NULL, NULL, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setrecmaster failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+
+/*
+  get a list of databases off a remote node
+ */
+int ctdb_ctrl_getdbmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, 
+                      TALLOC_CTX *mem_ctx, struct ctdb_dbid_map **dbmap)
+{
+       int ret;
+       TDB_DATA outdata;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_DBMAP, 0, tdb_null, 
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getdbmap failed ret:%d res:%d\n", ret, res));
+               return -1;
+       }
+
+       *dbmap = (struct ctdb_dbid_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
+       talloc_free(outdata.dptr);
+                   
+       return 0;
+}
+
+/*
+  get a list of nodes (vnn and flags ) from a remote node
+ */
+int ctdb_ctrl_getnodemap(struct ctdb_context *ctdb, 
+               struct timeval timeout, uint32_t destnode, 
+               TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
+{
+       int ret;
+       TDB_DATA outdata;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_NODEMAP, 0, tdb_null, 
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret == 0 && res == -1 && outdata.dsize == 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed, falling back to ipv4-only control\n"));
+               return ctdb_ctrl_getnodemapv4(ctdb, timeout, destnode, mem_ctx, nodemap);
+       }
+       if (ret != 0 || res != 0 || outdata.dsize == 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodes failed ret:%d res:%d\n", ret, res));
+               return -1;
+       }
+
+       *nodemap = (struct ctdb_node_map *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
+       talloc_free(outdata.dptr);
+                   
+       return 0;
+}
+
+/*
+  old style ipv4-only get a list of nodes (vnn and flags ) from a remote node
+ */
+int ctdb_ctrl_getnodemapv4(struct ctdb_context *ctdb, 
+               struct timeval timeout, uint32_t destnode, 
+               TALLOC_CTX *mem_ctx, struct ctdb_node_map **nodemap)
+{
+       int ret, i, len;
+       TDB_DATA outdata;
+       struct ctdb_node_mapv4 *nodemapv4;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_NODEMAPv4, 0, tdb_null, 
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0 || outdata.dsize == 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getnodesv4 failed ret:%d res:%d\n", ret, res));
+               return -1;
+       }
+
+       nodemapv4 = (struct ctdb_node_mapv4 *)outdata.dptr;
+
+       len = offsetof(struct ctdb_node_map, nodes) + nodemapv4->num*sizeof(struct ctdb_node_and_flags);
+       (*nodemap) = talloc_zero_size(mem_ctx, len);
+       CTDB_NO_MEMORY(ctdb, (*nodemap));
+
+       (*nodemap)->num = nodemapv4->num;
+       for (i=0; i<nodemapv4->num; i++) {
+               (*nodemap)->nodes[i].pnn     = nodemapv4->nodes[i].pnn;
+               (*nodemap)->nodes[i].flags   = nodemapv4->nodes[i].flags;
+               (*nodemap)->nodes[i].addr.ip = nodemapv4->nodes[i].sin;
+               (*nodemap)->nodes[i].addr.sa.sa_family = AF_INET;
+       }
+               
+       talloc_free(outdata.dptr);
+                   
+       return 0;
+}
+
+/*
+  drop the transport, reload the nodes file and restart the transport
+ */
+int ctdb_ctrl_reload_nodes_file(struct ctdb_context *ctdb, 
+                   struct timeval timeout, uint32_t destnode)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_RELOAD_NODES_FILE, 0, tdb_null, 
+                          NULL, NULL, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reloadnodesfile failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+
+/*
+  set vnn map on a node
+ */
+int ctdb_ctrl_setvnnmap(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, 
+                       TALLOC_CTX *mem_ctx, struct ctdb_vnn_map *vnnmap)
+{
+       int ret;
+       TDB_DATA data;
+       int32_t res;
+       struct ctdb_vnn_map_wire *map;
+       size_t len;
+
+       len = offsetof(struct ctdb_vnn_map_wire, map) + sizeof(uint32_t)*vnnmap->size;
+       map = talloc_size(mem_ctx, len);
+       CTDB_NO_MEMORY(ctdb, map);
+
+       map->generation = vnnmap->generation;
+       map->size = vnnmap->size;
+       memcpy(map->map, vnnmap->map, sizeof(uint32_t)*map->size);
+       
+       data.dsize = len;
+       data.dptr  = (uint8_t *)map;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_SETVNNMAP, 0, data, 
+                          NULL, NULL, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setvnnmap failed\n"));
+               return -1;
+       }
+
+       talloc_free(map);
+
+       return 0;
+}
+
+
+/*
+  async send for pull database
+ */
+struct ctdb_client_control_state *ctdb_ctrl_pulldb_send(
+       struct ctdb_context *ctdb, uint32_t destnode, uint32_t dbid,
+       uint32_t lmaster, TALLOC_CTX *mem_ctx, struct timeval timeout)
+{
+       TDB_DATA indata;
+       struct ctdb_control_pulldb *pull;
+       struct ctdb_client_control_state *state;
+
+       pull = talloc(mem_ctx, struct ctdb_control_pulldb);
+       CTDB_NO_MEMORY_NULL(ctdb, pull);
+
+       pull->db_id   = dbid;
+       pull->lmaster = lmaster;
+
+       indata.dsize = sizeof(struct ctdb_control_pulldb);
+       indata.dptr  = (unsigned char *)pull;
+
+       state = ctdb_control_send(ctdb, destnode, 0, 
+                                 CTDB_CONTROL_PULL_DB, 0, indata, 
+                                 mem_ctx, &timeout, NULL);
+       talloc_free(pull);
+
+       return state;
+}
+
+/*
+  async recv for pull database
+ */
+int ctdb_ctrl_pulldb_recv(
+       struct ctdb_context *ctdb, 
+       TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state, 
+       TDB_DATA *outdata)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control_recv(ctdb, state, mem_ctx, outdata, &res, NULL);
+       if ( (ret != 0) || (res != 0) ){
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_pulldb_recv failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  pull all keys and records for a specific database on a node
+ */
+int ctdb_ctrl_pulldb(struct ctdb_context *ctdb, uint32_t destnode, 
+               uint32_t dbid, uint32_t lmaster, 
+               TALLOC_CTX *mem_ctx, struct timeval timeout,
+               TDB_DATA *outdata)
+{
+       struct ctdb_client_control_state *state;
+
+       state = ctdb_ctrl_pulldb_send(ctdb, destnode, dbid, lmaster, mem_ctx,
+                                     timeout);
+       
+       return ctdb_ctrl_pulldb_recv(ctdb, mem_ctx, state, outdata);
+}
+
+
+/*
+  change dmaster for all keys in the database to the new value
+ */
+int ctdb_ctrl_setdmaster(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, 
+                        TALLOC_CTX *mem_ctx, uint32_t dbid, uint32_t dmaster)
+{
+       int ret;
+       TDB_DATA indata;
+       int32_t res;
+
+       indata.dsize = 2*sizeof(uint32_t);
+       indata.dptr = (unsigned char *)talloc_array(mem_ctx, uint32_t, 2);
+
+       ((uint32_t *)(&indata.dptr[0]))[0] = dbid;
+       ((uint32_t *)(&indata.dptr[0]))[1] = dmaster;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_SET_DMASTER, 0, indata, 
+                          NULL, NULL, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for setdmaster failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  ping a node, return number of clients connected
+ */
+int ctdb_ctrl_ping(struct ctdb_context *ctdb, uint32_t destnode)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_PING, 0, 
+                          tdb_null, NULL, NULL, &res, NULL, NULL);
+       if (ret != 0) {
+               return -1;
+       }
+       return res;
+}
+
+int ctdb_ctrl_get_runstate(struct ctdb_context *ctdb, 
+                          struct timeval timeout, 
+                          uint32_t destnode,
+                          uint32_t *runstate)
+{
+       TDB_DATA outdata;
+       int32_t res;
+       int ret;
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_RUNSTATE, 0,
+                          tdb_null, ctdb, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,("ctdb_control for get_runstate failed\n"));
+               return ret != 0 ? ret : res;
+       }
+
+       if (outdata.dsize != sizeof(uint32_t)) {
+               DEBUG(DEBUG_ERR,("Invalid return data in get_runstate\n"));
+               talloc_free(outdata.dptr);
+               return -1;
+       }
+
+       if (runstate != NULL) {
+               *runstate = *(uint32_t *)outdata.dptr;
+       }
+       talloc_free(outdata.dptr);
+
+       return 0;
+}
+
+/*
+  find the real path to a ltdb 
+ */
+int ctdb_ctrl_getdbpath(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx, 
+                  const char **path)
+{
+       int ret;
+       int32_t res;
+       TDB_DATA data;
+
+       data.dptr = (uint8_t *)&dbid;
+       data.dsize = sizeof(dbid);
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GETDBPATH, 0, data, 
+                          mem_ctx, &data, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               return -1;
+       }
+
+       (*path) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
+       if ((*path) == NULL) {
+               return -1;
+       }
+
+       talloc_free(data.dptr);
+
+       return 0;
+}
+
+/*
+  find the name of a db 
+ */
+int ctdb_ctrl_getdbname(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t dbid, TALLOC_CTX *mem_ctx, 
+                  const char **name)
+{
+       int ret;
+       int32_t res;
+       TDB_DATA data;
+
+       data.dptr = (uint8_t *)&dbid;
+       data.dsize = sizeof(dbid);
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_DBNAME, 0, data, 
+                          mem_ctx, &data, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               return -1;
+       }
+
+       (*name) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
+       if ((*name) == NULL) {
+               return -1;
+       }
+
+       talloc_free(data.dptr);
+
+       return 0;
+}
+
+/*
+  get the health status of a db
+ */
+int ctdb_ctrl_getdbhealth(struct ctdb_context *ctdb,
+                         struct timeval timeout,
+                         uint32_t destnode,
+                         uint32_t dbid, TALLOC_CTX *mem_ctx,
+                         const char **reason)
+{
+       int ret;
+       int32_t res;
+       TDB_DATA data;
+
+       data.dptr = (uint8_t *)&dbid;
+       data.dsize = sizeof(dbid);
+
+       ret = ctdb_control(ctdb, destnode, 0,
+                          CTDB_CONTROL_DB_GET_HEALTH, 0, data,
+                          mem_ctx, &data, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               return -1;
+       }
+
+       if (data.dsize == 0) {
+               (*reason) = NULL;
+               return 0;
+       }
+
+       (*reason) = talloc_strndup(mem_ctx, (const char *)data.dptr, data.dsize);
+       if ((*reason) == NULL) {
+               return -1;
+       }
+
+       talloc_free(data.dptr);
+
+       return 0;
+}
+
+/*
+ * get db sequence number
+ */
+int ctdb_ctrl_getdbseqnum(struct ctdb_context *ctdb, struct timeval timeout,
+                         uint32_t destnode, uint32_t dbid, uint64_t *seqnum)
+{
+       int ret;
+       int32_t res;
+       TDB_DATA data, outdata;
+
+       data.dptr = (uint8_t *)&dbid;
+       data.dsize = sizeof(uint64_t);  /* This is just wrong */
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DB_SEQNUM,
+                          0, data, ctdb, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,("ctdb_control for getdbesqnum failed\n"));
+               return -1;
+       }
+
+       if (outdata.dsize != sizeof(uint64_t)) {
+               DEBUG(DEBUG_ERR,("Invalid return data in get_dbseqnum\n"));
+               talloc_free(outdata.dptr);
+               return -1;
+       }
+
+       if (seqnum != NULL) {
+               *seqnum = *(uint64_t *)outdata.dptr;
+       }
+       talloc_free(outdata.dptr);
+
+       return 0;
+}
+
+/*
+  create a database
+ */
+int ctdb_ctrl_createdb(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, 
+                      TALLOC_CTX *mem_ctx, const char *name, bool persistent)
+{
+       int ret;
+       int32_t res;
+       TDB_DATA data;
+       uint64_t tdb_flags = 0;
+
+       data.dptr = discard_const(name);
+       data.dsize = strlen(name)+1;
+
+       /* Make sure that volatile databases use jenkins hash */
+       if (!persistent) {
+               tdb_flags = TDB_INCOMPATIBLE_HASH;
+       }
+
+       ret = ctdb_control(ctdb, destnode, tdb_flags,
+                          persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH, 
+                          0, data, 
+                          mem_ctx, &data, &res, &timeout, NULL);
+
+       if (ret != 0 || res != 0) {
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  get debug level on a node
+ */
+int ctdb_ctrl_get_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t *level)
+{
+       int ret;
+       int32_t res;
+       TDB_DATA data;
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_DEBUG, 0, tdb_null, 
+                          ctdb, &data, &res, NULL, NULL);
+       if (ret != 0 || res != 0) {
+               return -1;
+       }
+       if (data.dsize != sizeof(int32_t)) {
+               DEBUG(DEBUG_ERR,("Bad control reply size in ctdb_get_debuglevel (got %u)\n",
+                        (unsigned)data.dsize));
+               return -1;
+       }
+       *level = *(int32_t *)data.dptr;
+       talloc_free(data.dptr);
+       return 0;
+}
+
+/*
+  set debug level on a node
+ */
+int ctdb_ctrl_set_debuglevel(struct ctdb_context *ctdb, uint32_t destnode, int32_t level)
+{
+       int ret;
+       int32_t res;
+       TDB_DATA data;
+
+       data.dptr = (uint8_t *)&level;
+       data.dsize = sizeof(level);
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_DEBUG, 0, data, 
+                          NULL, NULL, &res, NULL, NULL);
+       if (ret != 0 || res != 0) {
+               return -1;
+       }
+       return 0;
+}
+
+
+/*
+  get a list of connected nodes
+ */
+uint32_t *ctdb_get_connected_nodes(struct ctdb_context *ctdb, 
+                               struct timeval timeout,
+                               TALLOC_CTX *mem_ctx,
+                               uint32_t *num_nodes)
+{
+       struct ctdb_node_map *map=NULL;
+       int ret, i;
+       uint32_t *nodes;
+
+       *num_nodes = 0;
+
+       ret = ctdb_ctrl_getnodemap(ctdb, timeout, CTDB_CURRENT_NODE, mem_ctx, &map);
+       if (ret != 0) {
+               return NULL;
+       }
+
+       nodes = talloc_array(mem_ctx, uint32_t, map->num);
+       if (nodes == NULL) {
+               return NULL;
+       }
+
+       for (i=0;i<map->num;i++) {
+               if (!(map->nodes[i].flags & NODE_FLAGS_DISCONNECTED)) {
+                       nodes[*num_nodes] = map->nodes[i].pnn;
+                       (*num_nodes)++;
+               }
+       }
+
+       return nodes;
+}
+
+
+/*
+  reset remote status
+ */
+int ctdb_statistics_reset(struct ctdb_context *ctdb, uint32_t destnode)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_STATISTICS_RESET, 0, tdb_null, 
+                          NULL, NULL, &res, NULL, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for reset statistics failed\n"));
+               return -1;
+       }
+       return 0;
+}
+
+/*
+  attach to a specific database - client call
+*/
+struct ctdb_db_context *ctdb_attach(struct ctdb_context *ctdb,
+                                   struct timeval timeout,
+                                   const char *name,
+                                   bool persistent,
+                                   uint32_t tdb_flags)
+{
+       struct ctdb_db_context *ctdb_db;
+       TDB_DATA data;
+       int ret;
+       int32_t res;
+
+       ctdb_db = ctdb_db_handle(ctdb, name);
+       if (ctdb_db) {
+               return ctdb_db;
+       }
+
+       ctdb_db = talloc_zero(ctdb, struct ctdb_db_context);
+       CTDB_NO_MEMORY_NULL(ctdb, ctdb_db);
+
+       ctdb_db->ctdb = ctdb;
+       ctdb_db->db_name = talloc_strdup(ctdb_db, name);
+       CTDB_NO_MEMORY_NULL(ctdb, ctdb_db->db_name);
+
+       data.dptr = discard_const(name);
+       data.dsize = strlen(name)+1;
+
+       /* CTDB has switched to using jenkins hash for volatile databases.
+        * Even if tdb_flags do not explicitly mention TDB_INCOMPATIBLE_HASH,
+        * always set it.
+        */
+       if (!persistent) {
+               tdb_flags |= TDB_INCOMPATIBLE_HASH;
+       }
+
+       /* tell ctdb daemon to attach */
+       ret = ctdb_control(ctdb, CTDB_CURRENT_NODE, tdb_flags, 
+                          persistent?CTDB_CONTROL_DB_ATTACH_PERSISTENT:CTDB_CONTROL_DB_ATTACH,
+                          0, data, ctdb_db, &data, &res, NULL, NULL);
+       if (ret != 0 || res != 0 || data.dsize != sizeof(uint32_t)) {
+               DEBUG(DEBUG_ERR,("Failed to attach to database '%s'\n", name));
+               talloc_free(ctdb_db);
+               return NULL;
+       }
+       
+       ctdb_db->db_id = *(uint32_t *)data.dptr;
+       talloc_free(data.dptr);
+
+       ret = ctdb_ctrl_getdbpath(ctdb, timeout, CTDB_CURRENT_NODE, ctdb_db->db_id, ctdb_db, &ctdb_db->db_path);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,("Failed to get dbpath for database '%s'\n", name));
+               talloc_free(ctdb_db);
+               return NULL;
+       }
+
+       tdb_flags = persistent?TDB_DEFAULT:TDB_NOSYNC;
+       if (ctdb->valgrinding) {
+               tdb_flags |= TDB_NOMMAP;
+       }
+       tdb_flags |= TDB_DISALLOW_NESTING;
+
+       ctdb_db->ltdb = tdb_wrap_open(ctdb, ctdb_db->db_path, 0, tdb_flags, O_RDWR, 0);
+       if (ctdb_db->ltdb == NULL) {
+               ctdb_set_error(ctdb, "Failed to open tdb '%s'\n", ctdb_db->db_path);
+               talloc_free(ctdb_db);
+               return NULL;
+       }
+
+       ctdb_db->persistent = persistent;
+
+       DLIST_ADD(ctdb->db_list, ctdb_db);
+
+       /* add well known functions */
+       ctdb_set_call(ctdb_db, ctdb_null_func, CTDB_NULL_FUNC);
+       ctdb_set_call(ctdb_db, ctdb_fetch_func, CTDB_FETCH_FUNC);
+       ctdb_set_call(ctdb_db, ctdb_fetch_with_header_func, CTDB_FETCH_WITH_HEADER_FUNC);
+
+       return ctdb_db;
+}
+
+
+/*
+  setup a call for a database
+ */
+int ctdb_set_call(struct ctdb_db_context *ctdb_db, ctdb_fn_t fn, uint32_t id)
+{
+       struct ctdb_registered_call *call;
+
+#if 0
+       TDB_DATA data;
+       int32_t status;
+       struct ctdb_control_set_call c;
+       int ret;
+
+       /* this is no longer valid with the separate daemon architecture */
+       c.db_id = ctdb_db->db_id;
+       c.fn    = fn;
+       c.id    = id;
+
+       data.dptr = (uint8_t *)&c;
+       data.dsize = sizeof(c);
+
+       ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_SET_CALL, 0,
+                          data, NULL, NULL, &status, NULL, NULL);
+       if (ret != 0 || status != 0) {
+               DEBUG(DEBUG_ERR,("ctdb_set_call failed for call %u\n", id));
+               return -1;
+       }
+#endif
+
+       /* also register locally */
+       call = talloc(ctdb_db, struct ctdb_registered_call);
+       call->fn = fn;
+       call->id = id;
+
+       DLIST_ADD(ctdb_db->calls, call);        
+       return 0;
+}
+
+
+struct traverse_state {
+       bool done;
+       uint32_t count;
+       ctdb_traverse_func fn;
+       void *private_data;
+       bool listemptyrecords;
+};
+
+/*
+  called on each key during a ctdb_traverse
+ */
+static void traverse_handler(struct ctdb_context *ctdb, uint64_t srvid, TDB_DATA data, void *p)
+{
+       struct traverse_state *state = (struct traverse_state *)p;
+       struct ctdb_rec_data *d = (struct ctdb_rec_data *)data.dptr;
+       TDB_DATA key;
+
+       if (data.dsize < sizeof(uint32_t) ||
+           d->length != data.dsize) {
+               DEBUG(DEBUG_ERR,("Bad data size %u in traverse_handler\n", (unsigned)data.dsize));
+               state->done = true;
+               return;
+       }
+
+       key.dsize = d->keylen;
+       key.dptr  = &d->data[0];
+       data.dsize = d->datalen;
+       data.dptr = &d->data[d->keylen];
+
+       if (key.dsize == 0 && data.dsize == 0) {
+               /* end of traverse */
+               state->done = true;
+               return;
+       }
+
+       if (!state->listemptyrecords &&
+           data.dsize == sizeof(struct ctdb_ltdb_header))
+       {
+               /* empty records are deleted records in ctdb */
+               return;
+       }
+
+       if (state->fn(ctdb, key, data, state->private_data) != 0) {
+               state->done = true;
+       }
+
+       state->count++;
+}
+
+/**
+ * start a cluster wide traverse, calling the supplied fn on each record
+ * return the number of records traversed, or -1 on error
+ *
+ * Extendet variant with a flag to signal whether empty records should
+ * be listed.
+ */
+static int ctdb_traverse_ext(struct ctdb_db_context *ctdb_db,
+                            ctdb_traverse_func fn,
+                            bool withemptyrecords,
+                            void *private_data)
+{
+       TDB_DATA data;
+       struct ctdb_traverse_start_ext t;
+       int32_t status;
+       int ret;
+       uint64_t srvid = (getpid() | 0xFLL<<60);
+       struct traverse_state state;
+
+       state.done = false;
+       state.count = 0;
+       state.private_data = private_data;
+       state.fn = fn;
+       state.listemptyrecords = withemptyrecords;
+
+       ret = ctdb_client_set_message_handler(ctdb_db->ctdb, srvid, traverse_handler, &state);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,("Failed to setup traverse handler\n"));
+               return -1;
+       }
+
+       t.db_id = ctdb_db->db_id;
+       t.srvid = srvid;
+       t.reqid = 0;
+       t.withemptyrecords = withemptyrecords;
+
+       data.dptr = (uint8_t *)&t;
+       data.dsize = sizeof(t);
+
+       ret = ctdb_control(ctdb_db->ctdb, CTDB_CURRENT_NODE, 0, CTDB_CONTROL_TRAVERSE_START_EXT, 0,
+                          data, NULL, NULL, &status, NULL, NULL);
+       if (ret != 0 || status != 0) {
+               DEBUG(DEBUG_ERR,("ctdb_traverse_all failed\n"));
+               ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
+               return -1;
+       }
+
+       while (!state.done) {
+               event_loop_once(ctdb_db->ctdb->ev);
+       }
+
+       ret = ctdb_client_remove_message_handler(ctdb_db->ctdb, srvid, &state);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,("Failed to remove ctdb_traverse handler\n"));
+               return -1;
+       }
+
+       return state.count;
+}
+
+/**
+ * start a cluster wide traverse, calling the supplied fn on each record
+ * return the number of records traversed, or -1 on error
+ *
+ * Standard version which does not list the empty records:
+ * These are considered deleted.
+ */
+int ctdb_traverse(struct ctdb_db_context *ctdb_db, ctdb_traverse_func fn, void *private_data)
+{
+       return ctdb_traverse_ext(ctdb_db, fn, false, private_data);
+}
+
+#define ISASCII(x) (isprint(x) && !strchr("\"\\", (x)))
+/*
+  called on each key during a catdb
+ */
+int ctdb_dumpdb_record(struct ctdb_context *ctdb, TDB_DATA key, TDB_DATA data, void *p)
+{
+       int i;
+       struct ctdb_dump_db_context *c = (struct ctdb_dump_db_context *)p;
+       FILE *f = c->f;
+       struct ctdb_ltdb_header *h = (struct ctdb_ltdb_header *)data.dptr;
+
+       fprintf(f, "key(%u) = \"", (unsigned)key.dsize);
+       for (i=0;i<key.dsize;i++) {
+               if (ISASCII(key.dptr[i])) {
+                       fprintf(f, "%c", key.dptr[i]);
+               } else {
+                       fprintf(f, "\\%02X", key.dptr[i]);
+               }
+       }
+       fprintf(f, "\"\n");
+
+       fprintf(f, "dmaster: %u\n", h->dmaster);
+       fprintf(f, "rsn: %llu\n", (unsigned long long)h->rsn);
+
+       if (c->printlmaster && ctdb->vnn_map != NULL) {
+               fprintf(f, "lmaster: %u\n", ctdb_lmaster(ctdb, &key));
+       }
+
+       if (c->printhash) {
+               fprintf(f, "hash: 0x%08x\n", ctdb_hash(&key));
+       }
+
+       if (c->printrecordflags) {
+               fprintf(f, "flags: 0x%08x", h->flags);
+               if (h->flags & CTDB_REC_FLAG_MIGRATED_WITH_DATA) printf(" MIGRATED_WITH_DATA");
+               if (h->flags & CTDB_REC_FLAG_VACUUM_MIGRATED) printf(" VACUUM_MIGRATED");
+               if (h->flags & CTDB_REC_FLAG_AUTOMATIC) printf(" AUTOMATIC");
+               if (h->flags & CTDB_REC_RO_HAVE_DELEGATIONS) printf(" RO_HAVE_DELEGATIONS");
+               if (h->flags & CTDB_REC_RO_HAVE_READONLY) printf(" RO_HAVE_READONLY");
+               if (h->flags & CTDB_REC_RO_REVOKING_READONLY) printf(" RO_REVOKING_READONLY");
+               if (h->flags & CTDB_REC_RO_REVOKE_COMPLETE) printf(" RO_REVOKE_COMPLETE");
+               fprintf(f, "\n");
+       }
+
+       if (c->printdatasize) {
+               fprintf(f, "data size: %u\n", (unsigned)data.dsize);
+       } else {
+               fprintf(f, "data(%u) = \"", (unsigned)(data.dsize - sizeof(*h)));
+               for (i=sizeof(*h);i<data.dsize;i++) {
+                       if (ISASCII(data.dptr[i])) {
+                               fprintf(f, "%c", data.dptr[i]);
+                       } else {
+                               fprintf(f, "\\%02X", data.dptr[i]);
+                       }
+               }
+               fprintf(f, "\"\n");
+       }
+
+       fprintf(f, "\n");
+
+       return 0;
+}
+
+/*
+  convenience function to list all keys to stdout
+ */
+int ctdb_dump_db(struct ctdb_db_context *ctdb_db,
+                struct ctdb_dump_db_context *ctx)
+{
+       return ctdb_traverse_ext(ctdb_db, ctdb_dumpdb_record,
+                                ctx->printemptyrecords, ctx);
+}
+
+/*
+  get the pid of a ctdb daemon
+ */
+int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *pid)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_PID, 0, tdb_null, 
+                          NULL, NULL, &res, &timeout, NULL);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpid failed\n"));
+               return -1;
+       }
+
+       *pid = res;
+
+       return 0;
+}
+
+
+/*
+  async freeze send control
+ */
+struct ctdb_client_control_state *
+ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t priority)
+{
+       return ctdb_control_send(ctdb, destnode, priority, 
+                          CTDB_CONTROL_FREEZE, 0, tdb_null, 
+                          mem_ctx, &timeout, NULL);
+}
+
+/* 
+   async freeze recv control
+*/
+int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct ctdb_client_control_state *state)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control_recv(ctdb, state, mem_ctx, NULL, &res, NULL);
+       if ( (ret != 0) || (res != 0) ){
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_ctrl_freeze_recv failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  freeze databases of a certain priority
+ */
+int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
+{
+       TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+       struct ctdb_client_control_state *state;
+       int ret;
+
+       state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode, priority);
+       ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
+       talloc_free(tmp_ctx);
+
+       return ret;
+}
+
+/* Freeze all databases */
+int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+{
+       int i;
+
+       for (i=1; i<=NUM_DB_PRIORITIES; i++) {
+               if (ctdb_ctrl_freeze_priority(ctdb, timeout, destnode, i) != 0) {
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+/*
+  thaw databases of a certain priority
+ */
+int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, priority, 
+                          CTDB_CONTROL_THAW, 0, tdb_null, 
+                          NULL, NULL, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control thaw failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+/* thaw all databases */
+int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+{
+       return ctdb_ctrl_thaw_priority(ctdb, timeout, destnode, 0);
+}
+
+/*
+  get pnn of a node, or -1
+ */
+int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_PNN, 0, tdb_null, 
+                          NULL, NULL, &res, &timeout, NULL);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpnn failed\n"));
+               return -1;
+       }
+
+       return res;
+}
+
+/*
+  get the monitoring mode of a remote node
+ */
+int ctdb_ctrl_getmonmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t *monmode)
+{
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_MONMODE, 0, tdb_null, 
+                          NULL, NULL, &res, &timeout, NULL);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getmonmode failed\n"));
+               return -1;
+       }
+
+       *monmode = res;
+
+       return 0;
+}
+
+
+/*
+ set the monitoring mode of a remote node to active
+ */
+int ctdb_ctrl_enable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+{
+       int ret;
+       
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_ENABLE_MONITOR, 0, tdb_null, 
+                          NULL, NULL,NULL, &timeout, NULL);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for enable_monitor failed\n"));
+               return -1;
+       }
+
+       
+
+       return 0;
+}
+
+/*
+  set the monitoring mode of a remote node to disable
+ */
+int ctdb_ctrl_disable_monmode(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+{
+       int ret;
+       
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_DISABLE_MONITOR, 0, tdb_null, 
+                          NULL, NULL, NULL, &timeout, NULL);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for disable_monitor failed\n"));
+               return -1;
+       }
+
+       
+
+       return 0;
+}
+
+
+
+/* 
+  sent to a node to make it take over an ip address
+*/
+int ctdb_ctrl_takeover_ip(struct ctdb_context *ctdb, struct timeval timeout, 
+                         uint32_t destnode, struct ctdb_public_ip *ip)
+{
+       TDB_DATA data;
+       struct ctdb_public_ipv4 ipv4;
+       int ret;
+       int32_t res;
+
+       if (ip->addr.sa.sa_family == AF_INET) {
+               ipv4.pnn = ip->pnn;
+               ipv4.sin = ip->addr.ip;
+
+               data.dsize = sizeof(ipv4);
+               data.dptr  = (uint8_t *)&ipv4;
+
+               ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IPv4, 0, data, NULL,
+                          NULL, &res, &timeout, NULL);
+       } else {
+               data.dsize = sizeof(*ip);
+               data.dptr  = (uint8_t *)ip;
+
+               ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_TAKEOVER_IP, 0, data, NULL,
+                          NULL, &res, &timeout, NULL);
+       }
+
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for takeover_ip failed\n"));
+               return -1;
+       }
+
+       return 0;       
+}
+
+
+/* 
+  sent to a node to make it release an ip address
+*/
+int ctdb_ctrl_release_ip(struct ctdb_context *ctdb, struct timeval timeout, 
+                        uint32_t destnode, struct ctdb_public_ip *ip)
+{
+       TDB_DATA data;
+       struct ctdb_public_ipv4 ipv4;
+       int ret;
+       int32_t res;
+
+       if (ip->addr.sa.sa_family == AF_INET) {
+               ipv4.pnn = ip->pnn;
+               ipv4.sin = ip->addr.ip;
+
+               data.dsize = sizeof(ipv4);
+               data.dptr  = (uint8_t *)&ipv4;
+
+               ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IPv4, 0, data, NULL,
+                                  NULL, &res, &timeout, NULL);
+       } else {
+               data.dsize = sizeof(*ip);
+               data.dptr  = (uint8_t *)ip;
+
+               ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_RELEASE_IP, 0, data, NULL,
+                                  NULL, &res, &timeout, NULL);
+       }
+
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for release_ip failed\n"));
+               return -1;
+       }
+
+       return 0;       
+}
+
+
+/*
+  get a tunable
+ */
+int ctdb_ctrl_get_tunable(struct ctdb_context *ctdb, 
+                         struct timeval timeout, 
+                         uint32_t destnode,
+                         const char *name, uint32_t *value)
+{
+       struct ctdb_control_get_tunable *t;
+       TDB_DATA data, outdata;
+       int32_t res;
+       int ret;
+
+       data.dsize = offsetof(struct ctdb_control_get_tunable, name) + strlen(name) + 1;
+       data.dptr  = talloc_size(ctdb, data.dsize);
+       CTDB_NO_MEMORY(ctdb, data.dptr);
+
+       t = (struct ctdb_control_get_tunable *)data.dptr;
+       t->length = strlen(name)+1;
+       memcpy(t->name, name, t->length);
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_TUNABLE, 0, data, ctdb,
+                          &outdata, &res, &timeout, NULL);
+       talloc_free(data.dptr);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get_tunable failed\n"));
+               return ret != 0 ? ret : res;
+       }
+
+       if (outdata.dsize != sizeof(uint32_t)) {
+               DEBUG(DEBUG_ERR,("Invalid return data in get_tunable\n"));
+               talloc_free(outdata.dptr);
+               return -1;
+       }
+       
+       *value = *(uint32_t *)outdata.dptr;
+       talloc_free(outdata.dptr);
+
+       return 0;
+}
+
+/*
+  set a tunable
+ */
+int ctdb_ctrl_set_tunable(struct ctdb_context *ctdb, 
+                         struct timeval timeout, 
+                         uint32_t destnode,
+                         const char *name, uint32_t value)
+{
+       struct ctdb_control_set_tunable *t;
+       TDB_DATA data;
+       int32_t res;
+       int ret;
+
+       data.dsize = offsetof(struct ctdb_control_set_tunable, name) + strlen(name) + 1;
+       data.dptr  = talloc_size(ctdb, data.dsize);
+       CTDB_NO_MEMORY(ctdb, data.dptr);
+
+       t = (struct ctdb_control_set_tunable *)data.dptr;
+       t->length = strlen(name)+1;
+       memcpy(t->name, name, t->length);
+       t->value = value;
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_SET_TUNABLE, 0, data, NULL,
+                          NULL, &res, &timeout, NULL);
+       talloc_free(data.dptr);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_tunable failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  list tunables
+ */
+int ctdb_ctrl_list_tunables(struct ctdb_context *ctdb, 
+                           struct timeval timeout, 
+                           uint32_t destnode,
+                           TALLOC_CTX *mem_ctx,
+                           const char ***list, uint32_t *count)
+{
+       TDB_DATA outdata;
+       int32_t res;
+       int ret;
+       struct ctdb_control_list_tunable *t;
+       char *p, *s, *ptr;
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_LIST_TUNABLES, 0, tdb_null, 
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for list_tunables failed\n"));
+               return -1;
+       }
+
+       t = (struct ctdb_control_list_tunable *)outdata.dptr;
+       if (outdata.dsize < offsetof(struct ctdb_control_list_tunable, data) ||
+           t->length > outdata.dsize-offsetof(struct ctdb_control_list_tunable, data)) {
+               DEBUG(DEBUG_ERR,("Invalid data in list_tunables reply\n"));
+               talloc_free(outdata.dptr);
+               return -1;              
+       }
+       
+       p = talloc_strndup(mem_ctx, (char *)t->data, t->length);
+       CTDB_NO_MEMORY(ctdb, p);
+
+       talloc_free(outdata.dptr);
+       
+       (*list) = NULL;
+       (*count) = 0;
+
+       for (s=strtok_r(p, ":", &ptr); s; s=strtok_r(NULL, ":", &ptr)) {
+               (*list) = talloc_realloc(mem_ctx, *list, const char *, 1+(*count));
+               CTDB_NO_MEMORY(ctdb, *list);
+               (*list)[*count] = talloc_strdup(*list, s);
+               CTDB_NO_MEMORY(ctdb, (*list)[*count]);
+               (*count)++;
+       }
+
+       talloc_free(p);
+
+       return 0;
+}
+
+
+int ctdb_ctrl_get_public_ips_flags(struct ctdb_context *ctdb,
+                                  struct timeval timeout, uint32_t destnode,
+                                  TALLOC_CTX *mem_ctx,
+                                  uint32_t flags,
+                                  struct ctdb_all_public_ips **ips)
+{
+       int ret;
+       TDB_DATA outdata;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_PUBLIC_IPS, flags, tdb_null,
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret == 0 && res == -1) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control to get public ips failed, falling back to ipv4-only version\n"));
+               return ctdb_ctrl_get_public_ipsv4(ctdb, timeout, destnode, mem_ctx, ips);
+       }
+       if (ret != 0 || res != 0) {
+         DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed ret:%d res:%d\n", ret, res));
+               return -1;
+       }
+
+       *ips = (struct ctdb_all_public_ips *)talloc_memdup(mem_ctx, outdata.dptr, outdata.dsize);
+       talloc_free(outdata.dptr);
+                   
+       return 0;
+}
+
+int ctdb_ctrl_get_public_ips(struct ctdb_context *ctdb,
+                            struct timeval timeout, uint32_t destnode,
+                            TALLOC_CTX *mem_ctx,
+                            struct ctdb_all_public_ips **ips)
+{
+       return ctdb_ctrl_get_public_ips_flags(ctdb, timeout,
+                                             destnode, mem_ctx,
+                                             0, ips);
+}
+
+int ctdb_ctrl_get_public_ipsv4(struct ctdb_context *ctdb, 
+                       struct timeval timeout, uint32_t destnode, 
+                       TALLOC_CTX *mem_ctx, struct ctdb_all_public_ips **ips)
+{
+       int ret, i, len;
+       TDB_DATA outdata;
+       int32_t res;
+       struct ctdb_all_public_ipsv4 *ipsv4;
+
+       ret = ctdb_control(ctdb, destnode, 0, 
+                          CTDB_CONTROL_GET_PUBLIC_IPSv4, 0, tdb_null, 
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for getpublicips failed\n"));
+               return -1;
+       }
+
+       ipsv4 = (struct ctdb_all_public_ipsv4 *)outdata.dptr;
+       len = offsetof(struct ctdb_all_public_ips, ips) +
+               ipsv4->num*sizeof(struct ctdb_public_ip);
+       *ips = talloc_zero_size(mem_ctx, len);
+       CTDB_NO_MEMORY(ctdb, *ips);
+       (*ips)->num = ipsv4->num;
+       for (i=0; i<ipsv4->num; i++) {
+               (*ips)->ips[i].pnn     = ipsv4->ips[i].pnn;
+               (*ips)->ips[i].addr.ip = ipsv4->ips[i].sin;
+       }
+
+       talloc_free(outdata.dptr);
+                   
+       return 0;
+}
+
+int ctdb_ctrl_get_public_ip_info(struct ctdb_context *ctdb,
+                                struct timeval timeout, uint32_t destnode,
+                                TALLOC_CTX *mem_ctx,
+                                const ctdb_sock_addr *addr,
+                                struct ctdb_control_public_ip_info **_info)
+{
+       int ret;
+       TDB_DATA indata;
+       TDB_DATA outdata;
+       int32_t res;
+       struct ctdb_control_public_ip_info *info;
+       uint32_t len;
+       uint32_t i;
+
+       indata.dptr = discard_const_p(uint8_t, addr);
+       indata.dsize = sizeof(*addr);
+
+       ret = ctdb_control(ctdb, destnode, 0,
+                          CTDB_CONTROL_GET_PUBLIC_IP_INFO, 0, indata,
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
+                               "failed ret:%d res:%d\n",
+                               ret, res));
+               return -1;
+       }
+
+       len = offsetof(struct ctdb_control_public_ip_info, ifaces);
+       if (len > outdata.dsize) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
+                               "returned invalid data with size %u > %u\n",
+                               (unsigned int)outdata.dsize,
+                               (unsigned int)len));
+               dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
+               return -1;
+       }
+
+       info = (struct ctdb_control_public_ip_info *)outdata.dptr;
+       len += info->num*sizeof(struct ctdb_control_iface_info);
+
+       if (len > outdata.dsize) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
+                               "returned invalid data with size %u > %u\n",
+                               (unsigned int)outdata.dsize,
+                               (unsigned int)len));
+               dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
+               return -1;
+       }
+
+       /* make sure we null terminate the returned strings */
+       for (i=0; i < info->num; i++) {
+               info->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
+       }
+
+       *_info = (struct ctdb_control_public_ip_info *)talloc_memdup(mem_ctx,
+                                                               outdata.dptr,
+                                                               outdata.dsize);
+       talloc_free(outdata.dptr);
+       if (*_info == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get public ip info "
+                               "talloc_memdup size %u failed\n",
+                               (unsigned int)outdata.dsize));
+               return -1;
+       }
+
+       return 0;
+}
+
+int ctdb_ctrl_get_ifaces(struct ctdb_context *ctdb,
+                        struct timeval timeout, uint32_t destnode,
+                        TALLOC_CTX *mem_ctx,
+                        struct ctdb_control_get_ifaces **_ifaces)
+{
+       int ret;
+       TDB_DATA outdata;
+       int32_t res;
+       struct ctdb_control_get_ifaces *ifaces;
+       uint32_t len;
+       uint32_t i;
+
+       ret = ctdb_control(ctdb, destnode, 0,
+                          CTDB_CONTROL_GET_IFACES, 0, tdb_null,
+                          mem_ctx, &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
+                               "failed ret:%d res:%d\n",
+                               ret, res));
+               return -1;
+       }
+
+       len = offsetof(struct ctdb_control_get_ifaces, ifaces);
+       if (len > outdata.dsize) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
+                               "returned invalid data with size %u > %u\n",
+                               (unsigned int)outdata.dsize,
+                               (unsigned int)len));
+               dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
+               return -1;
+       }
+
+       ifaces = (struct ctdb_control_get_ifaces *)outdata.dptr;
+       len += ifaces->num*sizeof(struct ctdb_control_iface_info);
+
+       if (len > outdata.dsize) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
+                               "returned invalid data with size %u > %u\n",
+                               (unsigned int)outdata.dsize,
+                               (unsigned int)len));
+               dump_data(DEBUG_DEBUG, outdata.dptr, outdata.dsize);
+               return -1;
+       }
+
+       /* make sure we null terminate the returned strings */
+       for (i=0; i < ifaces->num; i++) {
+               ifaces->ifaces[i].name[CTDB_IFACE_SIZE] = '\0';
+       }
+
+       *_ifaces = (struct ctdb_control_get_ifaces *)talloc_memdup(mem_ctx,
+                                                                 outdata.dptr,
+                                                                 outdata.dsize);
+       talloc_free(outdata.dptr);
+       if (*_ifaces == NULL) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get ifaces "
+                               "talloc_memdup size %u failed\n",
+                               (unsigned int)outdata.dsize));
+               return -1;
+       }
+
+       return 0;
+}
+
+int ctdb_ctrl_set_iface_link(struct ctdb_context *ctdb,
+                            struct timeval timeout, uint32_t destnode,
+                            TALLOC_CTX *mem_ctx,
+                            const struct ctdb_control_iface_info *info)
+{
+       int ret;
+       TDB_DATA indata;
+       int32_t res;
+
+       indata.dptr = discard_const_p(uint8_t, info);
+       indata.dsize = sizeof(*info);
+
+       ret = ctdb_control(ctdb, destnode, 0,
+                          CTDB_CONTROL_SET_IFACE_LINK_STATE, 0, indata,
+                          mem_ctx, NULL, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set iface link "
+                               "failed ret:%d res:%d\n",
+                               ret, res));
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  set/clear the permanent disabled bit on a remote node
+ */
+int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, 
+                      uint32_t set, uint32_t clear)
+{
+       int ret;
+       TDB_DATA data;
+       struct ctdb_node_map *nodemap=NULL;
+       struct ctdb_node_flag_change c;
+       TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
+       uint32_t recmaster;
+       uint32_t *nodes;
+
+
+       /* find the recovery master */
+       ret = ctdb_ctrl_getrecmaster(ctdb, tmp_ctx, timeout, CTDB_CURRENT_NODE, &recmaster);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR, (__location__ " Unable to get recmaster from local node\n"));
+               talloc_free(tmp_ctx);
+               return ret;
+       }
+
+
+       /* read the node flags from the recmaster */
+       ret = ctdb_ctrl_getnodemap(ctdb, timeout, recmaster, tmp_ctx, &nodemap);
+       if (ret != 0) {
+               DEBUG(DEBUG_ERR, (__location__ " Unable to get nodemap from node %u\n", destnode));
+               talloc_free(tmp_ctx);
+               return -1;
+       }
+       if (destnode >= nodemap->num) {
+               DEBUG(DEBUG_ERR,(__location__ " Nodemap from recmaster does not contain node %d\n", destnode));
+               talloc_free(tmp_ctx);
+               return -1;
+       }
+
+       c.pnn       = destnode;
+       c.old_flags = nodemap->nodes[destnode].flags;
+       c.new_flags = c.old_flags;
+       c.new_flags |= set;
+       c.new_flags &= ~clear;
+
+       data.dsize = sizeof(c);
+       data.dptr = (unsigned char *)&c;
+
+       /* send the flags update to all connected nodes */
+       nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
+
+       if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
+                                       nodes, 0,
+                                       timeout, false, data,
+                                       NULL, NULL,
+                                       NULL) != 0) {
+               DEBUG(DEBUG_ERR, (__location__ " Unable to update nodeflags on remote nodes\n"));
+
+               talloc_free(tmp_ctx);
+               return -1;
+       }
+
+       talloc_free(tmp_ctx);
+       return 0;
+}
+
+
+/*
+  get all tunables
+ */
+int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb, 
+                              struct timeval timeout, 
+                              uint32_t destnode,
+                              struct ctdb_tunable *tunables)
+{
+       TDB_DATA outdata;
+       int ret;
+       int32_t res;
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_GET_ALL_TUNABLES, 0, tdb_null, ctdb,
+                          &outdata, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for get all tunables failed\n"));
+               return -1;
+       }
+
+       if (outdata.dsize != sizeof(*tunables)) {
+               DEBUG(DEBUG_ERR,(__location__ " bad data size %u in ctdb_ctrl_get_all_tunables should be %u\n",
+                        (unsigned)outdata.dsize, (unsigned)sizeof(*tunables)));
+               return -1;              
+       }
+
+       *tunables = *(struct ctdb_tunable *)outdata.dptr;
+       talloc_free(outdata.dptr);
+       return 0;
+}
+
+/*
+  add a public address to a node
+ */
+int ctdb_ctrl_add_public_ip(struct ctdb_context *ctdb, 
+                     struct timeval timeout, 
+                     uint32_t destnode,
+                     struct ctdb_control_ip_iface *pub)
+{
+       TDB_DATA data;
+       int32_t res;
+       int ret;
+
+       data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
+       data.dptr  = (unsigned char *)pub;
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_ADD_PUBLIC_IP, 0, data, NULL,
+                          NULL, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for add_public_ip failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  delete a public address from a node
+ */
+int ctdb_ctrl_del_public_ip(struct ctdb_context *ctdb, 
+                     struct timeval timeout, 
+                     uint32_t destnode,
+                     struct ctdb_control_ip_iface *pub)
+{
+       TDB_DATA data;
+       int32_t res;
+       int ret;
+
+       data.dsize = offsetof(struct ctdb_control_ip_iface, iface) + pub->len;
+       data.dptr  = (unsigned char *)pub;
+
+       ret = ctdb_control(ctdb, destnode, 0, CTDB_CONTROL_DEL_PUBLIC_IP, 0, data, NULL,
+                          NULL, &res, &timeout, NULL);
+       if (ret != 0 || res != 0) {
+               DEBUG(DEBUG_ERR,(__location__ " ctdb_control for del_public_ip failed\n"));
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+  kill a tcp connection
+ */
+int ctdb_ctrl_killtcp(struct ctdb_context *ctdb, 
+                     struct ti