Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions src/link_manager/LinkManagerStateMachineActiveActive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ void ActiveActiveStateMachine::handleMuxStateNotification(mux_state::MuxState::L
MUXLOGWARNING(boost::format("%s: state db mux state: %s") % mMuxPortConfig.getPortName() % mMuxStateName[label]);

mWaitTimer.cancel();
mLastMuxStateNotification = label;

if (mComponentInitState.all()) {
if (mMuxStateMachine.getWaitStateCause() != mux_state::WaitState::WaitStateCause::SwssUpdate) {
Expand Down Expand Up @@ -543,6 +544,15 @@ void ActiveActiveStateMachine::initializeTransitionFunctionTable()
boost::placeholders::_1
);

mStateTransitionHandler[link_prober::LinkProberState::Label::Unknown]
[mux_state::MuxState::Label::Standby]
[link_state::LinkState::Label::Up] =
boost::bind(
&ActiveActiveStateMachine::LinkProberUnknownMuxStandbyLinkUpTransitionFunction,
this,
boost::placeholders::_1
);

mStateTransitionHandler[link_prober::LinkProberState::Label::Active]
[mux_state::MuxState::Label::Unknown]
[link_state::LinkState::Label::Up] =
Expand Down Expand Up @@ -621,9 +631,29 @@ void ActiveActiveStateMachine::LinkProberActiveMuxStandbyLinkUpTransitionFunctio
void ActiveActiveStateMachine::LinkProberUnknownMuxActiveLinkUpTransitionFunction(CompositeState &nextState)
{
MUXLOGINFO(mMuxPortConfig.getPortName());
switchMuxState(nextState, mux_state::MuxState::Label::Standby);
if (mMuxPortConfig.getMode() == common::MuxPortConfig::Mode::Active && mLastMuxStateNotification != mux_state::MuxState::Label::Active) {
// last switch mux state to active failed, try again
switchMuxState(nextState, mux_state::MuxState::Label::Active, true);
} else {
switchMuxState(nextState, mux_state::MuxState::Label::Standby);
}
}

//
// ---> LinkProberUnknownMuxStandbyLinkUpTransitionFunction(CompositeState &nextState);
//
// transition function when entering {LinkProberUnknown, MuxStandby, LinkUp} state
//
void ActiveActiveStateMachine::LinkProberUnknownMuxStandbyLinkUpTransitionFunction(CompositeState &nextState)
{
MUXLOGINFO(mMuxPortConfig.getPortName());
if (mMuxPortConfig.getMode() == common::MuxPortConfig::Mode::Active && mLastMuxStateNotification != mux_state::MuxState::Label::Active) {
// last switch mux state to active failed, try again
switchMuxState(nextState, mux_state::MuxState::Label::Active, true);
}
}


//
// ---> LinkProberActiveMuxUnknownLinkUpTransitionFunction(CompositeState &nextState);
//
Expand Down Expand Up @@ -781,10 +811,12 @@ void ActiveActiveStateMachine::enterPeerLinkProberState(link_prober::LinkProberS
//
void ActiveActiveStateMachine::switchMuxState(
CompositeState &nextState,
mux_state::MuxState::Label label
mux_state::MuxState::Label label,
bool forceSwitch
)
{
if (mMuxPortConfig.getMode() == common::MuxPortConfig::Mode::Auto ||
if (forceSwitch ||
mMuxPortConfig.getMode() == common::MuxPortConfig::Mode::Auto ||
mMuxPortConfig.getMode() == common::MuxPortConfig::Mode::Detached) {
MUXLOGWARNING(
boost::format("%s: Switching MUX state to '%s'") %
Expand Down
27 changes: 19 additions & 8 deletions src/link_manager/LinkManagerStateMachineActiveActive.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,15 +150,15 @@ class ActiveActiveStateMachine : public LinkManagerStateMachineBase,

/**
* @method handleDefaultRouteStateNotification(const DefaultRoute routeState)
*
*
* @brief handle default route state notification from routeorch
*
*
* @param routeState
*
*
* @return none
*/
*/
void handleDefaultRouteStateNotification(const DefaultRoute routeState) override;

/**
*@method handleGetServerMacNotification
*
Expand Down Expand Up @@ -272,6 +272,15 @@ class ActiveActiveStateMachine : public LinkManagerStateMachineBase,
*/
void LinkProberUnknownMuxActiveLinkUpTransitionFunction(CompositeState &nextState);

/**
* @method LinkProberUnknownMuxStandbyLinkUpTransitionFunction
*
* @brief transition function when entering {LinkProberUnknown, MuxStandby, LinkUp} state
*
* @param nextState reference to composite state
*/
void LinkProberUnknownMuxStandbyLinkUpTransitionFunction(CompositeState &nextState);

/**
* @method LinkProberUnknownMuxUnknownLinkUpTransitionFunction
*
Expand Down Expand Up @@ -374,8 +383,9 @@ class ActiveActiveStateMachine : public LinkManagerStateMachineBase,
*
* @param nextState reference to composite state
* @param label new MuxState label to switch to
* @param forceSwitch force switch mux state, used to match the driver state only
*/
inline void switchMuxState(CompositeState &nextState, mux_state::MuxState::Label label);
inline void switchMuxState(CompositeState &nextState, mux_state::MuxState::Label label, bool forceSwitch = false);

/**
* @method switchPeerMuxState
Expand Down Expand Up @@ -467,9 +477,9 @@ class ActiveActiveStateMachine : public LinkManagerStateMachineBase,

/**
* @method shutdownOrRestartLinkProberOnDefaultRoute()
*
*
* @brief shutdown or restart link prober based on default route state
*
*
* @return none
*/
void shutdownOrRestartLinkProberOnDefaultRoute() override;
Expand Down Expand Up @@ -558,6 +568,7 @@ class ActiveActiveStateMachine : public LinkManagerStateMachineBase,
private: // peer link prober state and mux state
link_prober::LinkProberState::Label mPeerLinkProberState = link_prober::LinkProberState::Label::PeerWait;
mux_state::MuxState::Label mPeerMuxState = mux_state::MuxState::Label::Wait;
mux_state::MuxState::Label mLastMuxStateNotification = mux_state::MuxState::Label::Unknown;

private:
uint32_t mMuxProbeBackoffFactor = 1;
Expand Down
72 changes: 72 additions & 0 deletions test/LinkManagerStateMachineActiveActiveTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -496,4 +496,76 @@ TEST_F(LinkManagerStateMachineActiveActiveTest, LinkmgrdBootupSequenceHeartBeatF
EXPECT_EQ(mDbInterfacePtr->mLastSetMuxState, mux_state::MuxState::Label::Active);
}

TEST_F(LinkManagerStateMachineActiveActiveTest, LinkmgrdBootupSequenceMuxConfigActiveProbeActive)
{
activateStateMachine();
VALIDATE_STATE(Wait, Wait, Down);

postLinkEvent(link_state::LinkState::Up);
VALIDATE_STATE(Wait, Wait, Up);

postLinkProberEvent(link_prober::LinkProberState::Unknown, 3);
VALIDATE_STATE(Unknown, Standby, Up);
EXPECT_EQ(mDbInterfacePtr->mSetMuxStateInvokeCount, 1);
EXPECT_EQ(mDbInterfacePtr->mLastSetMuxState, mux_state::MuxState::Label::Standby);

handleMuxState("unknown", 3);
VALIDATE_STATE(Unknown, Unknown, Up);

handleMuxConfig("active", 1);
VALIDATE_STATE(Unknown, Active, Up);
EXPECT_EQ(mDbInterfacePtr->mSetMuxStateInvokeCount, 2);
EXPECT_EQ(mDbInterfacePtr->mLastSetMuxState, mux_state::MuxState::Label::Active);

handleMuxState("unknown", 5);
VALIDATE_STATE(Unknown, Unknown, Up);

handleProbeMuxState("unknown", 3);
VALIDATE_STATE(Unknown, Unknown, Up);

// xcvrd now answers the mux probe
handleProbeMuxState("active", 3);
VALIDATE_STATE(Unknown, Active, Up);
EXPECT_EQ(mDbInterfacePtr->mSetMuxStateInvokeCount, 3);
EXPECT_EQ(mDbInterfacePtr->mLastSetMuxState, mux_state::MuxState::Label::Active);

handleMuxState("active", 3);
VALIDATE_STATE(Unknown, Active, Up);
}

TEST_F(LinkManagerStateMachineActiveActiveTest, LinkmgrdBootupSequenceMuxConfigActiveProbeStandby)
{
activateStateMachine();
VALIDATE_STATE(Wait, Wait, Down);

postLinkEvent(link_state::LinkState::Up);
VALIDATE_STATE(Wait, Wait, Up);

postLinkProberEvent(link_prober::LinkProberState::Unknown, 3);
VALIDATE_STATE(Unknown, Standby, Up);
EXPECT_EQ(mDbInterfacePtr->mSetMuxStateInvokeCount, 1);
EXPECT_EQ(mDbInterfacePtr->mLastSetMuxState, mux_state::MuxState::Label::Standby);

handleMuxState("unknown", 3);
VALIDATE_STATE(Unknown, Unknown, Up);

handleMuxConfig("active", 1);
VALIDATE_STATE(Unknown, Active, Up);
EXPECT_EQ(mDbInterfacePtr->mSetMuxStateInvokeCount, 2);
EXPECT_EQ(mDbInterfacePtr->mLastSetMuxState, mux_state::MuxState::Label::Active);

handleMuxState("unknown", 5);
VALIDATE_STATE(Unknown, Unknown, Up);

handleProbeMuxState("unknown", 3);
VALIDATE_STATE(Unknown, Unknown, Up);

// xcvrd now answers the mux probe
handleProbeMuxState("standby", 3);
EXPECT_EQ(mDbInterfacePtr->mSetMuxStateInvokeCount, 3);
EXPECT_EQ(mDbInterfacePtr->mLastSetMuxState, mux_state::MuxState::Label::Active);
handleMuxState("active", 3);
VALIDATE_STATE(Unknown, Active, Up);
}

} /* namespace test */