|
18 | 18 | #include <map> |
19 | 19 | #include <iostream> |
20 | 20 |
|
21 | | -using NvmeGwId = std::string; |
22 | | -using NvmeGroupKey = std::pair<std::string, std::string>; |
23 | | -using NvmeNqnId = std::string; |
24 | | -using NvmeAnaGrpId = uint32_t; |
| 21 | +using NvmeGwId = std::string; |
| 22 | +using NvmeGroupKey = std::pair<std::string, std::string>; |
| 23 | +using NvmeNqnId = std::string; |
| 24 | +using NvmeAnaGrpId = uint32_t; |
25 | 25 |
|
26 | 26 |
|
27 | 27 | enum class gw_states_per_group_t { |
28 | | - GW_IDLE_STATE = 0, //invalid state |
29 | | - GW_STANDBY_STATE, |
30 | | - GW_ACTIVE_STATE, |
31 | | - GW_OWNER_WAIT_FAILBACK_PREPARED, |
32 | | - GW_WAIT_FAILBACK_PREPARED, |
33 | | - GW_WAIT_BLOCKLIST_CMPL |
| 28 | + GW_IDLE_STATE = 0, //invalid state |
| 29 | + GW_STANDBY_STATE, |
| 30 | + GW_ACTIVE_STATE, |
| 31 | + GW_OWNER_WAIT_FAILBACK_PREPARED, |
| 32 | + GW_WAIT_FAILBACK_PREPARED, |
| 33 | + GW_WAIT_BLOCKLIST_CMPL |
34 | 34 | }; |
35 | 35 |
|
36 | 36 | enum class gw_exported_states_per_group_t { |
37 | | - GW_EXPORTED_OPTIMIZED_STATE = 0, |
38 | | - GW_EXPORTED_INACCESSIBLE_STATE |
| 37 | + GW_EXPORTED_OPTIMIZED_STATE = 0, |
| 38 | + GW_EXPORTED_INACCESSIBLE_STATE |
39 | 39 | }; |
40 | 40 |
|
41 | 41 | enum class gw_availability_t { |
42 | | - GW_CREATED = 0, |
43 | | - GW_AVAILABLE, |
44 | | - GW_UNAVAILABLE, |
45 | | - GW_DELETED |
| 42 | + GW_CREATED = 0, |
| 43 | + GW_AVAILABLE, |
| 44 | + GW_UNAVAILABLE, |
| 45 | + GW_DELETED |
46 | 46 | }; |
47 | 47 |
|
48 | 48 | #define REDUNDANT_GW_ANA_GROUP_ID 0xFF |
49 | | -using SmState = std::map < NvmeAnaGrpId, gw_states_per_group_t>; |
| 49 | +using SmState = std::map < NvmeAnaGrpId, gw_states_per_group_t>; |
50 | 50 |
|
51 | | -using ana_state_t = std::vector<std::pair<gw_exported_states_per_group_t, epoch_t>>; |
| 51 | +using ana_state_t = |
| 52 | + std::vector<std::pair<gw_exported_states_per_group_t, epoch_t>>; |
52 | 53 |
|
53 | 54 | struct BeaconNamespace { |
54 | | - NvmeAnaGrpId anagrpid; |
55 | | - std::string nonce; |
56 | | - |
57 | | - // Define the equality operator |
58 | | - bool operator==(const BeaconNamespace& other) const { |
59 | | - return anagrpid == other.anagrpid && |
60 | | - nonce == other.nonce; |
61 | | - } |
| 55 | + NvmeAnaGrpId anagrpid; |
| 56 | + std::string nonce; |
| 57 | + |
| 58 | + // Define the equality operator |
| 59 | + bool operator==(const BeaconNamespace& other) const { |
| 60 | + return anagrpid == other.anagrpid && |
| 61 | + nonce == other.nonce; |
| 62 | + } |
62 | 63 | }; |
63 | 64 |
|
64 | 65 | // Beacon Listener represents an NVME Subsystem listener, |
65 | 66 | // which generally does not have to use TCP/IP. |
66 | 67 | // It is derived from the SPDK listener JSON RPC representation. |
67 | | -// For more details, see https://spdk.io/doc/jsonrpc.html#rpc_nvmf_listen_address. |
| 68 | +// For more details, see |
| 69 | +// https://spdk.io/doc/jsonrpc.html#rpc_nvmf_listen_address. |
68 | 70 | struct BeaconListener { |
69 | | - std::string address_family; // IPv4 or IPv6 |
70 | | - std::string address; // |
71 | | - std::string svcid; // port |
72 | | - |
73 | | - // Define the equality operator |
74 | | - bool operator==(const BeaconListener& other) const { |
75 | | - return address_family == other.address_family && |
76 | | - address == other.address && |
77 | | - svcid == other.svcid; |
78 | | - } |
| 71 | + std::string address_family; // IPv4 or IPv6 |
| 72 | + std::string address; // |
| 73 | + std::string svcid; // port |
| 74 | + |
| 75 | + // Define the equality operator |
| 76 | + bool operator==(const BeaconListener& other) const { |
| 77 | + return address_family == other.address_family && |
| 78 | + address == other.address && |
| 79 | + svcid == other.svcid; |
| 80 | + } |
79 | 81 | }; |
80 | 82 |
|
81 | 83 | struct BeaconSubsystem { |
82 | | - NvmeNqnId nqn; |
83 | | - std::list<BeaconListener> listeners; |
84 | | - std::list<BeaconNamespace> namespaces; |
85 | | - |
86 | | - // Define the equality operator |
87 | | - bool operator==(const BeaconSubsystem& other) const { |
88 | | - return nqn == other.nqn && |
89 | | - listeners == other.listeners && |
90 | | - namespaces == other.namespaces; |
91 | | - } |
| 84 | + NvmeNqnId nqn; |
| 85 | + std::list<BeaconListener> listeners; |
| 86 | + std::list<BeaconNamespace> namespaces; |
| 87 | + |
| 88 | + // Define the equality operator |
| 89 | + bool operator==(const BeaconSubsystem& other) const { |
| 90 | + return nqn == other.nqn && |
| 91 | + listeners == other.listeners && |
| 92 | + namespaces == other.namespaces; |
| 93 | + } |
92 | 94 | }; |
93 | 95 |
|
94 | 96 | using BeaconSubsystems = std::list<BeaconSubsystem>; |
95 | 97 |
|
96 | | -using NvmeNonceVector = std::vector<std::string>; |
97 | | -using NvmeAnaNonceMap = std::map <NvmeAnaGrpId, NvmeNonceVector>; |
| 98 | +using NvmeNonceVector = std::vector<std::string>; |
| 99 | +using NvmeAnaNonceMap = std::map <NvmeAnaGrpId, NvmeNonceVector>; |
98 | 100 |
|
99 | 101 | struct Blocklist_data{ |
100 | | - epoch_t osd_epoch; |
101 | | - bool is_failover; |
102 | | - Blocklist_data() { |
103 | | - osd_epoch = 0; |
104 | | - is_failover = true; |
105 | | - }; |
106 | | - Blocklist_data(epoch_t epoch, bool failover):osd_epoch(epoch), is_failover(failover) {}; |
| 102 | + epoch_t osd_epoch; |
| 103 | + bool is_failover; |
| 104 | + Blocklist_data() { |
| 105 | + osd_epoch = 0; |
| 106 | + is_failover = true; |
| 107 | + }; |
| 108 | + Blocklist_data(epoch_t epoch, bool failover) |
| 109 | + : osd_epoch(epoch), is_failover(failover) {}; |
107 | 110 | }; |
108 | 111 |
|
109 | | -using BlocklistData = std::map < NvmeAnaGrpId, Blocklist_data>; |
| 112 | +using BlocklistData = std::map<NvmeAnaGrpId, Blocklist_data>; |
110 | 113 |
|
111 | 114 | struct NvmeGwMonState { |
112 | | - NvmeAnaGrpId ana_grp_id; // ana-group-id allocated for this GW, GW owns this group-id |
113 | | - gw_availability_t availability; // in absence of beacon heartbeat messages it becomes inavailable |
114 | | - bool last_gw_map_epoch_valid; // "true" if the last epoch seen by the gw-client is up-to-date |
115 | | - bool performed_full_startup; // in order to identify gws that did not exit upon failover |
116 | | - BeaconSubsystems subsystems; // gateway susbsystem and their state machine states |
117 | | - NvmeAnaNonceMap nonce_map; |
118 | | - SmState sm_state; // state machine states per ANA group |
119 | | - BlocklistData blocklist_data; |
120 | | - |
121 | | - NvmeGwMonState(): ana_grp_id(REDUNDANT_GW_ANA_GROUP_ID) {}; |
122 | | - |
123 | | - NvmeGwMonState(NvmeAnaGrpId id): ana_grp_id(id), availability(gw_availability_t::GW_CREATED), last_gw_map_epoch_valid(false), |
124 | | - performed_full_startup(false) {}; |
125 | | - void set_unavailable_state() { |
126 | | - availability = gw_availability_t::GW_UNAVAILABLE; |
127 | | - performed_full_startup = false; // after setting this state the next time monitor sees GW, it expects it performed the full startup |
128 | | - } |
129 | | - void standby_state(NvmeAnaGrpId grpid) { |
130 | | - sm_state[grpid] = gw_states_per_group_t::GW_STANDBY_STATE; |
131 | | - }; |
132 | | - void active_state(NvmeAnaGrpId grpid) { |
133 | | - sm_state[grpid] = gw_states_per_group_t::GW_ACTIVE_STATE; |
134 | | - blocklist_data[grpid].osd_epoch = 0; |
135 | | - }; |
| 115 | + // ana-group-id allocated for this GW, GW owns this group-id |
| 116 | + NvmeAnaGrpId ana_grp_id; |
| 117 | + // in absence of beacon heartbeat messages it becomes inavailable |
| 118 | + gw_availability_t availability; |
| 119 | + // "true" if the last epoch seen by the gw-client is up-to-date |
| 120 | + bool last_gw_map_epoch_valid; |
| 121 | + // in order to identify gws that did not exit upon failover |
| 122 | + bool performed_full_startup; |
| 123 | + // gateway susbsystem and their state machine states |
| 124 | + BeaconSubsystems subsystems; |
| 125 | + NvmeAnaNonceMap nonce_map; |
| 126 | + |
| 127 | + // state machine states per ANA group |
| 128 | + SmState sm_state; |
| 129 | + BlocklistData blocklist_data; |
| 130 | + |
| 131 | + NvmeGwMonState(): ana_grp_id(REDUNDANT_GW_ANA_GROUP_ID) {} |
| 132 | + |
| 133 | + NvmeGwMonState(NvmeAnaGrpId id) |
| 134 | + : ana_grp_id(id), availability(gw_availability_t::GW_CREATED), |
| 135 | + last_gw_map_epoch_valid(false), performed_full_startup(false) {} |
| 136 | + void set_unavailable_state() { |
| 137 | + availability = gw_availability_t::GW_UNAVAILABLE; |
| 138 | + // after setting this state the next time monitor sees GW, |
| 139 | + // it expects it performed the full startup |
| 140 | + performed_full_startup = false; |
| 141 | + } |
| 142 | + void standby_state(NvmeAnaGrpId grpid) { |
| 143 | + sm_state[grpid] = gw_states_per_group_t::GW_STANDBY_STATE; |
| 144 | + } |
| 145 | + void active_state(NvmeAnaGrpId grpid) { |
| 146 | + sm_state[grpid] = gw_states_per_group_t::GW_ACTIVE_STATE; |
| 147 | + blocklist_data[grpid].osd_epoch = 0; |
| 148 | + } |
136 | 149 | }; |
137 | 150 |
|
138 | 151 | struct NqnState { |
139 | | - std::string nqn; // subsystem NQN |
140 | | - ana_state_t ana_state; // subsystem's ANA state |
141 | | - |
142 | | - // constructors |
143 | | - NqnState(const std::string& _nqn, const ana_state_t& _ana_state): |
144 | | - nqn(_nqn), ana_state(_ana_state) {} |
145 | | - NqnState(const std::string& _nqn, const SmState& sm_state, const NvmeGwMonState & gw_created) : nqn(_nqn) { |
146 | | - uint32_t i = 0; |
147 | | - for (auto& state_itr: sm_state) { |
148 | | - if (state_itr.first > i) { |
149 | | - uint32_t num_to_add = state_itr.first - i; |
150 | | - for (uint32_t j = 0; j<num_to_add; j++) { // add fake elements to the ana_state in order to preserve vector index == correct ana_group_id |
151 | | - std::pair<gw_exported_states_per_group_t, epoch_t> state_pair; |
152 | | - state_pair.first = gw_exported_states_per_group_t::GW_EXPORTED_INACCESSIBLE_STATE; |
153 | | - state_pair.second = 0; |
154 | | - ana_state.push_back(state_pair); |
155 | | - } |
156 | | - i += num_to_add; |
157 | | - } |
158 | | - std::pair<gw_exported_states_per_group_t, epoch_t> state_pair; |
159 | | - state_pair.first = (sm_state.at(state_itr.first) == gw_states_per_group_t::GW_ACTIVE_STATE |
160 | | - || sm_state.at(state_itr.first) == gw_states_per_group_t::GW_WAIT_BLOCKLIST_CMPL) |
161 | | - ? gw_exported_states_per_group_t::GW_EXPORTED_OPTIMIZED_STATE |
162 | | - : gw_exported_states_per_group_t::GW_EXPORTED_INACCESSIBLE_STATE; |
163 | | - state_pair.second = gw_created.blocklist_data.at(state_itr.first).osd_epoch; |
164 | | - ana_state.push_back(state_pair); |
165 | | - i ++; |
166 | | - } |
| 152 | + std::string nqn; // subsystem NQN |
| 153 | + ana_state_t ana_state; // subsystem's ANA state |
| 154 | + |
| 155 | + // constructors |
| 156 | + NqnState(const std::string& _nqn, const ana_state_t& _ana_state) |
| 157 | + : nqn(_nqn), ana_state(_ana_state) {} |
| 158 | + NqnState( |
| 159 | + const std::string& _nqn, const SmState& sm_state, |
| 160 | + const NvmeGwMonState & gw_created) |
| 161 | + : nqn(_nqn) { |
| 162 | + uint32_t i = 0; |
| 163 | + for (auto& state_itr: sm_state) { |
| 164 | + if (state_itr.first > i) { |
| 165 | + uint32_t num_to_add = state_itr.first - i; |
| 166 | + // add fake elements to the ana_state in order to |
| 167 | + // preserve vector index == correct ana_group_id |
| 168 | + for (uint32_t j = 0; j < num_to_add; j++) { |
| 169 | + std::pair<gw_exported_states_per_group_t, epoch_t> state_pair; |
| 170 | + state_pair.first = |
| 171 | + gw_exported_states_per_group_t::GW_EXPORTED_INACCESSIBLE_STATE; |
| 172 | + state_pair.second = 0; |
| 173 | + ana_state.push_back(state_pair); |
| 174 | + } |
| 175 | + i += num_to_add; |
| 176 | + } |
| 177 | + std::pair<gw_exported_states_per_group_t, epoch_t> state_pair; |
| 178 | + state_pair.first = ( |
| 179 | + (sm_state.at(state_itr.first) == |
| 180 | + gw_states_per_group_t::GW_ACTIVE_STATE) || |
| 181 | + (sm_state.at(state_itr.first) == |
| 182 | + gw_states_per_group_t::GW_WAIT_BLOCKLIST_CMPL)) |
| 183 | + ? gw_exported_states_per_group_t::GW_EXPORTED_OPTIMIZED_STATE |
| 184 | + : gw_exported_states_per_group_t::GW_EXPORTED_INACCESSIBLE_STATE; |
| 185 | + state_pair.second = |
| 186 | + gw_created.blocklist_data.at(state_itr.first).osd_epoch; |
| 187 | + ana_state.push_back(state_pair); |
| 188 | + i++; |
167 | 189 | } |
| 190 | + } |
168 | 191 | }; |
169 | 192 |
|
170 | 193 | typedef std::map<NvmeNqnId, NqnState> GwSubsystems; |
171 | 194 |
|
172 | 195 | struct NvmeGwClientState { |
173 | | - NvmeAnaGrpId group_id; |
174 | | - epoch_t gw_map_epoch; |
175 | | - GwSubsystems subsystems; |
176 | | - gw_availability_t availability; |
177 | | - NvmeGwClientState(NvmeAnaGrpId id, epoch_t epoch, gw_availability_t available): |
178 | | - group_id(id), |
179 | | - gw_map_epoch(epoch), |
180 | | - availability(available) |
181 | | - {}; |
182 | | - |
183 | | - NvmeGwClientState() : NvmeGwClientState(REDUNDANT_GW_ANA_GROUP_ID, 0, gw_availability_t::GW_UNAVAILABLE) {}; |
| 196 | + NvmeAnaGrpId group_id; |
| 197 | + epoch_t gw_map_epoch; |
| 198 | + GwSubsystems subsystems; |
| 199 | + gw_availability_t availability; |
| 200 | + NvmeGwClientState(NvmeAnaGrpId id, epoch_t epoch, gw_availability_t available) |
| 201 | + : group_id(id), gw_map_epoch(epoch), availability(available) {} |
| 202 | + |
| 203 | + NvmeGwClientState() |
| 204 | + : NvmeGwClientState( |
| 205 | + REDUNDANT_GW_ANA_GROUP_ID, 0, gw_availability_t::GW_UNAVAILABLE) {} |
184 | 206 | }; |
185 | 207 |
|
186 | | - |
187 | | -struct Tmdata{ |
188 | | - uint32_t timer_started; // statemachine timer(timestamp) set in some state |
189 | | - uint8_t timer_value; |
190 | | - std::chrono::system_clock::time_point end_time; |
191 | | - Tmdata() { |
192 | | - timer_started = 0; |
193 | | - timer_value = 0; |
194 | | - } |
| 208 | +struct Tmdata { |
| 209 | + uint32_t timer_started; // statemachine timer(timestamp) set in some state |
| 210 | + uint8_t timer_value; |
| 211 | + std::chrono::system_clock::time_point end_time; |
| 212 | + Tmdata() { |
| 213 | + timer_started = 0; |
| 214 | + timer_value = 0; |
| 215 | + } |
195 | 216 | }; |
196 | 217 |
|
197 | | -using TmData = std::map < NvmeAnaGrpId, Tmdata>; |
| 218 | +using TmData = std::map<NvmeAnaGrpId, Tmdata>; |
198 | 219 |
|
199 | 220 | struct NvmeGwTimerState { |
200 | | - TmData data; |
201 | | - NvmeGwTimerState() {}; |
| 221 | + TmData data; |
| 222 | + NvmeGwTimerState() {}; |
202 | 223 | }; |
203 | 224 |
|
204 | | -using NvmeGwMonClientStates = std::map<NvmeGwId, NvmeGwClientState>; |
205 | | -using NvmeGwTimers = std::map<NvmeGwId, NvmeGwTimerState>; |
206 | | -using NvmeGwMonStates = std::map<NvmeGwId, NvmeGwMonState>; |
| 225 | +using NvmeGwMonClientStates = std::map<NvmeGwId, NvmeGwClientState>; |
| 226 | +using NvmeGwTimers = std::map<NvmeGwId, NvmeGwTimerState>; |
| 227 | +using NvmeGwMonStates = std::map<NvmeGwId, NvmeGwMonState>; |
207 | 228 |
|
208 | 229 | #endif /* SRC_MON_NVMEOFGWTYPES_H_ */ |
0 commit comments