mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +03:00
Parallel database recovery fixes the samba/ctdb deadlock during recovery. Many times samba tries to grab multiple record locks in sequence. Consider a case when samba is already holding a record lock on a database and tries to get a record lock on second database. If the second record is not available on the local node, samba asks ctdb to migrate the record. If recovery occurs at this time (e.g. node becoming inactive), ctdb cannot freeze all the databases since samba is already holding a lock and waiting for the second lock. CTDB can process the second record request only after the recovery is complete, thus causing a deadlock. In parallel database recovery, each database is frozen and recovered independent from each other. So as soon as the second database is recovered, CTDB will resend all the pending migration requests and Samba can get the second lock. Once samba releases both the locks, ctdb can freeze the first database and recover it completing recovery process. Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net>
856 lines
33 KiB
Python
Executable File
856 lines
33 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
APPNAME = 'ctdb'
|
|
|
|
blddir = 'bin'
|
|
|
|
import sys, os
|
|
|
|
# find the buildtools directory
|
|
srcdir = '.'
|
|
while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5:
|
|
srcdir = srcdir + '/..'
|
|
sys.path.insert(0, srcdir + '/buildtools/wafsamba')
|
|
|
|
import wafsamba, samba_dist, Options, Logs, Utils
|
|
import samba_utils, samba_version
|
|
|
|
env = samba_utils.LOAD_ENVIRONMENT()
|
|
if os.path.isfile('./VERSION'):
|
|
vdir = '.'
|
|
elif os.path.isfile('../VERSION'):
|
|
vdir = '..'
|
|
else:
|
|
Logs.error("VERSION file not found")
|
|
|
|
version = samba_version.samba_version_file('%s/VERSION' % vdir, vdir, env)
|
|
VERSION = version.STRING.replace('-', '.')
|
|
|
|
default_prefix = Options.default_prefix = '/usr/local'
|
|
|
|
samba_dist.DIST_DIRS('''ctdb:. lib/replace:lib/replace lib/talloc:lib/talloc
|
|
lib/tevent:lib/tevent lib/tdb:lib/tdb
|
|
lib/socket_wrapper:lib/socket_wrapper
|
|
third_party/popt:third_party/popt
|
|
lib/util:lib/util lib/tdb_wrap:lib/tdb_wrap
|
|
lib/ccan:lib/ccan libcli/util:libcli/util
|
|
buildtools:buildtools third_party/waf:third_party/waf''')
|
|
|
|
manpages = [
|
|
'ctdb.1',
|
|
'ctdb.7',
|
|
'ctdbd.1',
|
|
'ctdbd.conf.5',
|
|
'ctdbd_wrapper.1',
|
|
'ctdb-statistics.7',
|
|
'ctdb-tunables.7',
|
|
'ltdbtool.1',
|
|
'onnode.1',
|
|
'ping_pong.1'
|
|
]
|
|
|
|
|
|
def set_options(opt):
|
|
opt.PRIVATE_EXTENSION_DEFAULT('ctdb')
|
|
|
|
opt.RECURSE('lib/replace')
|
|
|
|
opt.RECURSE('lib/util')
|
|
|
|
opt.RECURSE('lib/talloc')
|
|
opt.RECURSE('lib/tevent')
|
|
opt.RECURSE('lib/tdb')
|
|
|
|
opt.add_option('--enable-infiniband',
|
|
help=("Turn on infiniband support (default=no)"),
|
|
action="store_true", dest='ctdb_infiniband', default=False)
|
|
opt.add_option('--enable-pmda',
|
|
help=("Turn on PCP pmda support (default=no)"),
|
|
action="store_true", dest='ctdb_pmda', default=False)
|
|
|
|
opt.add_option('--with-logdir',
|
|
help=("Path to log directory"),
|
|
action="store", dest='ctdb_logdir', default=None)
|
|
opt.add_option('--with-socketpath',
|
|
help=("path to CTDB daemon socket"),
|
|
action="store", dest='ctdb_sockpath', default=None)
|
|
|
|
|
|
def configure(conf):
|
|
|
|
# CTDB relies on nested event loops
|
|
conf.env.TEVENT_DEPRECATED = 1
|
|
|
|
# No need to build python bindings for talloc/tevent/tdb
|
|
if conf.IN_LAUNCH_DIR():
|
|
conf.env.standalone_ctdb = True
|
|
Options.options.disable_python = True
|
|
|
|
conf.RECURSE('lib/replace')
|
|
|
|
if conf.env.standalone_ctdb:
|
|
conf.SAMBA_CHECK_PERL(mandatory=True)
|
|
|
|
conf.SAMBA_CHECK_PYTHON(mandatory=True, version=(2,5,0))
|
|
conf.SAMBA_CHECK_PYTHON_HEADERS(mandatory=True)
|
|
|
|
if conf.CHECK_FOR_THIRD_PARTY():
|
|
conf.RECURSE('third_party/popt')
|
|
else:
|
|
if not conf.CHECK_POPT():
|
|
raise Utils.WafError('popt development packages have not been found\nIf third_party is installed, check that it is in the proper place.')
|
|
else:
|
|
conf.define('USING_SYSTEM_POPT', 1)
|
|
|
|
conf.RECURSE('lib/util')
|
|
|
|
conf.RECURSE('lib/talloc')
|
|
conf.RECURSE('lib/tevent')
|
|
conf.RECURSE('lib/tdb')
|
|
if conf.env.standalone_ctdb or conf.CONFIG_GET('ENABLE_SELFTEST'):
|
|
conf.RECURSE('lib/socket_wrapper')
|
|
|
|
conf.CHECK_HEADERS('sched.h')
|
|
conf.CHECK_HEADERS('procinfo.h')
|
|
if sys.platform.startswith('aix') and not conf.CHECK_FUNCS('thread_setsched'):
|
|
Logs.error('Need thread_setsched() on AIX')
|
|
sys.exit(1)
|
|
elif not conf.CHECK_FUNCS('sched_setscheduler'):
|
|
Logs.error('Need sched_setscheduler()')
|
|
sys.exit(1)
|
|
conf.CHECK_FUNCS('mlockall')
|
|
|
|
if not conf.CHECK_VARIABLE('ETIME', headers='errno.h'):
|
|
conf.DEFINE('ETIME', 'ETIMEDOUT')
|
|
|
|
if sys.platform.startswith('linux'):
|
|
conf.SET_TARGET_TYPE('pcap', 'EMPTY')
|
|
else:
|
|
if not conf.CHECK_HEADERS('pcap.h'):
|
|
Logs.error('Need libpcap')
|
|
sys.exit(1)
|
|
if not conf.CHECK_FUNCS_IN('pcap_open_live', 'pcap', headers='pcap.h'):
|
|
Logs.error('Need libpcap')
|
|
sys.exit(1)
|
|
|
|
if not conf.CHECK_FUNCS_IN('backtrace backtrace_symbols', 'execinfo',
|
|
checklibc=True, headers='execinfo.h'):
|
|
Logs.error('backtrace support not available')
|
|
|
|
have_pmda = False
|
|
if Options.options.ctdb_pmda:
|
|
pmda_support = True
|
|
|
|
if not conf.CHECK_HEADERS('pcp/pmapi.h pcp/impl.h pcp/pmda.h',
|
|
together=True):
|
|
pmda_support = False
|
|
if not conf.CHECK_FUNCS_IN('pmProgname', 'pcp'):
|
|
pmda_support = False
|
|
if not conf.CHECK_FUNCS_IN('pmdaDaemon', 'pcp_pmda'):
|
|
pmda_support = False
|
|
if pmda_support:
|
|
have_pmda = True
|
|
else:
|
|
Logs.error("PMDA support not available")
|
|
if have_pmda:
|
|
Logs.info('Building with PMDA support')
|
|
conf.define('HAVE_PMDA', 1)
|
|
conf.env.CTDB_PMDADIR = os.path.join(conf.env.LOCALSTATEDIR,
|
|
'lib/pcp/pmdas/ctdb')
|
|
|
|
have_infiniband = False
|
|
if Options.options.ctdb_infiniband:
|
|
ib_support = True
|
|
|
|
if not conf.CHECK_HEADERS('infiniband/verbs.h rdma/rdma_cma.h'):
|
|
ib_support = False
|
|
if not conf.CHECK_FUNCS_IN('ibv_create_qp', 'ibverbs'):
|
|
ib_support = False
|
|
if not conf.CHECK_FUNCS_IN('rdma_connect', 'rdmacm'):
|
|
ib_support = False
|
|
if ib_support:
|
|
have_infiniband = True
|
|
else:
|
|
Logs.error("Infiniband support not available")
|
|
if have_infiniband:
|
|
Logs.info('Building with Infiniband support')
|
|
conf.define('HAVE_INFINIBAND', 1)
|
|
conf.define('USE_INFINIBAND', 1)
|
|
|
|
conf.env.CTDB_BINDIR = os.path.join(conf.env.EXEC_PREFIX, 'bin')
|
|
conf.env.CTDB_ETCDIR = os.path.join(conf.env.SYSCONFDIR, 'ctdb')
|
|
conf.env.CTDB_VARDIR = os.path.join(conf.env.LOCALSTATEDIR, 'lib/ctdb')
|
|
conf.env.CTDB_RUNDIR = os.path.join(conf.env.LOCALSTATEDIR, 'run/ctdb')
|
|
|
|
if Options.options.ctdb_logdir:
|
|
conf.env.CTDB_LOGDIR = Options.options.ctdb_logdir
|
|
else:
|
|
conf.env.CTDB_LOGDIR = os.path.join(conf.env.LOCALSTATEDIR, 'log')
|
|
|
|
if Options.options.ctdb_sockpath:
|
|
conf.env.CTDB_SOCKPATH = Options.options.ctdb_sockpath
|
|
else:
|
|
conf.env.CTDB_SOCKPATH = os.path.join(conf.env.CTDB_RUNDIR,
|
|
'ctdbd.socket')
|
|
|
|
conf.ADD_CFLAGS('''-DCTDB_HELPER_BINDIR=\"%s\"
|
|
-DLOGDIR=\"%s\"
|
|
-DSOCKPATH=\"%s\"
|
|
-DCTDB_ETCDIR=\"%s\"
|
|
-DCTDB_VARDIR=\"%s\"
|
|
-DCTDB_RUNDIR=\"%s\"''' % (
|
|
conf.env.CTDB_BINDIR,
|
|
conf.env.CTDB_LOGDIR,
|
|
conf.env.CTDB_SOCKPATH,
|
|
conf.env.CTDB_ETCDIR,
|
|
conf.env.CTDB_VARDIR,
|
|
conf.env.CTDB_RUNDIR))
|
|
|
|
conf.env.CTDB_TEST_DATADIR = os.path.join(conf.env.EXEC_PREFIX,
|
|
'share/ctdb-tests')
|
|
conf.env.CTDB_TEST_LIBDIR = os.path.join(conf.env.LIBDIR, 'ctdb-tests')
|
|
|
|
# Allow unified compilation and separate compilation of utilities
|
|
# to find includes
|
|
if not conf.env.standalone_ctdb:
|
|
conf.ADD_EXTRA_INCLUDES('#include/public #ctdb/include')
|
|
else:
|
|
if srcdir == '.':
|
|
# Building from tarball
|
|
conf.ADD_EXTRA_INCLUDES('#include')
|
|
conf.ADD_EXTRA_INCLUDES('#include/internal')
|
|
else:
|
|
# Building standalone CTDB from within Samba tree
|
|
conf.ADD_EXTRA_INCLUDES('#ctdb/include')
|
|
conf.ADD_EXTRA_INCLUDES('#ctdb/include/internal')
|
|
conf.ADD_EXTRA_INCLUDES('#ctdb')
|
|
conf.ADD_EXTRA_INCLUDES('#lib #lib/replace')
|
|
|
|
conf.DEFINE('HAVE_CONFIG_H', 1, add_to_cflags=True)
|
|
conf.DEFINE('SAMBA_UTIL_CORE_ONLY', 1, add_to_cflags=True)
|
|
conf.SAMBA_CONFIG_H()
|
|
|
|
|
|
def build(bld):
|
|
if bld.env.standalone_ctdb:
|
|
# enable building of public headers in the build tree
|
|
bld.env.build_public_headers = 'include/public'
|
|
|
|
version_h = samba_utils.os_path_relpath(os.path.join(Options.launch_dir,
|
|
"version.h"),
|
|
bld.curdir)
|
|
|
|
if bld.env.standalone_ctdb:
|
|
ctdb_mkversion = '../packaging/mkversion.sh'
|
|
t = bld.SAMBA_GENERATOR('ctdb-version-header',
|
|
target='include/ctdb_version.h',
|
|
rule='%s ${TGT} %s' % (ctdb_mkversion, VERSION),
|
|
dep_vars=['VERSION'])
|
|
t.env.VERSION = VERSION
|
|
|
|
t = bld.SAMBA_GENERATOR('ctdb-samba-version-header',
|
|
target=version_h,
|
|
rule='printf "#include \\"ctdb_version.h\\" \\n#define SAMBA_VERSION_STRING CTDB_VERSION_STRING\\n" > ${TGT}',
|
|
dep_vars=['VERSION'])
|
|
t.env.VERSION = VERSION
|
|
else:
|
|
t = bld.SAMBA_GENERATOR('ctdb-samba-version-header',
|
|
target='include/ctdb_version.h',
|
|
rule='printf "#include \\"%s\\" \\n#define CTDB_VERSION_STRING SAMBA_VERSION_STRING\\n" > ${TGT}' % version_h,
|
|
dep_vars=['VERSION'])
|
|
t.env.VERSION = VERSION
|
|
|
|
bld.env.PKGCONFIGDIR = '${LIBDIR}/pkgconfig'
|
|
|
|
bld.RECURSE('lib/replace')
|
|
if bld.CHECK_FOR_THIRD_PARTY():
|
|
bld.RECURSE('third_party/popt')
|
|
|
|
bld.RECURSE('lib/tdb_wrap')
|
|
bld.RECURSE('lib/util')
|
|
|
|
bld.RECURSE('lib/talloc')
|
|
bld.RECURSE('lib/tevent')
|
|
bld.RECURSE('lib/tdb')
|
|
if bld.env.standalone_ctdb or bld.CONFIG_GET('SOCKET_WRAPPER'):
|
|
bld.RECURSE('lib/socket_wrapper')
|
|
|
|
if bld.env.standalone_ctdb:
|
|
# In a combined build is implemented, CTDB will wanted to
|
|
# build against samba-util rather than samba-util-core.
|
|
# Similarly, other Samba subsystems expect samba-util. So,
|
|
# for a standalone build, just define a fake samba-util
|
|
# subsystem that pulls in samba-util-core.
|
|
bld.SAMBA_SUBSYSTEM('samba-util',
|
|
source='',
|
|
deps='samba-util-core')
|
|
|
|
bld.SAMBA_SUBSYSTEM('ctdb-tcp',
|
|
source=bld.SUBDIR('tcp',
|
|
'tcp_connect.c tcp_init.c tcp_io.c'),
|
|
includes='include include/internal',
|
|
deps='replace tdb talloc tevent')
|
|
|
|
ib_deps = ''
|
|
if bld.env.HAVE_INFINIBAND:
|
|
bld.SAMBA_SUBSYSTEM('ctdb-ib',
|
|
source=bld.SUBDIR('ib',
|
|
'''ibwrapper.c ibw_ctdb.c
|
|
ibw_ctdb_init.c'''),
|
|
includes='include include/internal',
|
|
deps='replace')
|
|
ib_deps = ' ctdb-ib rdmacm ibverbs'
|
|
|
|
if sys.platform.startswith('linux'):
|
|
CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_linux.c')
|
|
elif sys.platform.startswith('aix'):
|
|
CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_aix.c')
|
|
elif sys.platform.startswith('freebsd'):
|
|
CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_freebsd.c')
|
|
elif sys.platform == 'kfreebsd':
|
|
CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_kfreebsd.c')
|
|
elif sys.platform == 'gnu':
|
|
CTDB_SYSTEM_SRC = bld.SUBDIR('common', 'system_gnu.c')
|
|
else:
|
|
Logs.error("Platform %s not supported" % sys.platform)
|
|
|
|
bld.SAMBA_SUBSYSTEM('ctdb-system',
|
|
source='common/system_common.c ' + CTDB_SYSTEM_SRC,
|
|
includes='include include/internal',
|
|
deps='replace talloc tevent tdb pcap')
|
|
|
|
bld.SAMBA_SUBSYSTEM('ctdb-common',
|
|
source=bld.SUBDIR('common',
|
|
'''ctdb_io.c ctdb_util.c ctdb_ltdb.c
|
|
cmdline.c rb_tree.c
|
|
ctdb_fork.c'''),
|
|
includes='include include/internal common .',
|
|
deps='replace popt talloc tevent tdb popt ctdb-system')
|
|
|
|
bld.SAMBA_SUBSYSTEM('ctdb-common-util',
|
|
source=bld.SUBDIR('common',
|
|
'system_util.c ctdb_logging.c'),
|
|
includes='include include/internal',
|
|
deps='replace tevent tdb')
|
|
|
|
bld.SAMBA_SUBSYSTEM('ctdb-util',
|
|
source=bld.SUBDIR('common',
|
|
'''db_hash.c srvid.c reqid.c
|
|
pkt_read.c pkt_write.c comm.c
|
|
logging.c'''),
|
|
deps='replace talloc tevent tdb tevent-unix-util')
|
|
|
|
bld.SAMBA_SUBSYSTEM('ctdb-protocol',
|
|
source=bld.SUBDIR('protocol',
|
|
'''protocol_header.c protocol_packet.c
|
|
protocol_types.c protocol_call.c
|
|
protocol_message.c
|
|
protocol_control.c
|
|
protocol_client.c
|
|
protocol_util.c'''),
|
|
includes='include',
|
|
deps='replace talloc tdb')
|
|
|
|
bld.SAMBA_SUBSYSTEM('ctdb-client',
|
|
source=bld.SUBDIR('client', 'ctdb_client.c'),
|
|
includes='include include/internal',
|
|
deps='''replace popt talloc tevent tdb
|
|
samba-util tdb-wrap ctdb-util''')
|
|
|
|
bld.SAMBA_SUBSYSTEM('ctdb-client2',
|
|
source=bld.SUBDIR('client',
|
|
'''client_connect.c client_call.c
|
|
client_message.c client_control.c
|
|
client_message_sync.c
|
|
client_control_sync.c
|
|
client_db.c client_util.c
|
|
'''),
|
|
includes='include include/internal',
|
|
deps='replace talloc tevent tdb tdb-wrap')
|
|
|
|
bld.SAMBA_SUBSYSTEM('ctdb-server',
|
|
source='server/ctdbd.c ' +
|
|
bld.SUBDIR('server',
|
|
'''ctdb_daemon.c ctdb_recoverd.c
|
|
ctdb_recover.c ctdb_freeze.c
|
|
ctdb_tunables.c ctdb_monitor.c
|
|
ctdb_server.c ctdb_control.c
|
|
ctdb_call.c ctdb_ltdb_server.c
|
|
ctdb_traverse.c eventscript.c
|
|
ctdb_takeover.c ctdb_serverids.c
|
|
ctdb_persistent.c ctdb_keepalive.c
|
|
ctdb_logging.c
|
|
ctdb_logging_syslog.c
|
|
ctdb_logging_file.c
|
|
ctdb_uptime.c
|
|
ctdb_vacuum.c ctdb_banning.c
|
|
ctdb_statistics.c
|
|
ctdb_update_record.c
|
|
ctdb_lock.c'''),
|
|
includes='include include/internal',
|
|
deps='replace popt talloc tevent tdb talloc_report')
|
|
|
|
bld.SAMBA_BINARY('ctdbd',
|
|
source='',
|
|
deps='''ctdb-server ctdb-client ctdb-common
|
|
ctdb-common-util ctdb-tcp ctdb-util''' +
|
|
ib_deps,
|
|
install_path='${SBINDIR}',
|
|
manpages='ctdbd.1')
|
|
|
|
bld.SAMBA_BINARY('ctdb',
|
|
source='tools/ctdb.c tools/ctdb_vacuum.c',
|
|
deps='''ctdb-client ctdb-common ctdb-common-util
|
|
ctdb-util''',
|
|
includes='include include/internal',
|
|
install_path='${BINDIR}',
|
|
manpages='ctdb.1')
|
|
|
|
bld.SAMBA_BINARY('ltdbtool',
|
|
source='tools/ltdbtool.c',
|
|
includes='include',
|
|
deps='tdb',
|
|
install_path='${BINDIR}',
|
|
manpages='ltdbtool.1')
|
|
|
|
bld.SAMBA_BINARY('ctdb_lock_helper',
|
|
source='server/ctdb_lock_helper.c',
|
|
deps='samba-util ctdb-common-util talloc tdb',
|
|
includes='include include/internal',
|
|
install_path='${BINDIR}')
|
|
|
|
bld.SAMBA_BINARY('ctdb_event_helper',
|
|
source='server/ctdb_event_helper.c',
|
|
includes='include include/internal',
|
|
deps='samba-util ctdb-common-util replace tdb',
|
|
install_path='${BINDIR}')
|
|
|
|
bld.SAMBA_BINARY('ctdb_recovery_helper',
|
|
source='server/ctdb_recovery_helper.c',
|
|
deps='''ctdb-client2 ctdb-protocol ctdb-util
|
|
samba-util replace tdb''',
|
|
install_path='${BINDIR}')
|
|
|
|
bld.SAMBA_GENERATOR('ctdb-smnotify-h',
|
|
source='utils/smnotify/smnotify.x',
|
|
target='utils/smnotify/smnotify.h',
|
|
rule='rpcgen -h ${SRC} > ${TGT}')
|
|
|
|
xdr_buf_hack = 'sed -e "s@^\([ \t]*register int32_t \*buf\);@\\1 = buf;@"'
|
|
|
|
bld.SAMBA_GENERATOR('ctdb-smnotify-x',
|
|
source='utils/smnotify/smnotify.x',
|
|
target='utils/smnotify/gen_xdr.c',
|
|
rule='rpcgen -c ${SRC} | ' + xdr_buf_hack + ' > ${TGT}')
|
|
|
|
bld.SAMBA_GENERATOR('ctdb-smnotify-c',
|
|
source='utils/smnotify/smnotify.x',
|
|
target='utils/smnotify/gen_smnotify.c',
|
|
rule='rpcgen -l ${SRC} > ${TGT}')
|
|
|
|
bld.SAMBA_BINARY('smnotify',
|
|
source=bld.SUBDIR('utils/smnotify',
|
|
'smnotify.c gen_smnotify.c gen_xdr.c'),
|
|
deps='ctdb-smnotify-h ctdb-smnotify-c ctdb-smnotify-x popt',
|
|
includes='utils utils/smnotify',
|
|
install_path='${BINDIR}')
|
|
|
|
bld.SAMBA_BINARY('ping_pong',
|
|
source='utils/ping_pong/ping_pong.c',
|
|
deps='',
|
|
install_path='${BINDIR}',
|
|
manpages='ping_pong.1')
|
|
|
|
if bld.env.HAVE_PMDA:
|
|
bld.SAMBA_BINARY('pmdactdb',
|
|
source='utils/pmda/pmda_ctdb.c',
|
|
includes='include include/internal',
|
|
deps='''ctdb-client ctdb-common
|
|
ctdb-common-util pcp_pmda pcp''',
|
|
install_path='${CTDB_PMDADIR}')
|
|
bld.INSTALL_FILES('${CTDB_PMDADIR}', 'utils/pmda/Install',
|
|
destname='Install')
|
|
bld.INSTALL_FILES('${CTDB_PMDADIR}', 'utils/pmda/Remove',
|
|
destname='Remove')
|
|
bld.INSTALL_FILES('${CTDB_PMDADIR}', 'utils/pmda/pmns',
|
|
destname='pmns')
|
|
bld.INSTALL_FILES('${CTDB_PMDADIR}', 'utils/pmda/domain.h',
|
|
destname='domain.h')
|
|
bld.INSTALL_FILES('${CTDB_PMDADIR}', 'utils/pmda/help',
|
|
destname='help')
|
|
bld.INSTALL_FILES('${CTDB_PMDADIR}', 'utils/pmda/README',
|
|
destname='README')
|
|
|
|
sed_expr1 = 's|/usr/local/var/lib/ctdb|%s|g' % (bld.env.CTDB_VARDIR)
|
|
sed_expr2 = 's|/usr/local/etc/ctdb|%s|g' % (bld.env.CTDB_ETCDIR)
|
|
sed_expr3 = 's|/usr/local/var/log|%s|g' % (bld.env.CTDB_LOGDIR)
|
|
sed_expr4 = 's|/usr/local/var/run/ctdb|%s|g' % (bld.env.CTDB_RUNDIR)
|
|
sed_expr5 = 's|/usr/local/sbin|%s|g' % (bld.env.SBINDIR)
|
|
sed_cmdline = '-e "%s" -e "%s" -e "%s" -e "%s" -e "%s"' % \
|
|
(sed_expr1, sed_expr2, sed_expr3, sed_expr4, sed_expr5)
|
|
|
|
for f in manpages:
|
|
x = '%s.xml' % (f)
|
|
bld.SAMBA_GENERATOR(x,
|
|
source=os.path.join('doc', x),
|
|
target=x,
|
|
rule='sed %s ${SRC} > ${TGT}' % (sed_cmdline))
|
|
|
|
if 'XSLTPROC_MANPAGES' in bld.env and bld.env['XSLTPROC_MANPAGES']:
|
|
bld.MANPAGES('''onnode.1 ctdbd_wrapper.1 ctdbd.conf.5
|
|
ctdb.7 ctdb-statistics.7 ctdb-tunables.7''',
|
|
True)
|
|
else:
|
|
for m in manpages:
|
|
bld.SAMBA_GENERATOR(m,
|
|
source=os.path.join("doc", m),
|
|
target=m,
|
|
rule='sed %s ${SRC} > ${TGT}' % (sed_cmdline))
|
|
bld.INSTALL_FILES('${MANDIR}/man%s' % m[-1], m)
|
|
|
|
bld.SAMBA_GENERATOR('ctdb-onnode',
|
|
source='tools/onnode',
|
|
target='onnode',
|
|
rule='sed %s ${SRC} > ${TGT}' % (sed_cmdline))
|
|
bld.INSTALL_FILES('${BINDIR}', 'onnode',
|
|
destname='onnode', chmod=0755)
|
|
|
|
bld.SAMBA_GENERATOR('ctdb-diagnostics',
|
|
source='tools/ctdb_diagnostics',
|
|
target='ctdb_diagnostics',
|
|
rule='sed %s ${SRC} > ${TGT}' % (sed_cmdline))
|
|
bld.INSTALL_FILES('${BINDIR}', 'ctdb_diagnostics',
|
|
destname='ctdb_diagnostics', chmod=0755)
|
|
|
|
bld.SAMBA_GENERATOR('ctdbd-wrapper',
|
|
source='config/ctdbd_wrapper',
|
|
target='ctdbd_wrapper',
|
|
rule='sed %s ${SRC} > ${TGT}' % (sed_cmdline))
|
|
bld.INSTALL_FILES('${SBINDIR}', 'ctdbd_wrapper',
|
|
destname='ctdbd_wrapper', chmod=0755)
|
|
|
|
def SUBDIR_MODE_callback(arg, dirname, fnames):
|
|
for f in fnames:
|
|
fl = os.path.join(dirname, f)
|
|
if os.path.isdir(fl) or os.path.islink(fl):
|
|
continue
|
|
mode = os.lstat(fl).st_mode & 0777
|
|
if arg['trim_path']:
|
|
fl = samba_utils.os_path_relpath(fl, arg['trim_path'])
|
|
arg['file_list'].append([fl, mode])
|
|
|
|
def SUBDIR_MODE(path, trim_path=None):
|
|
pd = {'trim_path': trim_path, 'file_list': []}
|
|
os.path.walk(path, SUBDIR_MODE_callback, pd)
|
|
return pd['file_list']
|
|
|
|
etc_subdirs = [
|
|
'events.d',
|
|
'nfs-checks.d'
|
|
]
|
|
|
|
if bld.env.standalone_ctdb:
|
|
configdir = 'config'
|
|
else:
|
|
configdir = 'ctdb/config'
|
|
|
|
for t in etc_subdirs:
|
|
files = SUBDIR_MODE('%s/%s' % (configdir, t), trim_path=configdir)
|
|
for fmode in files:
|
|
bld.INSTALL_FILES(bld.env.CTDB_ETCDIR, 'config/%s' % fmode[0],
|
|
destname=fmode[0], chmod=fmode[1])
|
|
|
|
bld.SAMBA_GENERATOR('ctdb-functions',
|
|
source='config/functions',
|
|
target='functions',
|
|
rule='sed %s ${SRC} > ${TGT}' % (sed_cmdline))
|
|
bld.INSTALL_FILES(bld.env.CTDB_ETCDIR, 'functions', destname='functions')
|
|
|
|
etc_scripts = [
|
|
'ctdb-crash-cleanup.sh',
|
|
'debug-hung-script.sh',
|
|
'debug_locks.sh',
|
|
'gcore_trace.sh',
|
|
'nfs-linux-kernel-callout',
|
|
'notify.sh',
|
|
'statd-callout'
|
|
]
|
|
|
|
for t in etc_scripts:
|
|
bld.INSTALL_FILES(bld.env.CTDB_ETCDIR, 'config/%s' % t,
|
|
destname=t, chmod=0755)
|
|
|
|
bld.SAMBA_GENERATOR('ctdb-sudoers',
|
|
source='config/ctdb.sudoers',
|
|
target='ctdb.sudoers',
|
|
rule='sed %s ${SRC} > ${TGT}' % (sed_cmdline))
|
|
bld.INSTALL_FILES('${SYSCONFDIR}/sudoers.d', 'ctdb.sudoers',
|
|
destname='ctdb')
|
|
|
|
bld.INSTALL_FILES('${CTDB_ETCDIR}/notify.d', 'config/notify.d.README',
|
|
destname='README')
|
|
|
|
bld.install_dir(bld.env.CTDB_LOGDIR)
|
|
bld.install_dir(bld.env.CTDB_RUNDIR)
|
|
bld.install_dir(bld.env.CTDB_VARDIR)
|
|
|
|
sed_expr = 's/@PACKAGE_VERSION@/%s/g' % VERSION
|
|
t = bld.SAMBA_GENERATOR('ctdb-pc',
|
|
source='ctdb.pc.in',
|
|
target='ctdb.pc',
|
|
rule='sed -e "%s" ${SRC} > ${TGT}' % sed_expr,
|
|
dep_vars=['VERSION'])
|
|
t.env.VERSION = VERSION
|
|
bld.INSTALL_FILES('${LIBDIR}/pkgconfig', 'ctdb.pc')
|
|
|
|
# Unit tests
|
|
ctdb_unit_tests = [
|
|
'db_hash_test',
|
|
'srvid_test',
|
|
'pkt_read_test',
|
|
'pkt_write_test',
|
|
'comm_test',
|
|
'comm_server_test',
|
|
'comm_client_test',
|
|
'protocol_types_test',
|
|
'protocol_client_test',
|
|
]
|
|
|
|
for target in ctdb_unit_tests:
|
|
src = 'tests/src/' + target + '.c'
|
|
|
|
bld.SAMBA_BINARY(target,
|
|
source=src,
|
|
deps='talloc tevent tdb tevent-unix-util',
|
|
install_path='${CTDB_TEST_LIBDIR}')
|
|
|
|
bld.SAMBA_BINARY('reqid_test',
|
|
source='tests/src/reqid_test.c',
|
|
deps='samba-util',
|
|
install_path='${CTDB_TEST_LIBDIR}')
|
|
|
|
# Test binaries
|
|
ctdb_tests = [
|
|
'rb_test',
|
|
'ctdb_bench',
|
|
'ctdb_fetch',
|
|
'ctdb_fetch_one',
|
|
'ctdb_fetch_readonly_once',
|
|
'ctdb_fetch_readonly_loop',
|
|
'ctdb_trackingdb_test',
|
|
'ctdb_update_record',
|
|
'ctdb_update_record_persistent',
|
|
'ctdb_store',
|
|
'ctdb_traverse',
|
|
'ctdb_randrec',
|
|
'ctdb_persistent',
|
|
'ctdb_porting_tests',
|
|
'ctdb_transaction',
|
|
'ctdb_lock_tdb'
|
|
]
|
|
|
|
for target in ctdb_tests:
|
|
src = 'tests/src/' + target + '.c'
|
|
|
|
bld.SAMBA_BINARY(target,
|
|
source=src,
|
|
includes='include include/internal',
|
|
deps='''ctdb-client ctdb-common ctdb-common-util
|
|
ctdb-util''',
|
|
install_path='${CTDB_TEST_LIBDIR}')
|
|
|
|
bld.SAMBA_BINARY('ctdb_takeover_tests',
|
|
source='tests/src/ctdb_takeover_tests.c',
|
|
deps='''replace popt tdb tevent talloc ctdb-system
|
|
samba-util tdb-wrap talloc_report''' +
|
|
ib_deps,
|
|
includes='include include/internal',
|
|
install_path='${CTDB_TEST_LIBDIR}')
|
|
|
|
bld.SAMBA_BINARY('ctdb_functest',
|
|
source='tests/src/ctdb_functest.c',
|
|
deps='''replace tdb tevent talloc popt ctdb-system
|
|
samba-util tdb-wrap''',
|
|
includes='include include/internal',
|
|
install_path='${CTDB_TEST_LIBDIR}')
|
|
|
|
bld.SAMBA_BINARY('ctdb_stubtest',
|
|
source='tests/src/ctdb_test.c',
|
|
deps='''replace tdb tevent talloc popt ctdb-system
|
|
samba-util tdb-wrap''',
|
|
includes='include include/internal',
|
|
install_path='${CTDB_TEST_LIBDIR}')
|
|
|
|
if bld.env.HAVE_INFINIBAND:
|
|
bld.SAMBA_BINARY('ibwrapper_test',
|
|
source='ib/ibwrapper_test.c',
|
|
includes='include include/internal',
|
|
deps='replace talloc ctdb-client ctdb-common ' +
|
|
ib_deps,
|
|
install_path='${CTDB_TEST_LIBDIR}')
|
|
|
|
test_subdirs = [
|
|
'complex',
|
|
'cunit',
|
|
'events.d',
|
|
'eventscripts',
|
|
'onnode',
|
|
'simple',
|
|
'takeover',
|
|
'tool'
|
|
]
|
|
|
|
for t in test_subdirs:
|
|
files = SUBDIR_MODE('tests/%s' % t, trim_path='tests')
|
|
for fmode in files:
|
|
bld.INSTALL_FILES(bld.env.CTDB_TEST_DATADIR, 'tests/%s' % fmode[0],
|
|
destname=fmode[0], chmod=fmode[1])
|
|
|
|
# Install tests/scripts directory without test_wrap
|
|
test_scripts = [
|
|
'common.sh',
|
|
'integration.bash',
|
|
'unit.sh'
|
|
]
|
|
|
|
for t in test_scripts:
|
|
bld.INSTALL_FILES(bld.env.CTDB_TEST_DATADIR,
|
|
os.path.join('tests/scripts', t),
|
|
destname=os.path.join('scripts', t))
|
|
|
|
sed_expr = 's@^TEST_SCRIPTS_DIR=.*@&\\nexport TEST_BIN_DIR=\"%s\"@' % (
|
|
bld.env.CTDB_TEST_LIBDIR)
|
|
bld.SAMBA_GENERATOR('ctdb-test-wrap',
|
|
source='tests/scripts/test_wrap',
|
|
target='test_wrap',
|
|
rule='sed -e "%s" ${SRC} > ${TGT}' % sed_expr)
|
|
bld.INSTALL_FILES(bld.env.CTDB_TEST_DATADIR+"/scripts", 'test_wrap',
|
|
destname='test_wrap', chmod=0755)
|
|
|
|
sed_expr1 = 's@^test_dir=.*@test_dir=%s\\nexport TEST_BIN_DIR=\"%s\"@' % (
|
|
bld.env.CTDB_TEST_DATADIR, bld.env.CTDB_TEST_LIBDIR)
|
|
sed_expr2 = 's@^\(export CTDB_TESTS_ARE_INSTALLED\)=false@\\1=true@'
|
|
bld.SAMBA_GENERATOR('ctdb-test-runner',
|
|
source='tests/run_tests.sh',
|
|
target='ctdb_run_tests.sh',
|
|
rule='sed -e "%s" -e "%s" ${SRC} > ${TGT}' % (
|
|
sed_expr1, sed_expr2))
|
|
bld.INSTALL_FILES('${BINDIR}', 'ctdb_run_tests.sh',
|
|
destname='ctdb_run_tests', chmod=0755)
|
|
bld.symlink_as(os.path.join(bld.env.BINDIR, 'ctdb_run_cluster_tests'),
|
|
'ctdb_run_tests')
|
|
|
|
test_eventscript_links = [
|
|
'events.d',
|
|
'functions',
|
|
'nfs-checks.d',
|
|
'nfs-linux-kernel-callout',
|
|
'statd-callout'
|
|
]
|
|
|
|
test_link_dir = os.path.join(bld.env.CTDB_TEST_DATADIR,
|
|
'eventscripts/etc-ctdb')
|
|
for t in test_eventscript_links:
|
|
bld.symlink_as(os.path.join(test_link_dir, t),
|
|
os.path.join(bld.env.CTDB_ETCDIR, t))
|
|
|
|
# Tests that use onnode need to overwrite link to in-tree
|
|
# functions file when installed
|
|
bld.symlink_as(os.path.join(bld.env.CTDB_TEST_DATADIR, 'onnode/functions'),
|
|
os.path.join(bld.env.CTDB_ETCDIR, 'functions'))
|
|
bld.symlink_as(os.path.join(bld.env.CTDB_TEST_DATADIR, 'simple/functions'),
|
|
os.path.join(bld.env.CTDB_ETCDIR, 'functions'))
|
|
|
|
# Need a link to nodes file because $CTDB_BASE is overridden
|
|
bld.symlink_as(os.path.join(bld.env.CTDB_TEST_DATADIR, 'simple/nodes'),
|
|
os.path.join(bld.env.CTDB_ETCDIR, 'nodes'))
|
|
|
|
|
|
def testonly(ctx):
|
|
cmd = 'tests/run_tests.sh -V tests/var'
|
|
ret = samba_utils.RUN_COMMAND(cmd)
|
|
if ret != 0:
|
|
print('tests exited with exit status %d' % ret)
|
|
sys.exit(ret)
|
|
|
|
|
|
def test(ctx):
|
|
import Scripting
|
|
Scripting.commands.append('build')
|
|
Scripting.commands.append('testonly')
|
|
|
|
|
|
def autotest(ctx):
|
|
ld = 'LD_PRELOAD=%s/bin/shared/libsocket-wrapper.so' % os.getcwd()
|
|
cmd = '%s tests/run_tests.sh -e -S -C' % ld
|
|
ret = samba_utils.RUN_COMMAND(cmd)
|
|
if ret != 0:
|
|
print('autotest exited with exit status %d' % ret)
|
|
sys.exit(ret)
|
|
|
|
|
|
def show_version(ctx):
|
|
print VERSION
|
|
|
|
|
|
def dist():
|
|
samba_dist.DIST_FILES('VERSION:VERSION', extend=True)
|
|
|
|
t = 'include/ctdb_version.h'
|
|
cmd = 'packaging/mkversion.sh %s %s' % (t, VERSION)
|
|
ret = samba_utils.RUN_COMMAND(cmd)
|
|
if ret != 0:
|
|
print('Command "%s" failed with exit status %d' % (cmd, ret))
|
|
sys.exit(ret)
|
|
samba_dist.DIST_FILES('ctdb/%s:%s' % (t, t), extend=True)
|
|
|
|
t = 'ctdb.spec'
|
|
sed_expr1 = 's/@VERSION@/%s/g' % VERSION
|
|
sed_expr2 = 's/@RELEASE@/%s/g' % '1'
|
|
cmd = 'sed -e "%s" -e "%s" packaging/RPM/ctdb.spec.in > %s' % (
|
|
sed_expr1, sed_expr2, t)
|
|
ret = samba_utils.RUN_COMMAND(cmd)
|
|
if ret != 0:
|
|
print('Command "%s" failed with exit status %d' % (cmd, ret))
|
|
sys.exit(ret)
|
|
samba_dist.DIST_FILES('ctdb/%s:%s' % (t, t), extend=True)
|
|
|
|
cmd = 'make -C doc'
|
|
ret = samba_utils.RUN_COMMAND(cmd)
|
|
if ret != 0:
|
|
print('Command "%s" failed with exit status %d' % (cmd, ret))
|
|
sys.exit(ret)
|
|
for t in manpages:
|
|
samba_dist.DIST_FILES('ctdb/doc/%s:doc/%s' % (t, t), extend=True)
|
|
samba_dist.DIST_FILES('ctdb/doc/%s.html:doc/%s.html' % (t, t),
|
|
extend=True)
|
|
|
|
samba_dist.dist()
|
|
|
|
|
|
def rpmonly(ctx):
|
|
opts = os.getenv('RPM_OPTIONS') or ''
|
|
cmd = 'rpmbuild -ta --clean --rmsource %s ctdb-%s.tar.gz' % (opts, VERSION)
|
|
ret = samba_utils.RUN_COMMAND(cmd)
|
|
if ret != 0:
|
|
print('rpmbuild exited with exit status %d' % ret)
|
|
sys.exit(ret)
|
|
|
|
|
|
def rpm(ctx):
|
|
import Scripting
|
|
Scripting.commands.append('dist')
|
|
Scripting.commands.append('rpmonly')
|
|
|
|
|
|
def ctags(ctx):
|
|
"build 'tags' file using ctags"
|
|
import Utils
|
|
source_root = os.path.dirname(Utils.g_module.root_path)
|
|
cmd = 'ctags $(find %s -name "*.[ch]")' % source_root
|
|
print("Running: %s" % cmd)
|
|
ret = samba_utils.RUN_COMMAND(cmd)
|
|
if ret != 0:
|
|
print('ctags failed with exit status %d' % ret)
|
|
sys.exit(ret)
|