krb5 commit: Avoid unnecessary iprop full resyncs after resets
Greg Hudson
ghudson at mit.edu
Mon Apr 13 18:09:07 EDT 2015
https://github.com/krb5/krb5/commit/0a8d39d8c4cbe0539343b44a9a1ebaebe9d1b363
commit 0a8d39d8c4cbe0539343b44a9a1ebaebe9d1b363
Author: Greg Hudson <ghudson at mit.edu>
Date: Thu Apr 9 14:23:07 2015 -0400
Avoid unnecessary iprop full resyncs after resets
When resetting the ulog header or initializing it from a dump file
kdb_last_t value, instead of setting kdb_num to 0, create a dummy
entry for the last_sno value so that we can remember its timestamp.
With this change, a slave no longer needs to perform two full resyncs
after an upstream header initialization. Dummy entries are never
transmitted to downstream slaves because the iprop protocol never
transmits the kdb_first_sno update; if one is somehow transmitted, the
slave will ignore it because it doesn't have the kdb_commit flag set.
reset_header() is renamed to reset_ulog(), takes a kdb_log_context
parameter, and is responsible for syncing the header. sync_update()
now returns void and aborts if msync() fails, just like sync_header().
A new helper set_dummy() writes a dummy entry and sets the ulog to
point to it.
Adjust kproplog to recognize and display dummy entries. Adjust
t_ulog.c and t_iprop.py for the new behavior. In t_iprop.py, remove a
kpropd -t test which became redundant with the previous test.
ticket: 8164 (new)
src/lib/kdb/kdb_log.c | 77 ++++++++++++++++---------
src/lib/kdb/t_ulog.c | 6 +-
src/slave/kproplog.c | 16 ++++--
src/tests/t_iprop.py | 153 ++++++++++++++++++++++--------------------------
4 files changed, 133 insertions(+), 119 deletions(-)
diff --git a/src/lib/kdb/kdb_log.c b/src/lib/kdb/kdb_log.c
index faca467..d377a20 100644
--- a/src/lib/kdb/kdb_log.c
+++ b/src/lib/kdb/kdb_log.c
@@ -51,14 +51,11 @@ time_current(kdbe_time_t *out)
}
/* Sync update entry to disk. */
-static krb5_error_code
+static void
sync_update(kdb_hlog_t *ulog, kdb_ent_header_t *upd)
{
unsigned long start, end, size;
- if (ulog == NULL)
- return KRB5_LOG_ERROR;
-
if (!pagesize)
pagesize = getpagesize();
@@ -68,7 +65,11 @@ sync_update(kdb_hlog_t *ulog, kdb_ent_header_t *upd)
~(pagesize - 1);
size = end - start;
- return msync((caddr_t)start, size, MS_SYNC);
+ if (msync((caddr_t)start, size, MS_SYNC)) {
+ /* Couldn't sync to disk, let's panic. */
+ syslog(LOG_ERR, _("could not sync ulog update to disk"));
+ abort();
+ }
}
/* Sync memory to disk for the update log header. */
@@ -199,15 +200,42 @@ resize(kdb_hlog_t *ulog, uint32_t ulogentries, int ulogfd,
return 0;
}
+/* Set the ulog to contain only a dummy entry with the given serial number and
+ * timestamp. */
+static void
+set_dummy(kdb_log_context *log_ctx, kdb_sno_t sno, const kdbe_time_t *kdb_time)
+{
+ kdb_hlog_t *ulog = log_ctx->ulog;
+ kdb_ent_header_t *ent = INDEX(ulog, (sno - 1) % log_ctx->ulogentries);
+
+ memset(ent, 0, sizeof(*ent));
+ ent->kdb_umagic = KDB_ULOG_MAGIC;
+ ent->kdb_entry_sno = sno;
+ ent->kdb_time = *kdb_time;
+ sync_update(ulog, ent);
+
+ ulog->kdb_num = 1;
+ ulog->kdb_first_sno = ulog->kdb_last_sno = sno;
+ ulog->kdb_first_time = ulog->kdb_last_time = *kdb_time;
+}
+
+/* Reinitialize the ulog header, starting from sno 1 with the current time. */
static void
-reset_header(kdb_hlog_t *ulog)
+reset_ulog(kdb_log_context *log_ctx)
{
+ kdbe_time_t kdb_time;
+ kdb_hlog_t *ulog = log_ctx->ulog;
+
memset(ulog, 0, sizeof(*ulog));
ulog->kdb_hmagic = KDB_ULOG_HDR_MAGIC;
ulog->db_version_num = KDB_VERSION;
- ulog->kdb_state = KDB_STABLE;
ulog->kdb_block = ULOG_BLOCK;
- time_current(&ulog->kdb_last_time);
+
+ /* Create a dummy entry to remember the timestamp for downstreams. */
+ time_current(&kdb_time);
+ set_dummy(log_ctx, 1, &kdb_time);
+ ulog->kdb_state = KDB_STABLE;
+ sync_header(ulog);
}
/*
@@ -276,14 +304,13 @@ store_update(kdb_log_context *log_ctx, kdb_incr_update_t *upd)
return KRB5_LOG_CONV;
indx_log->kdb_commit = TRUE;
- retval = sync_update(ulog, indx_log);
- if (retval)
- return retval;
+ sync_update(ulog, indx_log);
/* Modify the ulog header to reflect the new update. */
ulog->kdb_last_sno = upd->kdb_entry_sno;
ulog->kdb_last_time = upd->kdb_time;
if (ulog->kdb_num == 0) {
+ /* We should only see this in old ulogs. */
ulog->kdb_num = 1;
ulog->kdb_first_sno = upd->kdb_entry_sno;
ulog->kdb_first_time = upd->kdb_time;
@@ -318,7 +345,7 @@ ulog_add_update(krb5_context context, kdb_incr_update_t *upd)
/* If we have reached the last possible serial number, reinitialize the
* ulog and start over. Slaves will do a full resync. */
if (ulog->kdb_last_sno == (kdb_sno_t)-1)
- reset_header(ulog);
+ reset_ulog(log_ctx);
upd->kdb_entry_sno = ulog->kdb_last_sno + 1;
time_current(&upd->kdb_time);
@@ -367,7 +394,7 @@ ulog_replay(krb5_context context, kdb_incr_result_t *incr_ret, char **db_args)
/* If (unexpectedly) this update does not follow the last one we
* stored, discard any previous ulog state. */
if (ulog->kdb_num != 0 && upd->kdb_entry_sno != ulog->kdb_last_sno + 1)
- reset_header(ulog);
+ reset_ulog(log_ctx);
if (upd->kdb_deleted) {
dbprincstr = k5memdup0(upd->kdb_princ_name.utf8str_t_val,
@@ -411,10 +438,8 @@ ulog_replay(krb5_context context, kdb_incr_result_t *incr_ret, char **db_args)
cleanup:
if (fupd)
ulog_free_entries(fupd, no_of_updates);
- if (retval) {
- reset_header(ulog);
- sync_header(ulog);
- }
+ if (retval)
+ reset_ulog(log_ctx);
unlock_ulog(context);
krb5_db_unlock(context);
return retval;
@@ -432,8 +457,7 @@ ulog_init_header(krb5_context context)
ret = lock_ulog(context, KRB5_LOCKMODE_EXCLUSIVE);
if (ret)
return ret;
- reset_header(ulog);
- sync_header(ulog);
+ reset_ulog(log_ctx);
unlock_ulog(context);
return 0;
}
@@ -498,8 +522,7 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries)
unlock_ulog(context);
return KRB5_LOG_CORRUPT;
}
- reset_header(ulog);
- sync_header(ulog);
+ reset_ulog(log_ctx);
}
/* Reinit ulog if ulogentries changed such that we have too many entries or
@@ -507,10 +530,8 @@ ulog_map(krb5_context context, const char *logname, uint32_t ulogentries)
if (ulog->kdb_num != 0 &&
(ulog->kdb_num > ulogentries ||
!check_sno(log_ctx, ulog->kdb_first_sno, &ulog->kdb_first_time) ||
- !check_sno(log_ctx, ulog->kdb_last_sno, &ulog->kdb_last_time))) {
- reset_header(ulog);
- sync_header(ulog);
- }
+ !check_sno(log_ctx, ulog->kdb_last_sno, &ulog->kdb_last_time)))
+ reset_ulog(log_ctx);
if (ulog->kdb_num != ulogentries) {
/* Expand the ulog file if it isn't big enough. */
@@ -550,7 +571,7 @@ ulog_get_entries(krb5_context context, const kdb_last_t *last,
/* If another process terminated mid-update, reset the ulog and force full
* resyncs. */
if (ulog->kdb_state != KDB_STABLE)
- reset_header(ulog);
+ reset_ulog(log_ctx);
ulog_handle->ret = get_sno_status(log_ctx, last);
if (ulog_handle->ret != UPDATE_OK)
@@ -649,8 +670,8 @@ ulog_set_last(krb5_context context, const kdb_last_t *last)
ret = lock_ulog(context, KRB5_LOCKMODE_EXCLUSIVE);
if (ret)
return ret;
- ulog->kdb_last_sno = last->last_sno;
- ulog->kdb_last_time = last->last_time;
+
+ set_dummy(log_ctx, last->last_sno, &last->last_time);
sync_header(ulog);
unlock_ulog(context);
return 0;
diff --git a/src/lib/kdb/t_ulog.c b/src/lib/kdb/t_ulog.c
index 2fb8a82..96e00bb 100644
--- a/src/lib/kdb/t_ulog.c
+++ b/src/lib/kdb/t_ulog.c
@@ -77,12 +77,12 @@ main(int argc, char **argv)
ulog->kdb_first_sno = ulog->kdb_last_sno - ulog->kdb_num + 1;
/* Add an empty update. This should reinitialize the ulog, then add the
- * update with serial number 1. */
+ * update with serial number 2. */
memset(&upd, 0, sizeof(kdb_incr_update_t));
if (ulog_add_update(context, &upd) != 0)
abort();
- assert(ulog->kdb_num == 1);
+ assert(ulog->kdb_num == 2);
assert(ulog->kdb_first_sno == 1);
- assert(ulog->kdb_last_sno == 1);
+ assert(ulog->kdb_last_sno == 2);
return 0;
}
diff --git a/src/slave/kproplog.c b/src/slave/kproplog.c
index efa1f43..857ef03 100644
--- a/src/slave/kproplog.c
+++ b/src/slave/kproplog.c
@@ -357,6 +357,17 @@ print_update(kdb_hlog_t *ulog, uint32_t entry, uint32_t ulogentries,
exit(1);
}
+ printf("---\n");
+ printf(_("Update Entry\n"));
+
+ printf(_("\tUpdate serial # : %u\n"), indx_log->kdb_entry_sno);
+
+ /* The initial entry after a reset is a dummy entry; skip it. */
+ if (indx_log->kdb_entry_size == 0) {
+ printf(_("\tDummy entry\n"));
+ continue;
+ }
+
memset(&upd, 0, sizeof(kdb_incr_update_t));
xdrmem_create(&xdrs, (char *)indx_log->entry_data,
indx_log->kdb_entry_size, XDR_DECODE);
@@ -365,11 +376,6 @@ print_update(kdb_hlog_t *ulog, uint32_t entry, uint32_t ulogentries,
exit(1);
}
- printf("---\n");
- printf(_("Update Entry\n"));
-
- printf(_("\tUpdate serial # : %u\n"), indx_log->kdb_entry_sno);
-
printf(_("\tUpdate operation : "));
if (upd.kdb_deleted)
printf(_("Delete\n"));
diff --git a/src/tests/t_iprop.py b/src/tests/t_iprop.py
index 1ed8dbd..6b38b8a 100755
--- a/src/tests/t_iprop.py
+++ b/src/tests/t_iprop.py
@@ -100,7 +100,13 @@ def check_ulog(num, first, last, entries, env=None):
m = re.match(r'\tUpdate principal : (.*)$', line)
if m:
eprinc = entries[ser - first]
- if m.group(1) != eprinc:
+ if eprinc == None:
+ fail('Expected dummy update entry %d' % ser)
+ elif m.group(1) != eprinc:
+ fail('Expected princ %s in update entry %d' % (eprinc, ser))
+ if line == '\tDummy entry':
+ eprinc = entries[ser - first]
+ if eprinc != None:
fail('Expected princ %s in update entry %d' % (eprinc, ser))
# slave1 will receive updates from master, and slave2 will receive
@@ -158,7 +164,7 @@ realm.run([kdb5_util, 'load', dumpfile], slave2)
# Reinitialize the master ulog so we know exactly what to expect in
# it.
realm.run([kproplog, '-R'])
-check_ulog(0, 0, 0, [])
+check_ulog(1, 1, 1, [None])
# Make some changes to the master DB.
realm.addprinc(pr1)
@@ -166,22 +172,22 @@ realm.addprinc(pr3)
realm.addprinc(pr2)
realm.run([kadminl, 'modprinc', '-allow_tix', pr2])
realm.run([kadminl, 'modprinc', '+allow_tix', pr2])
-check_ulog(5, 1, 5, [pr1, pr3, pr2, pr2, pr2])
+check_ulog(6, 1, 6, [None, pr1, pr3, pr2, pr2, pr2])
# Start kpropd for slave1 and get a full dump from master.
kpropd1 = realm.start_kpropd(slave1, ['-d'])
-wait_for_prop(kpropd1, True, 0, 5)
+wait_for_prop(kpropd1, True, 1, 6)
out = realm.run([kadminl, 'listprincs'], env=slave1)
if pr1 not in out or pr2 not in out or pr3 not in out:
fail('slave1 does not have all principals from master')
-check_ulog(0, 0, 5, [], slave1)
+check_ulog(1, 6, 6, [None], slave1)
# Make a change and check that it propagates incrementally.
realm.run([kadminl, 'modprinc', '-allow_tix', pr2])
-check_ulog(6, 1, 6, [pr1, pr3, pr2, pr2, pr2, pr2])
+check_ulog(7, 1, 7, [None, pr1, pr3, pr2, pr2, pr2, pr2])
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, False, 5, 6)
-check_ulog(1, 6, 6, [pr2], slave1)
+wait_for_prop(kpropd1, False, 6, 7)
+check_ulog(2, 6, 7, [None, pr2], slave1)
out = realm.run([kadminl, 'getprinc', pr2], env=slave1)
if 'Attributes: DISALLOW_ALL_TIX' not in out:
fail('slave1 does not have modification from master')
@@ -203,8 +209,8 @@ realm.start_server([kadmind, '-nofork', '-proponly', '-W', '-p', kdb5_util,
kpropd2 = realm.start_server([kpropd, '-d', '-D', '-P', slave2_kprop_port,
'-f', slave2_in_dump_path, '-p', kdb5_util,
'-a', acl_file, '-A', hostname], 'ready', slave2)
-wait_for_prop(kpropd2, True, 0, 6)
-check_ulog(0, 0, 6, [], slave2)
+wait_for_prop(kpropd2, True, 1, 7)
+check_ulog(1, 7, 7, [None], slave2)
out = realm.run([kadminl, 'listprincs'], env=slave1)
if pr1 not in out or pr2 not in out or pr3 not in out:
fail('slave2 does not have all principals from slave1')
@@ -212,16 +218,16 @@ if pr1 not in out or pr2 not in out or pr3 not in out:
# Make another change and check that it propagates incrementally to
# both slaves.
realm.run([kadminl, 'modprinc', '-maxrenewlife', '22 hours', pr1])
-check_ulog(7, 1, 7, [pr1, pr3, pr2, pr2, pr2, pr2, pr1])
+check_ulog(8, 1, 8, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1])
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, False, 6, 7)
-check_ulog(2, 6, 7, [pr2, pr1], slave1)
+wait_for_prop(kpropd1, False, 7, 8)
+check_ulog(3, 6, 8, [None, pr2, pr1], slave1)
out = realm.run([kadminl, 'getprinc', pr1], env=slave1)
if 'Maximum renewable life: 0 days 22:00:00\n' not in out:
fail('slave1 does not have modification from master')
kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, False, 6, 7)
-check_ulog(1, 7, 7, [pr1], slave2)
+wait_for_prop(kpropd2, False, 7, 8)
+check_ulog(2, 7, 8, [None, pr1], slave2)
out = realm.run([kadminl, 'getprinc', pr1], env=slave2)
if 'Maximum renewable life: 0 days 22:00:00\n' not in out:
fail('slave2 does not have modification from slave1')
@@ -231,126 +237,120 @@ if 'Maximum renewable life: 0 days 22:00:00\n' not in out:
# slave2 should still be in sync with slave1 after the resync, so make
# sure it doesn't take a full resync.
realm.run([kproplog, '-R'], slave1)
-check_ulog(0, 0, 0, [], slave1)
+check_ulog(1, 1, 1, [None], slave1)
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, True, 0, 7)
-check_ulog(2, 6, 7, [pr2, pr1], slave1)
+wait_for_prop(kpropd1, True, 1, 8)
+check_ulog(3, 6, 8, [None, pr2, pr1], slave1)
kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, False, 7, 7)
-check_ulog(1, 7, 7, [pr1], slave2)
+wait_for_prop(kpropd2, False, 8, 8)
+check_ulog(2, 7, 8, [None, pr1], slave2)
# Make another change and check that it propagates incrementally to
# both slaves.
realm.run([kadminl, 'modprinc', '+allow_tix', 'w'])
-check_ulog(8, 1, 8, [pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr2])
+check_ulog(9, 1, 9, [None, pr1, pr3, pr2, pr2, pr2, pr2, pr1, pr2])
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, False, 7, 8)
-check_ulog(3, 6, 8, [pr2, pr1, pr2], slave1)
+wait_for_prop(kpropd1, False, 8, 9)
+check_ulog(4, 6, 9, [None, pr2, pr1, pr2], slave1)
out = realm.run([kadminl, 'getprinc', pr2], env=slave1)
if 'Attributes:\n' not in out:
fail('slave1 does not have modification from master')
kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, False, 7, 8)
-check_ulog(2, 7, 8, [pr1, pr2], slave2)
+wait_for_prop(kpropd2, False, 8, 9)
+check_ulog(3, 7, 9, [None, pr1, pr2], slave2)
out = realm.run([kadminl, 'getprinc', pr2], env=slave2)
if 'Attributes:\n' not in out:
fail('slave2 does not have modification from slave1')
# Create a policy and check that it propagates via full resync.
realm.run([kadminl, 'addpol', '-minclasses', '2', 'testpol'])
-check_ulog(0, 0, 0, [])
+check_ulog(1, 1, 1, [None])
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, True, 8, 0)
-check_ulog(0, 0, 0, [], slave1)
+wait_for_prop(kpropd1, True, 9, 1)
+check_ulog(1, 1, 1, [None], slave1)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1)
if 'Minimum number of password character classes: 2' not in out:
fail('slave1 does not have policy from master')
kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 8, 0)
-check_ulog(0, 0, 0, [], slave2)
+wait_for_prop(kpropd2, True, 9, 1)
+check_ulog(1, 1, 1, [None], slave2)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2)
if 'Minimum number of password character classes: 2' not in out:
fail('slave2 does not have policy from slave1')
# Modify the policy and test that it also propagates via full resync.
realm.run([kadminl, 'modpol', '-minlength', '17', 'testpol'])
-check_ulog(0, 0, 0, [])
+check_ulog(1, 1, 1, [None])
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, True, 0, 0)
-check_ulog(0, 0, 0, [], slave1)
+wait_for_prop(kpropd1, True, 1, 1)
+check_ulog(1, 1, 1, [None], slave1)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1)
if 'Minimum password length: 17' not in out:
fail('slave1 does not have policy change from master')
kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 0, 0)
-check_ulog(0, 0, 0, [], slave2)
+wait_for_prop(kpropd2, True, 1, 1)
+check_ulog(1, 1, 1, [None], slave2)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2)
if 'Minimum password length: 17' not in out:
fail('slave2 does not have policy change from slave1')
# Delete the policy and test that it propagates via full resync.
realm.run([kadminl, 'delpol', 'testpol'])
-check_ulog(0, 0, 0, [])
+check_ulog(1, 1, 1, [None])
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, True, 0, 0)
-check_ulog(0, 0, 0, [], slave1)
+wait_for_prop(kpropd1, True, 1, 1)
+check_ulog(1, 1, 1, [None], slave1)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1, expected_code=1)
if 'Policy does not exist' not in out:
fail('slave1 did not get policy deletion from master')
kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 0, 0)
-check_ulog(0, 0, 0, [], slave2)
+wait_for_prop(kpropd2, True, 1, 1)
+check_ulog(1, 1, 1, [None], slave2)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave2, expected_code=1)
if 'Policy does not exist' not in out:
fail('slave2 did not get policy deletion from slave1')
-# Modify a principal on the master and test that it propagates via
-# full resync. (The master's ulog does not remember the timestamp it
-# had at serial number 0, so it does not know that an incremental
-# propagation is possible.)
+# Modify a principal on the master and test that it propagates incrementally.
realm.run([kadminl, 'modprinc', '-maxlife', '10 minutes', pr1])
-check_ulog(1, 1, 1, [pr1])
+check_ulog(2, 1, 2, [None, pr1])
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, True, 0, 1)
-check_ulog(0, 0, 1, [], slave1)
+wait_for_prop(kpropd1, False, 1, 2)
+check_ulog(2, 1, 2, [None, pr1], slave1)
out = realm.run([kadminl, 'getprinc', pr1], env=slave1)
if 'Maximum ticket life: 0 days 00:10:00' not in out:
fail('slave1 does not have modification from master')
kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 0, 1)
-check_ulog(0, 0, 1, [], slave2)
+wait_for_prop(kpropd2, False, 1, 2)
+check_ulog(2, 1, 2, [None, pr1], slave2)
out = realm.run([kadminl, 'getprinc', pr1], env=slave2)
if 'Maximum ticket life: 0 days 00:10:00' not in out:
fail('slave2 does not have modification from slave1')
-# Delete a principal and test that it propagates incrementally to
-# slave1. slave2 needs another full resync because slave1 no longer
-# has serial number 1 in its ulog after processing its first
-# incremental update.
+# Delete a principal and test that it propagates incrementally.
realm.run([kadminl, 'delprinc', pr3])
-check_ulog(2, 1, 2, [pr1, pr3])
+check_ulog(3, 1, 3, [None, pr1, pr3])
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, False, 1, 2)
-check_ulog(1, 2, 2, [pr3], slave1)
+wait_for_prop(kpropd1, False, 2, 3)
+check_ulog(3, 1, 3, [None, pr1, pr3], slave1)
out = realm.run([kadminl, 'getprinc', pr3], env=slave1, expected_code=1)
if 'Principal does not exist' not in out:
fail('slave1 does not have principal deletion from master')
kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 1, 2)
-check_ulog(0, 0, 2, [], slave2)
+wait_for_prop(kpropd2, False, 2, 3)
+check_ulog(3, 1, 3, [None, pr1, pr3], slave2)
out = realm.run([kadminl, 'getprinc', pr3], env=slave2, expected_code=1)
if 'Principal does not exist' not in out:
fail('slave2 does not have principal deletion from slave1')
# Reset the ulog on the master to force a full resync.
realm.run([kproplog, '-R'])
-check_ulog(0, 0, 0, [])
+check_ulog(1, 1, 1, [None])
kpropd1.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd1, True, 2, 0)
-check_ulog(0, 0, 0, [], slave1)
+wait_for_prop(kpropd1, True, 3, 1)
+check_ulog(1, 1, 1, [None], slave1)
kpropd2.send_signal(signal.SIGUSR1)
-wait_for_prop(kpropd2, True, 2, 0)
-check_ulog(0, 0, 0, [], slave2)
+wait_for_prop(kpropd2, True, 3, 1)
+check_ulog(1, 1, 1, [None], slave2)
# Stop the kprop daemons so we can test kpropd -t.
stop_daemon(kpropd1)
@@ -360,40 +360,27 @@ stop_daemon(kpropd2)
out = realm.run_kpropd_once(slave1, ['-d'])
if 'KDC is synchronized' not in out:
fail('Expected synchronized from kpropd -t')
-check_ulog(0, 0, 0, [], slave1)
+check_ulog(1, 1, 1, [None], slave1)
-# Make a change on the master; this will cause a full resync since the
-# master was recently reinitialized.
+# Make a change on the master and fetch it incrementally.
realm.run([kadminl, 'modprinc', '-maxlife', '5 minutes', pr1])
-check_ulog(1, 1, 1, [pr1])
+check_ulog(2, 1, 2, [None, pr1])
out = realm.run_kpropd_once(slave1, ['-d'])
-if ('Full propagation transfer finished' not in out or
- 'KDC is synchronized' not in out):
+if 'Got incremental updates (sno=2 ' not in out:
fail('Expected full dump and synchronized from kpropd -t')
-check_ulog(0, 0, 1, [], slave1)
+check_ulog(2, 1, 2, [None, pr1], slave1)
out = realm.run([kadminl, 'getprinc', pr1], env=slave1)
if 'Maximum ticket life: 0 days 00:05:00' not in out:
fail('slave1 does not have modification from master after kpropd -t')
-# Make another change and get it via incremental update.
-realm.run([kadminl, 'modprinc', '-maxlife', '15 minutes', pr1])
-check_ulog(2, 1, 2, [pr1, pr1])
-out = realm.run_kpropd_once(slave1, ['-d'])
-if 'Got incremental updates (sno=2 ' not in out:
- fail('Expected incremental updates from kpropd -t')
-check_ulog(1, 2, 2, [pr1], slave1)
-out = realm.run([kadminl, 'getprinc', pr1], env=slave1)
-if 'Maximum ticket life: 0 days 00:15:00' not in out:
- fail('slave1 does not have modification from master after kpropd -t')
-
# Propagate a policy change via full resync.
realm.run([kadminl, 'addpol', '-minclasses', '3', 'testpol'])
-check_ulog(0, 0, 0, [])
+check_ulog(1, 1, 1, [None])
out = realm.run_kpropd_once(slave1, ['-d'])
if ('Full propagation transfer finished' not in out or
'KDC is synchronized' not in out):
fail('Expected full dump and synchronized from kpropd -t')
-check_ulog(0, 0, 0, [], slave1)
+check_ulog(1, 1, 1, [None], slave1)
out = realm.run([kadminl, 'getpol', 'testpol'], env=slave1)
if 'Minimum number of password character classes: 3' not in out:
fail('slave1 does not have policy from master after kpropd -t')
More information about the cvs-krb5
mailing list