@@ -379,6 +379,14 @@ void OSDSingletonState::store_map_bl(
379379 map_bl_cache.insert (e, std::move (bl));
380380}
381381
382+ void OSDSingletonState::store_inc_map_bl (
383+ ceph::os::Transaction& t,
384+ epoch_t e, bufferlist&& bl)
385+ {
386+ meta_coll->store_inc_map (t, e, bl);
387+ inc_map_bl_cache.insert (e, std::move (bl));
388+ }
389+
382390seastar::future<bufferlist> OSDSingletonState::load_map_bl (
383391 epoch_t e)
384392{
@@ -387,29 +395,56 @@ seastar::future<bufferlist> OSDSingletonState::load_map_bl(
387395 return seastar::make_ready_future<bufferlist>(*found);
388396 } else {
389397 logger ().debug (" {} loading osdmap.{} from disk" , __func__, e);
390- return meta_coll->load_map (e);
398+ return meta_coll->load_map (e).then ([this , e](auto && bl) {
399+ map_bl_cache.insert (e, bl);
400+ return seastar::make_ready_future<bufferlist>(std::move (bl));
401+ });
391402 }
392403}
393404
394- seastar::future<std::map<epoch_t , bufferlist>> OSDSingletonState::load_map_bls (
405+ read_errorator::future<ceph::bufferlist> OSDSingletonState::load_inc_map_bl (
406+ epoch_t e)
407+ {
408+ if (std::optional<bufferlist> found = inc_map_bl_cache.find (e); found) {
409+ logger ().debug (" {} inc map.{} found in cache" , __func__, e);
410+ return read_errorator::make_ready_future<bufferlist>(*found);
411+ } else {
412+ logger ().debug (" {} loading inc map.{} from disk" , __func__, e);
413+ return meta_coll->load_inc_map (e).safe_then ([this , e](auto && bl) {
414+ inc_map_bl_cache.insert (e, bl);
415+ return seastar::make_ready_future<bufferlist>(std::move (bl));
416+ }, read_errorator::pass_further{});
417+ }
418+ }
419+
420+ seastar::future<OSDMapService::bls_map_t > OSDSingletonState::load_map_bls (
395421 epoch_t first,
396422 epoch_t last)
397423{
398424 logger ().debug (" {} loading maps [{},{}]" ,
399425 __func__, first, last);
400426 ceph_assert (first <= last);
401- // TODO: take osd_map_max into account
402- // int max = cct->_conf->osd_map_message_max;
403- // ssize_t max_bytes = cct->_conf->osd_map_message_max_bytes;
404427 return seastar::map_reduce (boost::make_counting_iterator<epoch_t >(first),
405428 boost::make_counting_iterator<epoch_t >(last + 1 ),
406429 [this ](epoch_t e) {
407- return load_map_bl (e).then ([e](auto && bl) {
408- return seastar::make_ready_future<std::pair<epoch_t , bufferlist>>(
409- std::make_pair (e, std::move (bl)));
430+ return load_inc_map_bl (e).safe_then ([](auto && bl) {
431+ return seastar::make_ready_future<OSDMapService::bls_pair>(
432+ std::make_pair (OSDMapService::encoded_osdmap_type_t ::INCMAP,
433+ std::move (bl)));
434+ }, read_errorator::all_same_way ([this , e] {
435+ logger ().debug (" load_map_bls: can't load inc map {}, attempting full map instread" ,
436+ e);
437+ return load_map_bl (e).then ([](auto && bl) {
438+ return seastar::make_ready_future<OSDMapService::bls_pair>(
439+ std::make_pair (OSDMapService::encoded_osdmap_type_t ::FULLMAP,
440+ std::move (bl)));
441+ });
442+ })).then ([e] (auto && loaded_map) {
443+ return seastar::make_ready_future<OSDMapService::bls_map_pair_t >(
444+ std::make_pair (e, std::move (loaded_map)));
410445 });
411446 },
412- std::map< epoch_t , bufferlist> {},
447+ OSDMapService:: bls_map_t {},
413448 [](auto && bls, auto && epoch_bl) {
414449 bls.emplace (std::move (epoch_bl));
415450 return std::move (bls);
@@ -453,11 +488,12 @@ seastar::future<> OSDSingletonState::store_maps(ceph::os::Transaction& t,
453488 " loading osdmap.{}" , e, e - 1 );
454489 ceph_assert (std::cmp_greater (e, 0u ));
455490 return load_map (e - 1 ).then (
456- [&added_maps, e, bl=p->second , &t, this ](auto o) {
491+ [&added_maps, e, bl=p->second , &t, this ](auto o) mutable {
457492 OSDMap::Incremental inc;
458493 auto i = bl.cbegin ();
459494 inc.decode (i);
460495 o->apply_incremental (inc);
496+ store_inc_map_bl (t, e, std::move (bl));
461497 bufferlist fbl;
462498 o->encode (fbl, inc.encode_features | CEPH_FEATURE_RESERVED);
463499 logger ().info (" store_maps storing osdmap.{}" , o->get_epoch ());
@@ -499,6 +535,7 @@ void OSDSingletonState::trim_maps(ceph::os::Transaction& t,
499535 t.get_num_ops () < crimson::common::local_conf ()->osd_target_transaction_size ) {
500536 logger ().debug (" {}: removing old osdmap epoch {}" , __func__, superblock.get_oldest_map ());
501537 meta_coll->remove_map (t, superblock.get_oldest_map ());
538+ meta_coll->remove_inc_map (t, superblock.get_oldest_map ());
502539 superblock.maps .erase (superblock.get_oldest_map ());
503540 }
504541
@@ -757,49 +794,80 @@ seastar::future<> ShardServices::dispatch_context(
757794 });
758795}
759796
760- seastar::future<> OSDSingletonState::send_incremental_map (
761- crimson::net::Connection &conn ,
762- epoch_t first )
797+ seastar::future<MURef<MOSDMap>> OSDSingletonState::build_incremental_map_msg (
798+ epoch_t first ,
799+ epoch_t last )
763800{
764- logger ().info (" {}: first osdmap: {} "
765- " superblock's oldest map: {}" ,
766- __func__, first, superblock.get_oldest_map ());
767- if (first >= superblock.get_oldest_map ()) {
768- // TODO: osd_map_share_max_epochs
769- // See OSDService::build_incremental_map_msg
801+ return seastar::do_with (crimson::common::local_conf ()->osd_map_message_max ,
802+ crimson::make_message<MOSDMap>(
803+ monc.get_fsid (),
804+ osdmap->get_encoding_features ()),
805+ [this , &first, last](unsigned int map_message_max,
806+ auto & m) {
807+ m->cluster_osdmap_trim_lower_bound = superblock.cluster_osdmap_trim_lower_bound ;
808+ m->newest_map = superblock.get_newest_map ();
809+ auto maybe_handle_mapgap = seastar::now ();
770810 if (first < superblock.cluster_osdmap_trim_lower_bound ) {
771811 logger ().info (" {}: cluster osdmap lower bound: {} "
772- " > first {}, starting with full map" ,
773- __func__, superblock.cluster_osdmap_trim_lower_bound , first);
812+ " > first {}, starting with full map" ,
813+ __func__, superblock.cluster_osdmap_trim_lower_bound , first);
774814 // we don't have the next map the target wants,
775815 // so start with a full map.
776816 first = superblock.cluster_osdmap_trim_lower_bound ;
817+ maybe_handle_mapgap = load_map_bl (first).then (
818+ [&first, &map_message_max, &m](auto && bl) {
819+ m->maps [first] = std::move (bl);
820+ --map_message_max;
821+ ++first;
822+ });
777823 }
778- return load_map_bls (
779- first, superblock.get_newest_map ()
780- ).then ([this , &conn](auto && bls) {
781- auto m = crimson::make_message<MOSDMap>(
782- monc.get_fsid (),
783- osdmap->get_encoding_features ());
784- m->cluster_osdmap_trim_lower_bound = superblock.cluster_osdmap_trim_lower_bound ;
785- m->newest_map = superblock.get_newest_map ();
786- m->maps = std::move (bls);
787- return conn.send (std::move (m));
788- });
789- } else {
790- // See OSDService::send_incremental_map
791- // just send latest full map
792- return load_map_bl (osdmap->get_epoch ()
793- ).then ([this , &conn](auto && bl) mutable {
794- auto m = crimson::make_message<MOSDMap>(
795- monc.get_fsid (),
796- osdmap->get_encoding_features ());
797- m->cluster_osdmap_trim_lower_bound = superblock.cluster_osdmap_trim_lower_bound ;
798- m->newest_map = superblock.get_newest_map ();
799- m->maps .emplace (osdmap->get_epoch (), std::move (bl));
800- return conn.send (std::move (m));
824+ return maybe_handle_mapgap.then ([this , first, last, &map_message_max, &m] {
825+ if (first > last) {
826+ // first may be later than last in the case of map gap
827+ ceph_assert (!m->maps .empty ());
828+ return seastar::make_ready_future<MURef<MOSDMap>>(std::move (m));
829+ }
830+ return load_map_bls (
831+ first,
832+ ((last - first) > map_message_max) ? (first + map_message_max) : last
833+ ).then ([&m](auto && bls) {
834+ ssize_t map_message_max_bytes = crimson::common::local_conf ()->osd_map_message_max_bytes ;
835+ for (auto const & [e, val] : bls) {
836+ map_message_max_bytes -= val.second .length ();
837+ if (map_message_max_bytes < 0 ) {
838+ break ;
839+ }
840+ if (val.first == OSDMapService::encoded_osdmap_type_t ::FULLMAP) {
841+ m->maps .emplace (e, std::move (val.second ));
842+ } else if (val.first == OSDMapService::encoded_osdmap_type_t ::INCMAP) {
843+ m->incremental_maps .emplace (e, std::move (val.second ));
844+ } else {
845+ ceph_abort ();
846+ }
847+ }
848+ return seastar::make_ready_future<MURef<MOSDMap>>(std::move (m));
849+ });
801850 });
851+ });
852+ }
853+
854+ seastar::future<> OSDSingletonState::send_incremental_map (
855+ crimson::net::Connection &conn,
856+ epoch_t first)
857+ {
858+ epoch_t to = osdmap->get_epoch ();
859+ logger ().info (" {}: first osdmap: {} "
860+ " superblock's oldest map: {}, "
861+ " to {}" ,
862+ __func__, first, superblock.get_oldest_map (), to);
863+ if (to > first && (int64_t )(to - first) > crimson::common::local_conf ()->osd_map_share_max_epochs ) {
864+ logger ().debug (" {} {} > max epochs to send of {}, only sending most recent," ,
865+ __func__, (to - first), crimson::common::local_conf ()->osd_map_share_max_epochs );
866+ first = to - crimson::common::local_conf ()->osd_map_share_max_epochs ;
802867 }
868+ return build_incremental_map_msg (first, to).then ([&conn](auto && m) {
869+ return conn.send (std::move (m));
870+ });
803871}
804872
805873seastar::future<> OSDSingletonState::send_incremental_map_to_osd (
0 commit comments