#ifndef lint
static char copyright[] =
-"$Id: mdb.c,v 1.79 2006/06/01 20:23:17 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
+"$Id: mdb.c,v 1.80 2006/06/09 15:51:02 dhankins Exp $ Copyright (c) 2004-2006 Internet Systems Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
}
+/* Variable to check if we're starting the server. The server will init as
+ * starting - but just to be safe start out as false to avoid triggering new
+ * special-case code
+ * XXX: There is actually a server_startup state...which is never entered...
+ */
+#define SS_NOSYNC 1
+#define SS_QFOLLOW 2
+static int server_starting = 0;
+
static int find_uid_statement (struct executable_statement *esp,
void *vp, int condp)
{
if (commit) {
if (!write_lease (comp))
return 0;
- if (!commit_leases ())
- return 0;
+ if ((server_starting & SS_NOSYNC) == 0) {
+ if (!commit_leases ())
+ return 0;
+ }
}
#if defined (FAILOVER_PROTOCOL)
int lease_enqueue (struct lease *comp)
{
struct lease **lq, *prev, *lp;
+ static struct lease **last_lq = NULL;
+ static struct lease *last_insert_point = NULL;
/* No queue to put it on? */
if (!comp -> pool)
return 0;
}
+ /* This only works during server startup: during runtime, the last
+ * lease may be dequeued inbetween calls. If the queue is the same
+ * as was used previously, and the lease structure isn't (this is not
+ * a re-queue), use that as a starting point for the insertion-sort.
+ */
+ if ((server_starting & SS_QFOLLOW) && (lq == last_lq) &&
+ (comp != last_insert_point) &&
+ (last_insert_point->sort_time <= comp->sort_time)) {
+ prev = last_insert_point;
+ lp = prev->next;
+ } else {
+ prev = NULL;
+ lp = *lq;
+ }
+
/* Insertion sort the lease onto the appropriate queue. */
- prev = (struct lease *)0;
- for (lp = *lq; lp; lp = lp -> next) {
+ for (; lp ; lp = lp->next) {
if (lp -> sort_time >= comp -> sort_time)
break;
prev = lp;
}
+
if (prev) {
if (prev -> next) {
lease_reference (&comp -> next, prev -> next, MDL);
}
lease_reference (lq, comp, MDL);
}
+ last_insert_point = comp;
+ last_lq = lq;
return 1;
}
struct lease *l;
struct lease **lptr[6];
+ /* Indicate that we are in the startup phase */
+ server_starting = SS_NOSYNC | SS_QFOLLOW;
+
/* First, go over the hash list and actually put all the leases
on the appropriate lists. */
lease_hash_foreach (lease_ip_addr_hash, lease_instantiate);
/* Loop through each pool in each shared network and call the
- expiry routine on the pool. */
+ * expiry routine on the pool. It is no longer safe to follow
+ * the queue insertion point, as expiration of a lease can move
+ * it between queues (and this may be the lease that function
+ * points at).
+ */
+ server_starting &= ~SS_QFOLLOW;
for (s = shared_networks; s; s = s -> next) {
for (p = s -> pools; p; p = p -> next) {
pool_timer (p);
p -> lease_count = 0;
p -> free_leases = 0;
p -> backup_leases = 0;
-
+
lptr [FREE_LEASES] = &p -> free;
lptr [ACTIVE_LEASES] = &p -> active;
lptr [EXPIRED_LEASES] = &p -> expired;
}
}
}
+
+ /* turn off startup phase */
+ server_starting = 0;
}
void dump_subnets ()