Skip to content

Commit 698e4c5

Browse files
leonidcktdreyer
authored andcommitted
mon/NVMeofGw*:
fix issue that GW was down when last subsystem was deleted Signed-off-by: Leonid Chernin <leonidc@il.ibm.com> Resolves: rhbz#2301460
1 parent cc2d70c commit 698e4c5

4 files changed

Lines changed: 100 additions & 8 deletions

File tree

src/mon/NVMeofGwMap.cc

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,30 @@ void NVMeofGwMap::track_deleting_gws(const NvmeGroupKey& group_key,
247247
}
248248
}
249249

250+
int NVMeofGwMap::process_gw_map_gw_no_subsystems(
251+
const NvmeGwId &gw_id, const NvmeGroupKey& group_key, bool &propose_pending)
252+
{
253+
int rc = 0;
254+
auto& gws_states = created_gws[group_key];
255+
auto gw_state = gws_states.find(gw_id);
256+
if (gw_state != gws_states.end()) {
257+
dout(10) << "GW- no subsystems configured " << gw_id << dendl;
258+
auto& st = gw_state->second;
259+
st.availability = gw_availability_t::GW_CREATED;
260+
for (auto& state_itr: created_gws[group_key][gw_id].sm_state) {
261+
fsm_handle_gw_no_subsystems(
262+
gw_id, group_key, state_itr.second,state_itr.first, propose_pending);
263+
}
264+
propose_pending = true; // map should reflect that gw becames Created
265+
if (propose_pending) validate_gw_map(group_key);
266+
} else {
267+
dout(1) << __FUNCTION__ << "ERROR GW-id was not found in the map "
268+
<< gw_id << dendl;
269+
rc = -EINVAL;
270+
}
271+
return rc;
272+
}
273+
250274
int NVMeofGwMap::process_gw_map_gw_down(
251275
const NvmeGwId &gw_id, const NvmeGroupKey& group_key, bool &propose_pending)
252276
{
@@ -263,7 +287,7 @@ int NVMeofGwMap::process_gw_map_gw_down(
263287
state_itr.first, propose_pending);
264288
state_itr.second = gw_states_per_group_t::GW_STANDBY_STATE;
265289
}
266-
propose_pending = true; // map should reflect that gw becames unavailable
290+
propose_pending = true; // map should reflect that gw becames Unavailable
267291
if (propose_pending) validate_gw_map(group_key);
268292
} else {
269293
dout(1) << __FUNCTION__ << "ERROR GW-id was not found in the map "
@@ -615,6 +639,59 @@ void NVMeofGwMap::fsm_handle_gw_alive(
615639
}
616640
}
617641

642+
void NVMeofGwMap::fsm_handle_gw_no_subsystems(
643+
const NvmeGwId &gw_id, const NvmeGroupKey& group_key,
644+
gw_states_per_group_t state, NvmeAnaGrpId grpid, bool &map_modified)
645+
{
646+
switch (state) {
647+
case gw_states_per_group_t::GW_STANDBY_STATE:
648+
case gw_states_per_group_t::GW_IDLE_STATE:
649+
// nothing to do
650+
break;
651+
652+
case gw_states_per_group_t::GW_WAIT_BLOCKLIST_CMPL:
653+
{
654+
cancel_timer(gw_id, group_key, grpid);
655+
auto& gw_st = created_gws[group_key][gw_id];
656+
gw_st.standby_state(grpid);
657+
map_modified = true;
658+
}
659+
break;
660+
661+
case gw_states_per_group_t::GW_WAIT_FAILBACK_PREPARED:
662+
cancel_timer(gw_id, group_key, grpid);
663+
map_modified = true;
664+
for (auto& gw_st: created_gws[group_key]) {
665+
auto& st = gw_st.second;
666+
// found GW that was intended for Failback for this ana grp
667+
if (st.sm_state[grpid] ==
668+
gw_states_per_group_t::GW_OWNER_WAIT_FAILBACK_PREPARED) {
669+
dout(4) << "Warning: Outgoing Failback when GW is without subsystems"
670+
<< " - to rollback it" <<" GW " << gw_id << "for ANA Group "
671+
<< grpid << dendl;
672+
st.standby_state(grpid);
673+
break;
674+
}
675+
}
676+
break;
677+
678+
case gw_states_per_group_t::GW_OWNER_WAIT_FAILBACK_PREPARED:
679+
case gw_states_per_group_t::GW_ACTIVE_STATE:
680+
{
681+
dout(4) << "Set state to Standby for GW " << gw_id << " group "
682+
<< grpid << dendl;
683+
auto& gw_st = created_gws[group_key][gw_id];
684+
gw_st.standby_state(grpid);
685+
}
686+
break;
687+
688+
default:
689+
{
690+
dout(4) << "Error : Invalid state " << state << "for GW " << gw_id << dendl;
691+
}
692+
}
693+
}
694+
618695
void NVMeofGwMap::fsm_handle_gw_down(
619696
const NvmeGwId &gw_id, const NvmeGroupKey& group_key,
620697
gw_states_per_group_t state, NvmeAnaGrpId grpid, bool &map_modified)

src/mon/NVMeofGwMap.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ class NVMeofGwMap
5454
int process_gw_map_gw_down(
5555
const NvmeGwId &gw_id, const NvmeGroupKey& group_key,
5656
bool &propose_pending);
57+
int process_gw_map_gw_no_subsystems(
58+
const NvmeGwId &gw_id, const NvmeGroupKey& group_key,
59+
bool &propose_pending);
5760
void update_active_timers(bool &propose_pending);
5861
void handle_abandoned_ana_groups(bool &propose_pending);
5962
void handle_removed_subsystems(
@@ -77,6 +80,9 @@ class NVMeofGwMap
7780
void fsm_handle_gw_down(
7881
const NvmeGwId &gw_id, const NvmeGroupKey& group_key,
7982
gw_states_per_group_t state, NvmeAnaGrpId grpid, bool &map_modified);
83+
void fsm_handle_gw_no_subsystems(
84+
const NvmeGwId &gw_id, const NvmeGroupKey& group_key,
85+
gw_states_per_group_t state, NvmeAnaGrpId grpid, bool &map_modified);
8086
void fsm_handle_gw_delete(
8187
const NvmeGwId &gw_id, const NvmeGroupKey& group_key,
8288
gw_states_per_group_t state, NvmeAnaGrpId grpid, bool &map_modified);

src/mon/NVMeofGwMon.cc

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,8 @@ bool NVMeofGwMon::prepare_command(MonOpRequestRef op)
432432
if (rc == 0) {
433433
bool propose = false;
434434
// Simulate immediate Failover of this GW
435-
process_gw_down(id, group_key, propose);
435+
process_gw_down(id, group_key, propose,
436+
gw_availability_t::GW_UNAVAILABLE);
436437
} else if (rc == -EINVAL) {
437438
dout (4) << "Error: GW not found in the database " << id << " "
438439
<< pool << " " << group << " rc " << rc << dendl;
@@ -462,13 +463,19 @@ bool NVMeofGwMon::prepare_command(MonOpRequestRef op)
462463
}
463464

464465
void NVMeofGwMon::process_gw_down(const NvmeGwId &gw_id,
465-
const NvmeGroupKey& group_key, bool &propose_pending)
466+
const NvmeGroupKey& group_key, bool &propose_pending,
467+
gw_availability_t avail)
466468
{
467469
LastBeacon lb = {gw_id, group_key};
468470
auto it = last_beacon.find(lb);
469471
if (it != last_beacon.end()) {
470472
last_beacon.erase(it);
471-
pending_map.process_gw_map_gw_down(gw_id, group_key, propose_pending);
473+
if (avail == gw_availability_t::GW_UNAVAILABLE) {
474+
pending_map.process_gw_map_gw_down(gw_id, group_key, propose_pending);
475+
} else {
476+
pending_map.process_gw_map_gw_no_subsystems(gw_id, group_key, propose_pending);
477+
}
478+
472479
}
473480
}
474481

@@ -581,7 +588,7 @@ bool NVMeofGwMon::prepare_beacon(MonOpRequestRef op)
581588
}
582589

583590
if (sub.size() == 0) {
584-
avail = gw_availability_t::GW_UNAVAILABLE;
591+
avail = gw_availability_t::GW_CREATED;
585592
}
586593
if (pending_map.created_gws[group_key][gw_id].subsystems != sub) {
587594
dout(10) << "subsystems of GW changed, propose pending " << gw_id << dendl;
@@ -607,8 +614,9 @@ bool NVMeofGwMon::prepare_beacon(MonOpRequestRef op)
607614
epoch_t last_osd_epoch = m->get_last_osd_epoch();
608615
pending_map.process_gw_map_ka(gw_id, group_key, last_osd_epoch, propose);
609616
// state set by GW client application
610-
} else if (avail == gw_availability_t::GW_UNAVAILABLE) {
611-
process_gw_down(gw_id, group_key, propose);
617+
} else if (avail == gw_availability_t::GW_UNAVAILABLE ||
618+
avail == gw_availability_t::GW_CREATED) {
619+
process_gw_down(gw_id, group_key, propose, avail);
612620
}
613621
// Periodic: check active FSM timers
614622
pending_map.update_active_timers(timer_propose);

src/mon/NVMeofGwMon.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ class NVMeofGwMon: public PaxosService,
8585
private:
8686
void synchronize_last_beacon();
8787
void process_gw_down(const NvmeGwId &gw_id,
88-
const NvmeGroupKey& group_key, bool &propose_pending);
88+
const NvmeGroupKey& group_key, bool &propose_pending,
89+
gw_availability_t avail);
8990
};
9091

9192
#endif /* MON_NVMEGWMONITOR_H_ */

0 commit comments

Comments
 (0)