iprop: Support hierarchical iprop

This commit is contained in:
Nicolas Williams
2020-09-17 23:40:12 -05:00
parent c12ca129b6
commit 0e09fa7fde
9 changed files with 283 additions and 24 deletions

View File

@@ -139,6 +139,12 @@ There is a keep-alive feature logged in the master's
file (e.g.\&
.Pa /var/heimdal/slave-stats ) .
.Pp
Note that hierarchical replication is supported by running
an
.Nm ipropd-master
on the same KDC as an
.Nm ipropd-slave .
.Pp
Supported options for
.Nm ipropd-master :
.Bl -tag -width Ds

View File

@@ -47,6 +47,7 @@ static int time_before_missing;
static int time_before_gone;
const char *master_hostname;
const char *pidfile_basename;
static krb5_socket_t
make_signal_socket (krb5_context context)
@@ -937,9 +938,13 @@ get_first(kadm5_server_context *server_context, int log_fd,
ret = kadm5_log_get_version_fd(server_context, log_fd, LOG_VERSION_FIRST,
initial_verp, initial_timep);
if (ret == HEIM_ERR_EOF)
ret = kadm5_log_get_version_fd(server_context, log_fd,
LOG_VERSION_UBER, initial_verp,
initial_timep);
if (ret != 0) {
flock(log_fd, LOCK_UN);
krb5_warnx(context, "could not read initial log entry");
krb5_warn(context, ret, "could not read initial log entry");
return -1;
}
@@ -1529,8 +1534,10 @@ static struct getargs args[] = {
"port ipropd will listen to", "port"},
{ "detach", 0, arg_flag, &detach_from_console,
"detach from console", NULL },
{ "daemon-child", 0 , arg_integer, &daemon_child,
{ "daemon-child", 0, arg_integer, &daemon_child,
"private argument, do not use", NULL },
{ "pidfile-basename", 0, arg_string, &pidfile_basename,
"basename of pidfile; private argument for testing", "NAME" },
{ "hostname", 0, arg_string, rk_UNCONST(&master_hostname),
"hostname of master (if not same as hostname)", "hostname" },
{ "verbose", 0, arg_flag, &verbose, NULL, NULL },
@@ -1573,7 +1580,7 @@ main(int argc, char **argv)
if (detach_from_console && daemon_child == -1)
daemon_child = roken_detach_prep(argc, argv, "--daemon-child");
rk_pidfile(NULL);
rk_pidfile(pidfile_basename);
ret = krb5_init_context(&context);
if (ret)

View File

@@ -43,7 +43,8 @@ static krb5_log_facility *log_facility;
static char five_min[] = "5 min";
static char *server_time_lost = five_min;
static int time_before_lost;
const char *slave_str = NULL;
static const char *slave_str;
static const char *pidfile_basename;
static int
connect_to_master (krb5_context context, const char *master,
@@ -305,9 +306,9 @@ append_to_log_file(krb5_context context,
}
static int
receive_loop (krb5_context context,
krb5_storage *sp,
kadm5_server_context *server_context)
receive_loop(krb5_context context,
krb5_storage *sp,
kadm5_server_context *server_context)
{
int ret;
off_t left, right, off;
@@ -316,6 +317,11 @@ receive_loop (krb5_context context,
if (verbose)
krb5_warnx(context, "receiving diffs");
ret = kadm5_log_exclusivelock(server_context);
if (ret)
krb5_err(context, IPROPD_RESTART, ret,
"Failed to lock iprop log for writes");
/*
* Seek to the first entry in the message from the master that is
* past the current version of the local database.
@@ -433,6 +439,12 @@ receive(krb5_context context,
if (ret)
krb5_err(context, IPROPD_RESTART_SLOW, ret, "db->close");
(void) kadm5_log_sharedlock(server_context);
if (verbose)
krb5_warnx(context, "downgraded iprop log lock to shared");
kadm5_log_signal_master(server_context);
if (verbose)
krb5_warnx(context, "signaled master for hierarchical iprop");
return ret2;
}
@@ -481,6 +493,9 @@ reinit_log(krb5_context context,
ret = kadm5_log_reinit(server_context, vno);
if (ret)
krb5_err(context, IPROPD_RESTART_SLOW, ret, "kadm5_log_reinit");
(void) kadm5_log_sharedlock(server_context);
if (verbose)
krb5_warnx(context, "downgraded iprop log lock to shared");
}
@@ -500,6 +515,10 @@ receive_everything(krb5_context context, int fd,
krb5_warnx(context, "receive complete database");
ret = kadm5_log_exclusivelock(server_context);
if (ret)
krb5_err(context, IPROPD_RESTART, ret,
"Failed to lock iprop log for writes");
ret = asprintf(&dbname, "%s-NEW", server_context->db->hdb_name);
if (ret == -1)
krb5_err(context, IPROPD_RESTART, ENOMEM, "asprintf");
@@ -673,8 +692,10 @@ static struct getargs args[] = {
"port ipropd-slave will connect to", "port"},
{ "detach", 0, arg_flag, &detach_from_console,
"detach from console", NULL },
{ "daemon-child", 0 , arg_integer, &daemon_child,
{ "daemon-child", 0, arg_integer, &daemon_child,
"private argument, do not use", NULL },
{ "pidfile-basename", 0, arg_string, &pidfile_basename,
"basename of pidfile; private argument for testing", "NAME" },
{ "hostname", 0, arg_string, rk_UNCONST(&slave_str),
"hostname of slave (if not same as hostname)", "hostname" },
{ "verbose", 0, arg_flag, &verbose, NULL, NULL },
@@ -729,7 +750,7 @@ main(int argc, char **argv)
if (detach_from_console && daemon_child == -1)
daemon_child = roken_detach_prep(argc, argv, "--daemon-child");
rk_pidfile(NULL);
rk_pidfile(pidfile_basename);
ret = krb5_init_context(&context);
if (ret)
@@ -804,13 +825,16 @@ main(int argc, char **argv)
if (ret)
krb5_err (context, 1, ret, "db->open");
ret = kadm5_log_init (server_context);
ret = kadm5_log_init(server_context);
if (ret)
krb5_err (context, 1, ret, "kadm5_log_init");
krb5_err(context, 1, ret, "kadm5_log_init");
(void) kadm5_log_sharedlock(server_context);
if (verbose)
krb5_warnx(context, "downgraded iprop log lock to shared");
ret = server_context->db->hdb_close (context, server_context->db);
ret = server_context->db->hdb_close(context, server_context->db);
if (ret)
krb5_err (context, 1, ret, "db->close");
krb5_err(context, 1, ret, "db->close");
get_creds(context, keytab_str, &ccache, master);
@@ -977,18 +1001,30 @@ main(int argc, char **argv)
continue;
}
/*
* It's unclear why we open th HDB and call kadm5_log_init() here.
*
* We don't need it to process the log entries we receive in the
* FOR_YOU case: we already call kadm5_log_recover() in receive() /
* receive_loop(). Maybe it's just just in case, though at the
* cost of synchronization with ipropd-master if we're running one
* for hierarchical iprop.
*/
ret = server_context->db->hdb_open(context,
server_context->db,
O_RDWR | O_CREAT, 0600);
if (ret)
krb5_err (context, 1, ret, "db->open while handling a "
"message from the master");
ret = kadm5_log_init(server_context);
if (ret) {
krb5_err(context, IPROPD_RESTART, ret, "kadm5_log_init while "
"handling a message from the master");
}
(void) kadm5_log_sharedlock(server_context);
if (verbose)
krb5_warnx(context, "downgraded iprop log lock to shared");
ret = server_context->db->hdb_close (context, server_context->db);
if (ret)
krb5_err (context, 1, ret, "db->close while handling a "
@@ -1019,6 +1055,7 @@ main(int argc, char **argv)
krb5_warnx(context, "master sent us a full dump");
ret = receive_everything(context, master_fd, server_context,
auth_context);
(void) kadm5_log_sharedlock(server_context);
if (ret == 0) {
ret = ihave(context, auth_context, master_fd,
server_context->log_context.version);
@@ -1027,6 +1064,11 @@ main(int argc, char **argv)
connected = FALSE;
else
is_up_to_date(context, status_file, server_context);
if (verbose)
krb5_warnx(context, "downgraded iprop log lock to shared");
kadm5_log_signal_master(server_context);
if (verbose)
krb5_warnx(context, "signaled master for hierarchical iprop");
break;
case ARE_YOU_THERE :
if (verbose)

View File

@@ -61,7 +61,9 @@ EXPORTS
kadm5_s_init_with_creds
kadm5_s_chpass_principal_cond
kadm5_s_create_principal_with_key
kadm5_log_exclusivelock
kadm5_log_set_version
kadm5_log_sharedlock
kadm5_log_signal_master
;! kadm5_log_signal_socket
kadm5_log_signal_socket_info ;!

View File

@@ -682,6 +682,40 @@ kadm5_log_init(kadm5_server_context *server_context)
return log_init(server_context, LOCK_EX);
}
/* Upgrade log lock to exclusive */
kadm5_ret_t
kadm5_log_exclusivelock(kadm5_server_context *server_context)
{
kadm5_log_context *log_context = &server_context->log_context;
if (log_context->lock_mode == LOCK_EX)
return 0;
if (log_context->log_fd == -1)
return EINVAL;
if (flock(log_context->log_fd, LOCK_EX) < 0)
return errno;
log_context->read_only = 0;
log_context->lock_mode = LOCK_EX;
return 0;
}
/* Downgrade log lock to shared */
kadm5_ret_t
kadm5_log_sharedlock(kadm5_server_context *server_context)
{
kadm5_log_context *log_context = &server_context->log_context;
if (log_context->lock_mode == LOCK_SH)
return 0;
if (log_context->log_fd == -1)
return EINVAL;
if (flock(log_context->log_fd, LOCK_SH) < 0)
return errno;
log_context->read_only = 1;
log_context->lock_mode = LOCK_SH;
return 0;
}
/* Open the log with an exclusive non-blocking lock */
kadm5_ret_t
kadm5_log_init_nb(kadm5_server_context *server_context)

View File

@@ -64,7 +64,9 @@ HEIMDAL_KAMD5_SERVER_1.0 {
kadm5_s_init_with_creds;
kadm5_s_chpass_principal_cond;
kadm5_s_create_principal_with_key;
kadm5_log_exclusivelock;
kadm5_log_set_version;
kadm5_log_sharedlock;
kadm5_log_signal_master;
kadm5_log_signal_socket;
kadm5_log_previous;

View File

@@ -15,6 +15,7 @@ noinst_DATA = \
krb5-bx509.conf \
krb5-httpkadmind.conf \
krb5-pkinit-win.conf \
krb5-master2.conf \
krb5-slave2.conf \
krb5-slave.conf
@@ -51,6 +52,7 @@ pwport = 49191
restport = 49192
restport2 = 49193
ipropport = 49194
ipropport2 = 49195
if HAVE_DLOPEN
do_dlopen = -e 's,[@]DLOPEN[@],true,g'
@@ -70,6 +72,7 @@ do_subst = $(heim_verbose)sed $(do_dlopen) \
-e 's,[@]restport2[@],$(restport2),g' \
-e 's,[@]pwport[@],$(pwport),g' \
-e 's,[@]ipropport[@],$(ipropport),g' \
-e 's,[@]ipropport2[@],$(ipropport2),g' \
-e 's,[@]objdir[@],$(top_builddir)/tests/kdc,g' \
-e 's,[@]top_builddir[@],$(top_builddir),g' \
-e 's,[@]db_type[@],$(db_type),g' \
@@ -165,7 +168,7 @@ check-httpkadmind: check-httpkadmind.in Makefile krb5-httpkadmind.conf
$(chmod) +x check-httpkadmind.tmp && \
mv check-httpkadmind.tmp check-httpkadmind
check-iprop: check-iprop.in Makefile krb5.conf krb5-slave.conf krb5-slave2.conf
check-iprop: check-iprop.in Makefile krb5.conf krb5-master2.conf krb5-slave.conf krb5-slave2.conf
$(do_subst) < $(srcdir)/check-iprop.in > check-iprop.tmp && \
$(chmod) +x check-iprop.tmp && \
mv check-iprop.tmp check-iprop
@@ -193,6 +196,9 @@ krb5.conf: krb5.conf.in Makefile
$(do_subst) \
-e 's,[@]WEAK[@],false,g' \
-e 's,[@]dk[@],,g' \
-e 's,[@]messages[@],messages,g' \
-e 's,[@]ipropstats[@],iprop-stats,g' \
-e 's,[@]signalsocket[@],signal,g' \
-e 's,[@]kdc[@],,g' < $(srcdir)/krb5.conf.in > krb5.conf.tmp && \
mv krb5.conf.tmp krb5.conf
@@ -236,6 +242,9 @@ krb5-weak.conf: krb5.conf.in Makefile
$(do_subst) \
-e 's,[@]WEAK[@],true,g' \
-e 's,[@]dk[@],default_keys = aes256-cts-hmac-sha1-96:pw-salt arcfour-hmac-md5:pw-salt des3-cbc-sha1:pw-salt des:pw-salt,g' \
-e 's,[@]messages[@],messages,g' \
-e 's,[@]signalsocket[@],signal,g' \
-e 's,[@]ipropstats[@],iprop-stats,g' \
-e 's,[@]kdc[@],,g' < $(srcdir)/krb5.conf.in > krb5-weak.conf.tmp && \
mv krb5-weak.conf.tmp krb5-weak.conf
@@ -243,13 +252,29 @@ krb5-slave.conf: krb5.conf.in Makefile
$(do_subst) \
-e 's,[@]WEAK[@],true,g' \
-e 's,[@]dk[@],,g' \
-e 's,[@]messages[@],messages,g' \
-e 's,[@]signalsocket[@],signal2,g' \
-e 's,[@]ipropstats[@],iprop-stats,g' \
-e 's,[@]kdc[@],.slave,g' < $(srcdir)/krb5.conf.in > krb5-slave.conf.tmp && \
mv krb5-slave.conf.tmp krb5-slave.conf
krb5-master2.conf: krb5.conf.in Makefile
$(do_subst) \
-e 's,[@]WEAK[@],true,g' \
-e 's,[@]dk[@],,g' \
-e 's,[@]messages[@],messages2,g' \
-e 's,[@]signalsocket[@],signal2,g' \
-e 's,[@]ipropstats[@],iprop-stats2,g' \
-e 's,[@]kdc[@],.slave,g' < $(srcdir)/krb5.conf.in > krb5-master2.conf.tmp && \
mv krb5-master2.conf.tmp krb5-master2.conf
krb5-slave2.conf: krb5.conf.in Makefile
$(do_subst) \
-e 's,[@]WEAK[@],true,g' \
-e 's,[@]dk[@],,g' \
-e 's,[@]messages[@],messages2,g' \
-e 's,[@]signalsocket[@],signal3,g' \
-e 's,[@]ipropstats[@],iprop-stats2,g' \
-e 's,[@]kdc[@],.slave2,g' < $(srcdir)/krb5.conf.in > krb5-slave2.conf.tmp && \
mv krb5-slave2.conf.tmp krb5-slave2.conf
@@ -295,6 +320,7 @@ CLEANFILES= \
foopassword \
foopassword.rkpty \
iprop-stats \
iprop-stats2 \
iprop.keytab \
ipropd.dumpfile \
kdc-tester4.json \
@@ -333,6 +359,8 @@ CLEANFILES= \
sdigest-reply \
server.keytab \
signal \
signal2 \
signal3 \
tempfile \
test-rc-file.rc \
ukt \

View File

@@ -50,6 +50,7 @@ R=TEST.H5L.SE
port=@port@
ipropport=@ipropport@
ipropport2=@ipropport2@
cache="FILE:${objdir}/cache.krb5"
keytabfile=${objdir}/iprop.keytab
@@ -59,6 +60,60 @@ kdc="${kdc} --addresses=localhost -P $port"
kadmin="${kadmin} -r $R"
kinit="${kinit} -c $cache ${afs_no_afslog}"
# We'll test iprop, and in particular, hierarchical iprop. This means we'll
# have a setup like:
#
# ipropd-master -> ipropd-slave -> 2nd ipropd-master -> 2nd ipropd-slave
# Waiting for incremental propagation is inherently difficult because we don't
# have a way for ipropd-slave to signal this script that it has received
# updates. Well, it does have a way to signal a possible ipropd-master for
# hierarchical iprop, but we don't have a way to get that signal here.
#
# FIXME: Add a private interface for async waiting for iprop.
#
# What we do is we have a set of utility functions:
#
# - get_iprop_ver [N] -> checks that N (default to 1) ops have made it over
# - get_iprop_ver2 [N] -> same, but for second ipropd-slave instance
#
# - wait_for -> repeat a command until it succeeds or too many tries
# - wait_for_slave [N] -> wait for N ops to make it over (calls get_iprop_ver)
# - wait_for_slave2 [N] -> same, but for second ipropd-slave instance
#
# In particular the wait_for* functions busy-wait for a max amount of time,
# with sleeps in between.
#
# NOTE: get_iprop_ver and get_iprop_ver2 keep hidden state.
#
# When first called, get_iprop_ver / get_iprop_ver2 save the current version
# numbers. Thereafter they check that N ops have been received.
#
# It is critical to account for every incremental op via get_iprop_ver /
# get_iprop_ver2, or wait_for_slave / wait_for_slave2, otherwise this test will
# be racy and will have spurious failures!
#
# The pattern should be something like this:
#
# echo "Add host"
# ${kadmin} -l add --random-key --use-defaults host/foo@${R} || exit 1
# wait_for_slave
# ^^^^^^^^^^^^^^
# waits for 1 operation
#
# or
#
# echo "Rollover host keys"
# ${kadmin} -l cpw -r --keepold host/foo@${R} || exit 1
# ${kadmin} -l cpw -r --keepold host/foo@${R} || exit 1
# ${kadmin} -l cpw -r --keepold host/foo@${R} || exit 1
# wait_for_slave 3
# ^^^^^^^^^^^^^^^^
# waits for the three operations
#
# So though all operations must be accounted for, they need not be accounted
# one by one.
slave_ver_from_master_old=
slave_ver_from_master_new=
slave_ver_old=
@@ -84,6 +139,31 @@ get_iprop_ver () {
return 0
}
slave_ver_from_master_old2=
slave_ver_from_master_new2=
slave_ver_old2=
slave_ver_new2=
get_iprop_ver2 () {
min_change=${1:-1}
slave_ver_from_master_new2=`grep '^iprop/' iprop-stats2 | head -1 | awk '{print $3}'`
slave_ver_new2=`grep 'up-to-date with version:' iprop-slave-status2 | awk '{print $4}'`
if [ -z "$slave_ver_from_master_new2" -o -z "$slave_ver_new2" ]; then
return 1
fi
if [ x"$slave_ver_from_master_new2" != x"$slave_ver_new2" ]; then
return 1
fi
if [ x"$slave_ver_from_master_old2" != x ]; then
change=`expr "$slave_ver_from_master_new2" - "$slave_ver_from_master_old2"`
if [ "$change" -lt "$min_change" ]; then
return 1
fi
fi
slave_ver_from_master_old2=$slave_ver_from_master_new2
slave_ver_old2=$slave_ver_new2
return 0
}
waitsec=65
sleeptime=2
wait_for () {
@@ -119,6 +199,10 @@ wait_for_slave () {
wait_for "iprop versions to change and/or slave to catch up" get_iprop_ver "$@"
}
wait_for_slave2 () {
wait_for "iprop versions to change and/or second slave to catch up" get_iprop_ver2 "$@"
}
wait_for_master_down () {
wait_for "master to exit" check_pidfile_is_dead ipropd-master
}
@@ -135,9 +219,10 @@ rm -f current-db*
rm -f current*.log
rm -f out-*
rm -f mkey.file*
rm -f messages.log
rm -f messages.log messages.log
> messages.log
> messages.log2
echo Creating database
${kadmin} -l \
@@ -194,8 +279,11 @@ ipdm=
kdcpid=
> iprop-stats
rm -f iprop-slave-status
> iprop-stats2
rm -f iprop-slave-status iprop-slave-status2
ipropd_slave2=$ipropd_slave
ipropd_master2=$ipropd_master
ipropd_slave="${ipropd_slave} --status-file=iprop-slave-status --port=$ipropport"
ipropd_slave="${ipropd_slave} --hostname=slave.test.h5l.se -k ${keytab}"
ipropd_slave="${ipropd_slave} --detach localhost"
@@ -203,7 +291,27 @@ ipropd_master="${ipropd_master} --hostname=localhost -k ${keytab}"
ipropd_master="${ipropd_master} --port=$ipropport"
ipropd_master="${ipropd_master} --database=${objdir}/current-db --detach"
trap "echo 'killing ipropd s + m + kdc'; kill -9 \${ipdm} \${ipds} \${kdcpid} >/dev/null 2>/dev/null; tail messages.log ; tail iprop-stats; exit 1;" EXIT
ipropd_slave2="${ipropd_slave2} --status-file=iprop-slave-status2 --port=$ipropport2"
ipropd_slave2="${ipropd_slave2} --hostname=slave.test.h5l.se -k ${keytab}"
ipropd_slave2="${ipropd_slave2} --pidfile-basename=ipropd-slave2"
ipropd_slave2="${ipropd_slave2} --detach localhost"
ipropd_master2="${ipropd_master2} --hostname=localhost -k ${keytab}"
ipropd_master2="${ipropd_master2} --port=$ipropport2"
ipropd_master2="${ipropd_master2} --pidfile-basename=ipropd-master2"
ipropd_master2="${ipropd_master2} --database=${objdir}/current-db.slave --detach"
cleanup() {
echo 'killing ipropd s + m + kdc'
test -n "$ipdm" && kill -9 $ipdm >/dev/null 2>/dev/null
test -n "$ipdm2" && kill -9 $ipdm2 >/dev/null 2>/dev/null
test -n "$ipds" && kill -9 $ipds >/dev/null 2>/dev/null
test -n "$ipds2" && kill -9 $ipds2 >/dev/null 2>/dev/null
test -n "$kdcpid" && kill -9 $kdcpid >/dev/null 2>/dev/null
tail messages.log
tail iprop-stats
exit 1
}
trap cleanup EXIT
echo Starting kdc ; > messages.log
${kdc} --detach --testing || { echo "kdc failed to start"; exit 1; }
@@ -226,6 +334,22 @@ echo "checking slave is up"
${EGREP} 'iprop/slave.test.h5l.se@TEST.H5L.SE.*Up' iprop-stats >/dev/null || exit 1
${EGREP} 'up-to-date with version' iprop-slave-status >/dev/null || { echo "slave to up to date" ; cat iprop-slave-status ; exit 1; }
# Also setup a second master on the slave, then a second slave to pull from the
# second master.
echo "starting master2" ; > messages.log
env ${HEIM_MALLOC_DEBUG} \
KRB5_CONFIG="${objdir}/krb5-master2.conf" \
${ipropd_master2} || { echo "second ipropd-master failed to start"; exit 1; }
ipdm2=`getpid ipropd-master2`
echo "starting slave2" ; > messages.log
env ${HEIM_MALLOC_DEBUG} \
KRB5_CONFIG="${objdir}/krb5-slave2.conf" \
${ipropd_slave2} || { echo "ipropd-slave failed to start"; exit 1; }
ipds2=`getpid ipropd-slave2`
sh ${wait_kdc} ipropd-slave messages2.log 'slave status change: up-to-date' || exit 1
wait_for "Slave sees new host" get_iprop_ver2 0 || exit 1
# ----------------- checking: pushing lives changes
slave_get() { KRB5_CONFIG="${objdir}/krb5-slave.conf" ${kadmin} -l get "$@"; }
@@ -242,6 +366,7 @@ slave_check_exists() {
echo "Add host"
${kadmin} -l add --random-key --use-defaults host/foo@${R} || exit 1
wait_for_slave
wait_for "Slave sees new host" slave_check_exists "host/foo@${R}"
echo "Rollover host keys"
@@ -254,6 +379,8 @@ slave_get host/foo@${R} | \
' | sed 's/^.*[[]\(.*\)[]].*$/\1/' | grep '[0-9]' | sort -nu | tr -d '
' | ${EGREP} 1234 > /dev/null || exit 1
wait_for_slave2 4
echo "Delete 3DES keys"
${kadmin} -l del_enctype host/foo@${R} des3-cbc-sha1
wait_for_slave
@@ -280,6 +407,8 @@ ${kadmin} -l get host/foo@${R} > /dev/null 2>/dev/null && exit 1
KRB5_CONFIG="${objdir}/krb5-slave.conf" \
${kadmin} -l get host/bar@${R} > /dev/null || exit 1
wait_for_slave2 3
echo "Delete host"
${kadmin} -l delete host/bar@${R} || exit 1
wait_for_slave
@@ -290,8 +419,11 @@ ${kadmin} -l get host/bar@${R} > /dev/null 2>/dev/null && exit 1
echo "Re-add host"
${kadmin} -l add --random-key --use-defaults host/foo@${R} || exit 1
${kadmin} -l add --random-key --use-defaults host/bar@${R} || exit 1
wait_for_slave 2
wait_for "Slave sees re-added host" slave_check_exists "host/bar@${R}"
wait_for_slave2 3
echo "kill slave and remove log and database"
> iprop-stats
sh ${leaks_kill} ipropd-slave $ipds || exit 1
@@ -324,6 +456,7 @@ echo "checking slave is up again"
wait_for "slave to start and connect to master" \
${EGREP} 'iprop/slave.test.h5l.se@TEST.H5L.SE.*Up' iprop-stats >/dev/null
wait_for_slave 2
wait_for_slave2 2
${EGREP} 'up-to-date with version' iprop-slave-status >/dev/null || { echo "slave not up to date" ; cat iprop-slave-status ; exit 1; }
echo "checking for replay problems"
${EGREP} 'Entry already exists in database' messages.log && exit 1
@@ -359,6 +492,7 @@ ${EGREP} 'Entry already exists in database' messages.log && exit 1
${kadmin} -l cpw --random-password user@${R} > /dev/null || exit 1
wait_for_slave
wait_for_slave2
echo "live truncate on master log"
${iprop_log} truncate -K 5 || exit 1
@@ -408,6 +542,7 @@ ${EGREP} 'Entry already exists in database' messages.log && exit 1
echo "pushing one change"
${kadmin} -l cpw --random-password user@${R} > /dev/null || exit 1
wait_for_slave
wait_for_slave2 0
echo "Killing master"
sh ${leaks_kill} ipropd-master $ipdm || exit 1
@@ -439,6 +574,7 @@ kill -0 ${ipds} || { echo "slave no longer there"; exit 1; }
echo "pushing one change"
${kadmin} -l cpw --random-password user@${R} > /dev/null || exit 1
wait_for_slave
wait_for_slave2
echo "shutting down all services"
@@ -446,6 +582,8 @@ leaked=false
sh ${leaks_kill} kdc $kdcpid || leaked=true
sh ${leaks_kill} ipropd-master $ipdm || leaked=true
sh ${leaks_kill} ipropd-slave $ipds || leaked=true
sh ${leaks_kill} ipropd-master $ipdm2 || leaked=true
sh ${leaks_kill} ipropd-slave $ipds2 || leaked=true
rm -f iprop-slave-status
trap "" EXIT
$leaked && exit 1

View File

@@ -114,8 +114,8 @@
}
}
signal_socket = @objdir@/signal
iprop-stats = @objdir@/iprop-stats
signal_socket = @objdir@/@signalsocket@
iprop-stats = @objdir@/@ipropstats@
iprop-acl = @srcdir@/iprop-acl
log-max-size = 40000
@@ -123,14 +123,14 @@
db-dir = @objdir@
[logging]
kdc = 0-/FILE:@objdir@/messages.log
krb5 = 0-/FILE:@objdir@/messages.log
default = 0-/FILE:@objdir@/messages.log
kdc = 0-/FILE:@objdir@/@messages@.log
krb5 = 0-/FILE:@objdir@/@messages@.log
default = 0-/FILE:@objdir@/@messages@.log
# If you are doing preformance measurements on OSX you want to change
# the kdc LOG line from = to - below to keep the FILE open and avoid
# open/write/close which is blocking (rdar:// ) on OSX.
# kdc = 0-/FILE=@objdir@/messages.log
# kdc = 0-/FILE=@objdir@/@messages@.log
[kadmin]
save-password = true