]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- Some patches to improve DHCP Server startup speed from Andrew Matheson
authorDavid Hankins <dhankins@isc.org>
Fri, 9 Jun 2006 15:51:02 +0000 (15:51 +0000)
committerDavid Hankins <dhankins@isc.org>
Fri, 9 Jun 2006 15:51:02 +0000 (15:51 +0000)
  have been incorporated. [ISC-Bugs #3154]

RELNOTES
server/mdb.c

index bd3af2dd243dadbce678645fcfdd9c0ecf00db2e..93e61bcc900109e067c5f9f6ec45d5da5153cc06 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -103,6 +103,9 @@ and for prodding me into improving it.
   been added which prints the local time in /var/db/dhcpd.leases rather
   than UTC.  Thanks to a patch from Ken Lalonde.
 
+- Some patches to improve DHCP Server startup speed from Andrew Matheson
+  have been incorporated.
+
                        Changes since 3.0.4
 
 - A warning that host statements declared within subnet or shared-network
index 959fb4695bbe66b7330a46849d955e0f0f9abdc9..3d10960524178a301a34a369250acd9d8b880f68 100644 (file)
@@ -34,7 +34,7 @@
 
 #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"
@@ -95,6 +95,15 @@ isc_result_t enter_class(cd, dynamicp, commit)
 }
 
 
+/* 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)
 {
@@ -1159,8 +1168,10 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
        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)
@@ -1956,6 +1967,8 @@ int write_leases ()
 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)
@@ -2029,13 +2042,28 @@ int lease_enqueue (struct lease *comp)
                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);
@@ -2049,6 +2077,8 @@ int lease_enqueue (struct lease *comp)
                }
                lease_reference (lq, comp, MDL);
        }
+       last_insert_point = comp;
+       last_lq = lq;
        return 1;
 }
 
@@ -2121,12 +2151,20 @@ void expire_all_pools ()
        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);
@@ -2134,7 +2172,7 @@ void expire_all_pools ()
                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;
@@ -2172,6 +2210,9 @@ void expire_all_pools ()
                }
            }
        }
+
+       /* turn off startup phase */
+       server_starting = 0;
 }
 
 void dump_subnets ()