summaryrefslogtreecommitdiff
path: root/server/failover.c
diff options
context:
space:
mode:
authorDavid Hankins <dhankins@isc.org>2007-10-09 22:32:49 +0000
committerDavid Hankins <dhankins@isc.org>2007-10-09 22:32:49 +0000
commitedb1283e10c6062cd7e84427d88e3c79baedccf9 (patch)
tree47f55e6b42b2825f9f33cd80dc6e6a0c053b36da /server/failover.c
parentf765ec367278d1e1673ac6c32570a1f6a57c6ef2 (diff)
downloadisc-dhcp-edb1283e10c6062cd7e84427d88e3c79baedccf9.tar.gz
- The peer_wants_leases() changes pulled up from 3.1.0 were corrected,
'never used' leases will no longer consistently shift between servers on every pool rebalance run. [ISC-Bugs #17211]
Diffstat (limited to 'server/failover.c')
-rw-r--r--server/failover.c39
1 files changed, 31 insertions, 8 deletions
diff --git a/server/failover.c b/server/failover.c
index 83719554..36451fb0 100644
--- a/server/failover.c
+++ b/server/failover.c
@@ -2362,17 +2362,40 @@ static int dhcp_failover_pool_dobalance(dhcp_failover_state_t *state)
pass = 0;
lease_reference(&lp, *lq, MDL);
- /* In the case where there are 2 leases, hold is zero, and
- * lts is 1 if both leases are on the local server. If
- * there is only 1 lease, both lts and hold are zero. Let's
- * not play ping pong.
- */
- while (lp && (lts > (pass ? hold : -hold))) {
+ while (lp) {
if (next)
lease_dereference(&next, MDL);
if (lp->next)
lease_reference(&next, lp->next, MDL);
+ /*
+ * Stop if the pool is 'balanced enough.'
+ *
+ * The pool is balanced enough if:
+ *
+ * 1) We're on the first run through and the peer has
+ * its fair share of leases already (lts reaches
+ * -hold).
+ * 2) We're on the second run through, we are shifting
+ * never-used leases, and there is a perfectly even
+ * balance (lts reaches zero).
+ * 3) Second run through, we are shifting previously
+ * used leases, and the local system has its fair
+ * share but no more (lts reaches hold).
+ *
+ * Note that this is implemented below in 3,2,1 order.
+ */
+ if (pass) {
+ if (lp->ends) {
+ if (lts <= hold)
+ break;
+ } else {
+ if (lts <= 0)
+ break;
+ }
+ } else if (lts <= -hold)
+ break;
+
if (pass || peer_wants_lease(lp)) {
--lts;
++leases_queued;
@@ -5512,8 +5535,8 @@ peer_wants_lease(struct lease *lp)
*/
hbaix = loadb_p_hash(lp->hardware_addr.hbuf + 1,
lp->hardware_addr.hlen - 1);
- else /* Consistent 50/50 split */
- return(lp->ip_addr.iabuf[lp->ip_addr.len-1] & 0x01);
+ else /* impossible to categorize into LBA */
+ return 0;
hm = state->hba[(hbaix >> 3) & 0x1F] & (1 << (hbaix & 0x07));