.PP
To shut the server down, open its control object and set the state
attribute to 2.
+.SH THE FAILOVER-STATE OBJECT
+The failover-state object is the object that tracks the state of the
+failover protocol as it is being managed for a given failover peer.
+The failover object has the following attributes (please see
+.B dhcpd.conf (5)
+for explanations about what these attributes mean):
+.PP
+.B name \fIdata\fR examine
+.RS 0.5i
+Indicates the name of the failover peer relationship, as described in
+the server's \fBdhcpd.conf\fR file.
+.RE
+.PP
+.B partner-address \fIdata\fR examine
+.RS 0.5i
+Indicates the failover partner's IP address.
+.RE
+.PP
+.B local-address \fIdata\fR examine
+.RS 0.5i
+Indicates the IP address that is being used by the DHCP server for
+this failover pair.
+.RE
+.PP
+.B partner-port \fIdata\fR examine
+.RS 0.5i
+Indicates the TCP port on which the failover partner is listening for
+failover protocol connections.
+.RE
+.PP
+.B local-port \fIdata\fR examine
+.RS 0.5i
+Indicates the TCP port on which the DHCP server is listening for
+failover protocol connections for this failover pair.
+.RE
+.PP
+.B max-outstanding-updates \fIinteger\fR examine
+.RS 0.5i
+Indicates the number of updates that can be outstanding and
+unacknowledged at any given time, in this failover relationship.
+.RE
+.PP
+.B mclt \fIinteger\fR examine
+.RS 0.5i
+Indicates the maximum client lead time in this failover relationship.
+.RE
+.PP
+.B load-balance-max-secs \fIinteger\fR examine
+.RS 0.5i
+Indicates the maximum value for the secs field in a client request
+before load balancing is bypassed.
+.RE
+.PP
+.B load-balance-hba \fIdata\fR examine
+.RS 0.5i
+Indicates the load balancing hash bucket array for this failover
+relationship.
+.RE
+.PP
+.B local-state \fIinteger\fR examine, modify
+.RS 0.5i
+Indicates the present state of the DHCP server in this failover
+relationship. Possible values for state are:
+.RE
+.RS 1i
+.PP
+.nf
+1 - partner down
+2 - normal
+3 - communications interrupted
+4 - resolution interrupted
+5 - potential conflict
+6 - recover
+7 - recover done
+8 - shutdown
+9 - paused
+10 - startup
+11 - recover wait
+.fi
+.RE
+.PP
+.RS 0.5i
+In general it is not a good idea to make changes to this state.
+However, in the case that the failover partner is known to be down, it
+can be useful to set the DHCP server's failover state to partner
+down. At this point the DHCP server will take over service of the
+failover partner's leases as soon as possible, and will give out
+normal leases, not leases that are restricted by MCLT. If you do put
+the DHCP server into the partner-down when the other DHCP server is
+not in the partner-down state, but is not reachable, IP address
+assignment conflicts are possible, even likely. Once a server has
+been put into partner-down mode, its failover partner must not be
+brought back online until communication is possible between the two
+servers.
+.RE
+.PP
+.B partner-state \fIinteger\fR examine
+.RS 0.5i
+Indicates the present state of the failover partner.
+.RE
+.PP
+.B local-stos \fIinteger\fR examine
+.RS 0.5i
+Indicates the time at which the DHCP server entered its present state
+in this failover relationship.
+.RE
+.PP
+.B partner-stos \fIinteger\fR examine
+.RS 0.5i
+Indicates the time at which the failover partner entered its present state.
+.RE
+.PP
+.B hierarchy \fIinteger\fR examine
+.RS 0.5i
+Indicates whether the DHCP server is primary (0) or secondary (1) in
+this failover relationship.
+.RE
+.PP
+.B last-packet-sent \fIinteger\fR examine
+.RS 0.5i
+Indicates the time at which the most recent failover packet was sent
+by this DHCP server to its failover partner.
+.RE
+.PP
+.B last-timestamp-received \fIinteger\fR examine
+.RS 0.5i
+Indicates the timestamp that was on the failover message most recently
+received from the failover partner.
+.RE
+.PP
+.B skew \fIinteger\fR examine
+.RS 0.5i
+Indicates the skew between the failover partner's clock and this DHCP
+server's clock
+.RE
+.PP
+.B max-response-delay \fIinteger\fR examine
+.RS 0.5i
+Indicates the time in seconds after which, if no message is received
+from the failover partner, the partner is assumed to be out of
+communication.
+.RE
+.PP
+.B cur-unacked-updates \fIinteger\fR examine
+.RS 0.5i
+Indicates the number of update messages that have been received from
+the failover partner but not yet processed.
+.RE
.SH FILES
.B ETCDIR/dhcpd.conf, DBDIR/dhcpd.leases, RUNDIR/dhcpd.pid,
.B DBDIR/dhcpd.leases~.
#ifndef lint
static char copyright[] =
-"$Id: failover.c,v 1.55 2001/06/27 00:31:12 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n";
+"$Id: failover.c,v 1.56 2001/06/29 18:34:57 mellon Exp $ Copyright (c) 1999-2001 The Internet Software Consortium. All rights reserved.\n";
#endif /* not lint */
#include "dhcpd.h"
to establish a connection with it. */
status = dhcp_failover_link_initiate ((omapi_object_t *)state);
if (status != ISC_R_SUCCESS && status != ISC_R_INCOMPLETE) {
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +90 dhcp_failover_reconnect");
+#endif
add_timeout (cur_time + 90,
dhcp_failover_reconnect, state,
(tvref_t)
status = (dhcp_failover_listen
((omapi_object_t *)state));
if (status != ISC_R_SUCCESS) {
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +90 %s",
+ "dhcp_failover_listener_restart");
+#endif
add_timeout (cur_time + 90,
dhcp_failover_listener_restart,
state,
status = ISC_R_SUCCESS;
/* Allow the peer fifteen seconds to send us a
startup message. */
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +15 %s",
+ "dhcp_failover_link_startup_timeout");
+#endif
add_timeout (cur_time + 15,
dhcp_failover_link_startup_timeout,
link,
name);
/* Start trying to reconnect. */
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +5 %s",
+ "dhcp_failover_reconnect");
+#endif
add_timeout (cur_time + 5, dhcp_failover_reconnect,
state,
(tvref_t)dhcp_failover_state_reference,
dhcp_failover_link_dereference (&state -> link_to_peer, MDL);
dhcp_failover_state_transition (state, "disconnect");
- if (state -> i_am == primary)
+ if (state -> i_am == primary) {
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +90 %s",
+ "dhcp_failover_reconnect");
+#endif
add_timeout (cur_time + 90, dhcp_failover_reconnect,
state,
(tvref_t)dhcp_failover_state_reference,
(tvunref_t)
dhcp_failover_state_dereference);
+ }
} else if (!strcmp (name, "message")) {
link = va_arg (ap, dhcp_failover_link_t *);
if (link -> imsg -> options_present & FTB_RECEIVE_TIMER)
state -> partner.max_response_delay =
link -> imsg -> receive_timer;
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +%d %s",
+ (int)state -> partner.max_response_delay / 3,
+ "dhcp_failover_send_contact");
+#endif
add_timeout (cur_time +
(int)state -> partner.max_response_delay / 3,
dhcp_failover_send_contact, state,
(tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference);
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +%d %s",
+ (int)state -> me.max_response_delay,
+ "dhcp_failover_timeout");
+#endif
add_timeout (cur_time +
(int)state -> me.max_response_delay,
dhcp_failover_timeout, state,
if (state -> link_to_peer &&
state -> link_to_peer == link &&
state -> link_to_peer -> state != dhcp_flink_disconnected)
+ {
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +%d %s",
+ (int)state -> me.max_response_delay,
+ "dhcp_failover_timeout");
+#endif
add_timeout (cur_time +
(int)state -> me.max_response_delay,
dhcp_failover_timeout, state,
(tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference);
+ }
}
/* Handle all the events we care about... */
break;
case startup:
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +15 %s",
+ "dhcp_failover_startup_timeout");
+#endif
add_timeout (cur_time + 15,
dhcp_failover_startup_timeout,
state,
/* If we come back in recover_wait and there's still waiting
to do, set a timeout. */
case recover_wait:
- if (state -> me.stos + state -> mclt > cur_time)
+ if (state -> me.stos + state -> mclt > cur_time) {
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +%d %s",
+ (int)(cur_time -
+ state -> me.stos + state -> mclt),
+ "dhcp_failover_startup_timeout");
+#endif
add_timeout ((int)(state -> me.stos + state -> mclt),
dhcp_failover_recover_done,
state,
(tvref_t)omapi_object_reference,
(tvunref_t)
omapi_object_dereference);
- else
+ } else
dhcp_failover_recover_done (state);
break;
state -> me.stos + state -> mclt) {
p -> next_event_time =
state -> me.stos + state -> mclt;
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +%d %s",
+ (int)(cur_time - p -> next_event_time),
+ "pool_timer");
+#endif
add_timeout (p -> next_event_time, pool_timer, p,
(tvref_t)pool_reference,
(tvunref_t)pool_dereference);
void dhcp_failover_toack_queue_timeout (void *vs)
{
dhcp_failover_state_t *state = vs;
+
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("dhcp_failover_toack_queue_timeout");
+#endif
+
dhcp_failover_send_acks (state);
}
/* Schedule a timeout to flush the ack queue. */
if (state -> pending_acks > 0) {
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +2 %s",
+ "dhcp_failover_toack_queue_timeout");
+#endif
add_timeout (cur_time + 2,
dhcp_failover_toack_queue_timeout, state,
(tvref_t)dhcp_failover_state_reference,
dhcp_failover_state_t *state = vs;
isc_result_t status;
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("dhcp_failover_reconnect");
+#endif
/* If we already connected the other way, let the connection
recovery code initiate any retry that may be required. */
if (state -> link_to_peer)
if (status != ISC_R_SUCCESS && status != ISC_R_INCOMPLETE) {
log_info ("failover peer %s: %s", state -> name,
isc_result_totext (status));
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +90 %s",
+ "dhcp_failover_listener_restart");
+#endif
add_timeout (cur_time + 90,
dhcp_failover_listener_restart, state,
(tvref_t)dhcp_failover_state_reference,
dhcp_failover_state_t *state = vs;
isc_result_t status;
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("dhcp_failover_startup_timeout");
+#endif
+
dhcp_failover_state_transition (state, "disconnect");
}
dhcp_failover_state_t *state = vs;
isc_result_t status;
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("dhcp_failover_listener_restart");
+#endif
+
status = dhcp_failover_listen ((omapi_object_t *)state);
if (status != ISC_R_SUCCESS) {
log_info ("failover peer %s: %s", state -> name,
isc_result_totext (status));
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +90 %s",
+ "dhcp_failover_listener_restart");
+#endif
add_timeout (cur_time + 90,
dhcp_failover_listener_restart, state,
(tvref_t)dhcp_failover_state_reference,
}
if (link -> state_object &&
link -> state_object -> link_to_peer == link) {
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +%d %s",
+ (int)(link -> state_object ->
+ partner.max_response_delay) / 3,
+ "dhcp_failover_send_contact");
+#endif
add_timeout (cur_time +
(int)(link -> state_object ->
partner.max_response_delay) / 3,
dhcp_failover_link_t *link;
isc_result_t status;
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("dhcp_failover_timeout");
+#endif
+
if (!state || state -> type != dhcp_type_failover_state)
return;
link = state -> link_to_peer;
# define FMA (char *)0, (unsigned *)0, 0
#endif
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("dhcp_failover_send_contact");
+#endif
+
if (!state || state -> type != dhcp_type_failover_state)
return;
link = state -> link_to_peer;
state -> partner.state != recover &&
state -> partner.state != recover_done) {
dhcp_failover_set_state (state, recover_wait);
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("add_timeout +%d %s",
+ (int)(cur_time -
+ state -> me.stos + state -> mclt),
+ "dhcp_failover_recover_done");
+#endif
add_timeout ((int)(state -> me.stos + state -> mclt),
dhcp_failover_recover_done,
state,
{
dhcp_failover_state_t *state = sp;
+#if defined (DEBUG_FAILOVER_TIMING)
+ log_info ("dhcp_failover_recover_done");
+#endif
+
dhcp_failover_set_state (state, recover_done);
}