]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- There is now a default 1/4 of a second scheduled delay between delayed
authorDavid Hankins <dhankins@isc.org>
Thu, 28 Feb 2008 23:40:45 +0000 (23:40 +0000)
committerDavid Hankins <dhankins@isc.org>
Thu, 28 Feb 2008 23:40:45 +0000 (23:40 +0000)
  fsync()'s, it can be configured by the max-ack-delay configuration
  parameter.  [ISC-Bugs #17679]

RELNOTES
includes/dhcpd.h
server/db.c
server/dhcp.c
server/dhcpd.c
server/dhcpd.conf.5
server/stables.c

index 3fe70bac27a15c27fbfb04a824c3318e35d034f2..731881ea5ce4f85dfc04b8b7d02856ded4207f7f 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -57,6 +57,10 @@ work on other platforms. Please report any problems and suggested fixes to
 - ./configure was extended to cover many optional build features, such
   as failover, server tracing, debugging, and the execute() command.
 
+- There is now a default 1/4 of a second scheduled delay between delayed
+  fsync()'s, it can be configured by the max-ack-delay configuration
+  parameter.
+
                        Changes since 4.0.0 (new features)
 
 - Added DHCPv6 rapid commit support.
index 489075c64faa6dfc899957269884d3e1e6798be4..7b17709335a782a45a216cdb5ceaa638f94c0c61 100644 (file)
@@ -624,6 +624,7 @@ struct lease_state {
 #define SV_LIMIT_ADDRS_PER_IA          56
 #define SV_LIMIT_PREFS_PER_IA          57
 #define SV_DELAYED_ACK                 58
+#define SV_MAX_ACK_DELAY               59
 
 #if !defined (DEFAULT_PING_TIMEOUT)
 # define DEFAULT_PING_TIMEOUT 1
@@ -633,6 +634,14 @@ struct lease_state {
 # define DEFAULT_DELAYED_ACK 28  /* default SO_SNDBUF size / 576 bytes */
 #endif
 
+#if !defined (DEFAULT_ACK_DELAY_SECS)
+# define DEFAULT_ACK_DELAY_SECS 0
+#endif
+
+#if !defined (DEFAULT_ACK_DELAY_USECS)
+# define DEFAULT_ACK_DELAY_USECS 250000 /* 1/4 of a second */
+#endif
+
 #if !defined (DEFAULT_DEFAULT_LEASE_TIME)
 # define DEFAULT_DEFAULT_LEASE_TIME 43200
 #endif
@@ -1939,6 +1948,8 @@ int data_string_sprintfa(struct data_string *ds, const char *fmt, ...);
 /* dhcp.c */
 extern int outstanding_pings;
 extern int max_outstanding_acks;
+extern int max_ack_delay_secs;
+extern int max_ack_delay_usecs;
 
 void dhcp PROTO ((struct packet *));
 void dhcpdiscover PROTO ((struct packet *, int));
index e2af0a28255889fc1f310ec0d6308027d275ffc2..563a261c99e4cc074588e1e1f214949b9b0b8cdc 100644 (file)
@@ -1059,8 +1059,8 @@ int commit_leases ()
                log_info ("commit_leases: unable to commit: %m");
                return 0;
        }
-       
-       /* send out all deferred ACKs now*/
+
+       /* send out all deferred ACKs now */
        flush_ackqueue(NULL);
 
        /* If we haven't rewritten the lease database in over an
index 7376932e3dd5bfa6c3c35c18275d5b928e196079..756746fe0aca8776cbbe8db611285f98ad7fe76f 100644 (file)
 #include "dhcpd.h"
 #include <errno.h>
 #include <limits.h>
+#include <sys/time.h>
+
+static void commit_leases_ackout(void *foo);
 
 int outstanding_pings;
 
 struct leasequeue *ackqueue_head, *ackqueue_tail;
 static struct leasequeue *free_ackqueue;
-TIME next_fsync;
+static struct timeval next_fsync;
 int outstanding_acks;
 int max_outstanding_acks = DEFAULT_DELAYED_ACK;
+int max_ack_delay_secs = DEFAULT_ACK_DELAY_SECS;
+int max_ack_delay_usecs = DEFAULT_ACK_DELAY_USECS;
 
 static char dhcp_message [256];
 static int site_code_min;
@@ -2836,6 +2841,7 @@ void
 delayed_ack_enqueue(struct lease *lease)
 {
        struct leasequeue *q;
+
        if (!write_lease(lease)) 
                return;
        if (free_ackqueue) {
@@ -2861,21 +2867,41 @@ delayed_ack_enqueue(struct lease *lease)
        if (outstanding_acks > max_outstanding_acks) 
                commit_leases();
 
-       /* If neccessary, schedule a fsync in 1 second */
-       /*
-       if (next_fsync < cur_time + 1) {
-               next_fsync = cur_time + 1;
-               add_timeout(next_fsync, commit_leases_readerdry, NULL,
+       /* If next_fsync is not set, schedule an fsync. */
+       if (next_fsync.tv_sec == 0 && next_fsync.tv_usec == 0) {
+               next_fsync.tv_sec = cur_tv.tv_sec + max_ack_delay_secs;
+               next_fsync.tv_usec = cur_tv.tv_usec + max_ack_delay_usecs;
+
+               if (next_fsync.tv_usec >= 1000000) {
+                       next_fsync.tv_sec++;
+                       next_fsync.tv_usec -= 1000000;
+               }
+
+               add_timeout(&next_fsync, commit_leases_ackout, NULL,
                            (tvref_t) NULL, (tvunref_t) NULL);
        }
-       */
 }
 
 void
 commit_leases_readerdry(void *foo) 
 {
-       if (outstanding_acks) 
+       if (outstanding_acks) {
+               commit_leases();
+
+               /* Reset next_fsync and cancel any pending timeout. */
+               memset(&next_fsync, 0, sizeof(next_fsync));
+               cancel_timeout(commit_leases_ackout, NULL);
+       }
+}
+
+static void
+commit_leases_ackout(void *foo)
+{
+       if (outstanding_acks) {
                commit_leases();
+
+               memset(&next_fsync, 0, sizeof(next_fsync));
+       }
 }
 
 /* CC: process the delayed ACK responses:
index 3540e53285470c202f63b7be12525e16e2464981..0f17ce41724220b4d1631b0730d11d656f5c3ece 100644 (file)
@@ -1086,6 +1086,22 @@ void postconf_initialization (int quiet)
                data_string_forget(&db, MDL);
        }
 
+       oc = lookup_option(&server_universe, options, SV_MAX_ACK_DELAY);
+       if (oc &&
+           evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
+                                 &global_scope, oc, MDL)) {
+               u_int32_t timeval;
+
+               if (db.len != 4)
+                       log_fatal("invalid max ack delay configuration");
+
+               timeval = getULong(db.data);
+               max_ack_delay_secs  = timeval / 1000000;
+               max_ack_delay_usecs = timeval % 1000000;
+
+               data_string_forget(&db, MDL);
+       }
+
        /* Don't need the options anymore. */
        option_state_dereference (&options, MDL);
        
index 221ce295020fc4afe364af0f22b755b87033073e..3425792063915eed9b8cc6d39f70c1c04d3d6f08 100644 (file)
@@ -28,7 +28,7 @@
 .\" see ``http://www.vix.com''.   To learn more about Nominum, Inc., see
 .\" ``http://www.nominum.com''.
 .\"
-.\" $Id: dhcpd.conf.5,v 1.94 2008/02/20 12:45:53 fdupont Exp $
+.\" $Id: dhcpd.conf.5,v 1.95 2008/02/28 23:40:45 dhankins Exp $
 .\"
 .TH dhcpd.conf 5
 .SH NAME
@@ -2069,14 +2069,17 @@ as the "valid lifetime" in DHCPv6).
 .PP
 The
 .I delayed-ack
-statement
+and
+.I max-ack-delay
+statements
 .RS 0.25i
 .PP
-.B delayed-ack \fInumber\fR\fB;\fR
+.B delayed-ack \fIcount\fR\fB;\fR
+.B max-ack-delay \fImicroseconds\fR\fB;\fR
 .PP
-.I Number
+.I Count
 should be an integer value from zero to 2^16-1, and defaults to 28.  The
-number represents how many DHCPv4 replies maximum will be queued pending
+count represents how many DHCPv4 replies maximum will be queued pending
 transmission until after a database commit event.  If this number is
 reached, a database commit event (commonly resulting in fsync() and
 representing a performance penalty) will be made, and the reply packets
@@ -2084,6 +2087,11 @@ will be transmitted in a batch afterwards.  This preserves the RFC2131
 direction that "stable storage" be updated prior to replying to clients.
 Should the DHCPv4 sockets "go dry" (select() returns immediately with no
 read sockets), the commit is made and any queued packets are transmitted.
+.PP
+Similarly, \fImicroseconds\fR indicates how many microseconds are permitted
+to pass inbetween queuing a packet pending an fsync, and performing the
+fsync.  Valid values range from 0 to 2^32-1, and defaults to 250,000 (1/4 of
+a second).
 .RE
 .PP
 The
index abb9647992c9f264350a54124ee15af3e8b33a2a..d21181662746db653e395f120c685eef5da082e2 100644 (file)
@@ -240,6 +240,7 @@ static struct option server_options[] = {
        { "limit-addrs-per-ia", "L",            &server_universe,  56, 1 },
        { "limit-prefs-per-ia", "L",            &server_universe,  57, 1 },
        { "delayed-ack", "S",                   &server_universe,  58, 1 },
+       { "max-ack-delay", "L",                 &server_universe,  59, 1 },
        { NULL, NULL, NULL, 0, 0 }
 };