| 3324 | } |
| 3325 | |
| 3326 | void Client::handle_mds_map(const MConstRef<MMDSMap>& m) |
| 3327 | { |
| 3328 | std::unique_lock cl(client_lock); |
| 3329 | if (m->get_epoch() <= mdsmap->get_epoch()) { |
| 3330 | ldout(cct, 1) << __func__ << " epoch " << m->get_epoch() |
| 3331 | << " is identical to or older than our " |
| 3332 | << mdsmap->get_epoch() << dendl; |
| 3333 | return; |
| 3334 | } |
| 3335 | |
| 3336 | cl.unlock(); |
| 3337 | ldout(cct, 1) << __func__ << " epoch " << m->get_epoch() << dendl; |
| 3338 | std::unique_ptr<MDSMap> _mdsmap(new MDSMap); |
| 3339 | _mdsmap->decode(m->get_encoded()); |
| 3340 | cancel_commands(*_mdsmap.get()); |
| 3341 | cl.lock(); |
| 3342 | |
| 3343 | _mdsmap.swap(mdsmap); |
| 3344 | |
| 3345 | // reset session |
| 3346 | for (auto p = mds_sessions.begin(); p != mds_sessions.end(); ) { |
| 3347 | mds_rank_t mds = p->first; |
| 3348 | MetaSessionRef session = p->second; |
| 3349 | ++p; |
| 3350 | |
| 3351 | int oldstate = _mdsmap->get_state(mds); |
| 3352 | int newstate = mdsmap->get_state(mds); |
| 3353 | if (!mdsmap->is_up(mds)) { |
| 3354 | session->con->mark_down(); |
| 3355 | } else if (mdsmap->get_addrs(mds) != session->addrs) { |
| 3356 | auto old_inc = _mdsmap->get_incarnation(mds); |
| 3357 | auto new_inc = mdsmap->get_incarnation(mds); |
| 3358 | if (old_inc != new_inc) { |
| 3359 | ldout(cct, 1) << "mds incarnation changed from " |
| 3360 | << old_inc << " to " << new_inc << dendl; |
| 3361 | oldstate = MDSMap::STATE_NULL; |
| 3362 | } |
| 3363 | session->con->mark_down(); |
| 3364 | session->addrs = mdsmap->get_addrs(mds); |
| 3365 | // When new MDS starts to take over, notify kernel to trim unused entries |
| 3366 | // in its dcache/icache. Hopefully, the kernel will release some unused |
| 3367 | // inodes before the new MDS enters reconnect state. |
| 3368 | trim_cache_for_reconnect(session.get()); |
| 3369 | } else if (oldstate == newstate) |
| 3370 | continue; // no change |
| 3371 | |
| 3372 | session->mds_state = newstate; |
| 3373 | if (newstate == MDSMap::STATE_RECONNECT) { |
| 3374 | session->con = messenger->connect_to_mds(session->addrs); |
| 3375 | send_reconnect(session.get()); |
| 3376 | } else if (newstate > MDSMap::STATE_RECONNECT) { |
| 3377 | if (oldstate < MDSMap::STATE_RECONNECT) { |
| 3378 | ldout(cct, 1) << "we may miss the MDSMap::RECONNECT, close mds session ... " << dendl; |
| 3379 | _closed_mds_session(session.get()); |
| 3380 | continue; |
| 3381 | } |
| 3382 | if (newstate >= MDSMap::STATE_ACTIVE) { |
| 3383 | if (oldstate < MDSMap::STATE_ACTIVE) { |
nothing calls this directly
no test coverage detected