} else if (shouldTerminate()) {
verboseTransition(HA_TERMINATED_ST);
+ } else if (isPartnerStateInvalid()) {
+ verboseTransition(HA_WAITING_ST);
+
} else {
// Transitions based on the partner's state.
return;
}
+ // Check if the partner state is valid per current configuration. If it is
+ // in an invalid state let's transition to the waiting state and stay there
+ // until the configuration is corrected.
+ if (isPartnerStateInvalid()) {
+ verboseTransition(HA_WAITING_ST);
+ return;
+ }
+
switch (communication_state_->getPartnerState()) {
case HA_IN_MAINTENANCE_ST:
verboseTransition(HA_PARTNER_IN_MAINTENANCE_ST);
return;
}
+ // Check if the partner state is valid per current configuration. If it is
+ // in an invalid state let's transition to the waiting state and stay there
+ // until the configuration is corrected.
+ if (isPartnerStateInvalid()) {
+ verboseTransition(HA_WAITING_ST);
+ return;
+ }
+
switch (communication_state_->getPartnerState()) {
case HA_HOT_STANDBY_ST:
case HA_LOAD_BALANCING_ST:
return;
}
+ // Check if the partner state is valid per current configuration. If it is
+ // in an invalid state let's transition to the waiting state and stay there
+ // until the configuration is corrected.
+ if (isPartnerStateInvalid()) {
+ verboseTransition(HA_WAITING_ST);
+ return;
+ }
+
switch (communication_state_->getPartnerState()) {
case HA_HOT_STANDBY_ST:
case HA_LOAD_BALANCING_ST:
return;
}
+ // Check if the partner state is valid per current configuration. If it is
+ // in an invalid state let's transition to the waiting state and stay there
+ // until the configuration is corrected.
+ if (isPartnerStateInvalid()) {
+ verboseTransition(HA_WAITING_ST);
+ return;
+ }
+
// We don't want to perform synchronous attempt to synchronize with
// a partner until we know that the partner is responding. Therefore,
// we wait for the heartbeat to complete successfully before we
return;
}
+ // Check if the partner state is valid per current configuration. If it is
+ // in an invalid state let's sit in the waiting state until the configuration
+ // is corrected.
+ if (isPartnerStateInvalid()) {
+ postNextEvent(NOP_EVT);
+ return;
+ }
+
switch (communication_state_->getPartnerState()) {
case HA_COMMUNICATION_RECOVERY_ST:
case HA_HOT_STANDBY_ST:
return (getLastEvent() == HA_MAINTENANCE_CANCEL_EVT);
}
+bool
+HAService::isPartnerStateInvalid() const {
+ switch (communication_state_->getPartnerState()) {
+ case HA_COMMUNICATION_RECOVERY_ST:
+ if (config_->getHAMode() != HAConfig::LOAD_BALANCING) {
+ LOG_WARN(ha_logger, HA_INVALID_PARTNER_STATE_COMMUNICATION_RECOVERY);
+ return (true);
+ }
+ break;
+
+ case HA_HOT_STANDBY_ST:
+ if (config_->getHAMode() != HAConfig::HOT_STANDBY) {
+ LOG_WARN(ha_logger, HA_INVALID_PARTNER_STATE_HOT_STANDBY);
+ return (true);
+ }
+ break;
+
+ case HA_LOAD_BALANCING_ST:
+ if (config_->getHAMode() != HAConfig::LOAD_BALANCING) {
+ LOG_WARN(ha_logger, HA_INVALID_PARTNER_STATE_LOAD_BALANCING);
+ return (true);
+ }
+ break;
+
+ default:
+ ;
+ }
+ return (false);
+}
+
size_t
HAService::asyncSendLeaseUpdates(const dhcp::Pkt4Ptr& query,
const dhcp::Lease4CollectionPtr& leases,
testTransition(MyState(HA_COMMUNICATION_RECOVERY_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_LOAD_BALANCING_ST));
+ testTransition(MyState(HA_COMMUNICATION_RECOVERY_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_COMMUNICATION_RECOVERY_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_LOAD_BALANCING_ST));
testTransition(MyState(HA_LOAD_BALANCING_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_LOAD_BALANCING_ST));
+ testTransition(MyState(HA_LOAD_BALANCING_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_LOAD_BALANCING_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_LOAD_BALANCING_ST));
testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_IN_MAINTENANCE_ST));
+ testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_IN_MAINTENANCE_ST));
+
testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_IN_MAINTENANCE_ST));
testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_WAITING_ST));
+ testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_WAITING_ST));
testTransition(MyState(HA_PARTNER_IN_MAINTENANCE_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
+ testTransition(MyState(HA_PARTNER_IN_MAINTENANCE_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
+
testTransition(MyState(HA_PARTNER_IN_MAINTENANCE_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
testTransition(MyState(HA_READY_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_LOAD_BALANCING_ST));
+ testTransition(MyState(HA_READY_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_READY_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_LOAD_BALANCING_ST));
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_SYNCING_ST));
+ testTransition(MyState(HA_WAITING_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_SYNCING_ST));
testTransition(MyState(HA_COMMUNICATION_RECOVERY_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_LOAD_BALANCING_ST));
+ testTransition(MyState(HA_COMMUNICATION_RECOVERY_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_COMMUNICATION_RECOVERY_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_LOAD_BALANCING_ST));
testTransition(MyState(HA_LOAD_BALANCING_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_LOAD_BALANCING_ST));
+ testTransition(MyState(HA_LOAD_BALANCING_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_LOAD_BALANCING_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_LOAD_BALANCING_ST));
testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_IN_MAINTENANCE_ST));
+ testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_IN_MAINTENANCE_ST));
+
testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_IN_MAINTENANCE_ST));
testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_WAITING_ST));
+ testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_WAITING_ST));
testTransition(MyState(HA_PARTNER_IN_MAINTENANCE_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
+ testTransition(MyState(HA_PARTNER_IN_MAINTENANCE_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
+
testTransition(MyState(HA_PARTNER_IN_MAINTENANCE_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
testTransition(MyState(HA_READY_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_LOAD_BALANCING_ST));
+ testTransition(MyState(HA_READY_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_READY_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_LOAD_BALANCING_ST));
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_SYNCING_ST));
+ testTransition(MyState(HA_WAITING_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_SYNCING_ST));
SCOPED_TRACE("HOT STANDBY state transitions");
testTransition(MyState(HA_HOT_STANDBY_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
- FinalState(HA_HOT_STANDBY_ST));
+ FinalState(HA_WAITING_ST));
testTransition(MyState(HA_HOT_STANDBY_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_HOT_STANDBY_ST));
+ testTransition(MyState(HA_HOT_STANDBY_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_HOT_STANDBY_ST), PartnerState(HA_IN_MAINTENANCE_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_IN_MAINTENANCE_ST));
+ testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_IN_MAINTENANCE_ST));
+
testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_IN_MAINTENANCE_ST));
testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_WAITING_ST));
+ testTransition(MyState(HA_HOT_STANDBY_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_IN_MAINTENANCE_ST),
FinalState(HA_PARTNER_DOWN_ST));
testTransition(MyState(HA_PARTNER_IN_MAINTENANCE_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
+ testTransition(MyState(HA_PARTNER_IN_MAINTENANCE_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
+
testTransition(MyState(HA_PARTNER_IN_MAINTENANCE_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
SCOPED_TRACE("READY state transitions");
testTransition(MyState(HA_READY_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
- FinalState(HA_HOT_STANDBY_ST));
+ FinalState(HA_WAITING_ST));
testTransition(MyState(HA_READY_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_HOT_STANDBY_ST));
+ testTransition(MyState(HA_READY_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_READY_ST), PartnerState(HA_IN_MAINTENANCE_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
SCOPED_TRACE("WAITING state transitions");
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
- FinalState(HA_SYNCING_ST));
+ FinalState(HA_WAITING_ST));
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_SYNCING_ST));
+ testTransition(MyState(HA_WAITING_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_IN_MAINTENANCE_ST),
FinalState(HA_SYNCING_ST));
startService(valid_config);
- testTransition(MyState(HA_WAITING_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ testTransition(MyState(HA_WAITING_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_READY_ST));
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_PARTNER_DOWN_ST),
SCOPED_TRACE("HOT STANDBY state transitions");
testTransition(MyState(HA_HOT_STANDBY_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
- FinalState(HA_HOT_STANDBY_ST));
+ FinalState(HA_WAITING_ST));
testTransition(MyState(HA_HOT_STANDBY_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_HOT_STANDBY_ST));
+ testTransition(MyState(HA_HOT_STANDBY_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_HOT_STANDBY_ST), PartnerState(HA_IN_MAINTENANCE_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
FinalState(HA_IN_MAINTENANCE_ST));
+ testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_HOT_STANDBY_ST),
+ FinalState(HA_IN_MAINTENANCE_ST));
+
testTransition(MyState(HA_IN_MAINTENANCE_ST), PartnerState(HA_LOAD_BALANCING_ST),
FinalState(HA_IN_MAINTENANCE_ST));
testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_WAITING_ST));
+ testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_PARTNER_DOWN_ST), PartnerState(HA_IN_MAINTENANCE_ST),
FinalState(HA_PARTNER_DOWN_ST));
SCOPED_TRACE("READY state transitions");
testTransition(MyState(HA_READY_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
- FinalState(HA_HOT_STANDBY_ST));
+ FinalState(HA_WAITING_ST));
testTransition(MyState(HA_READY_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_HOT_STANDBY_ST));
+ testTransition(MyState(HA_READY_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_READY_ST), PartnerState(HA_IN_MAINTENANCE_ST),
FinalState(HA_PARTNER_IN_MAINTENANCE_ST));
SCOPED_TRACE("WAITING state transitions");
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_COMMUNICATION_RECOVERY_ST),
- FinalState(HA_SYNCING_ST));
+ FinalState(HA_WAITING_ST));
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_SYNCING_ST));
+ testTransition(MyState(HA_WAITING_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ FinalState(HA_WAITING_ST));
+
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_IN_MAINTENANCE_ST),
FinalState(HA_SYNCING_ST));
startService(valid_config);
- testTransition(MyState(HA_WAITING_ST), PartnerState(HA_LOAD_BALANCING_ST),
+ testTransition(MyState(HA_WAITING_ST), PartnerState(HA_HOT_STANDBY_ST),
FinalState(HA_READY_ST));
testTransition(MyState(HA_WAITING_ST), PartnerState(HA_PARTNER_DOWN_ST),