Skip to content

Commit c056c9f

Browse files
Merge pull request ceph#62916 from mohit84/tick_without_osd_crash
osd: Access/Modify epoch maps under mutex in OSDSuperblock class
2 parents a668040 + 8cf896e commit c056c9f

File tree

5 files changed

+148
-27
lines changed

5 files changed

+148
-27
lines changed

src/crimson/osd/osd.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ void OSD::dump_status(Formatter* f) const
870870
f->dump_stream("osd_fsid") << superblock.osd_fsid;
871871
f->dump_unsigned("whoami", superblock.whoami);
872872
f->dump_string("state", pg_shard_manager.get_osd_state_string());
873-
f->dump_stream("maps") << superblock.maps;
873+
f->dump_stream("maps") << superblock.get_maps();
874874
f->dump_stream("oldest_map") << superblock.get_oldest_map();
875875
f->dump_stream("newest_map") << superblock.get_newest_map();
876876
f->dump_unsigned("cluster_osdmap_trim_lower_bound",
@@ -881,7 +881,7 @@ void OSD::dump_status(Formatter* f) const
881881
void OSD::print(std::ostream& out) const
882882
{
883883
out << "{osd." << superblock.whoami << " "
884-
<< superblock.osd_fsid << " maps " << superblock.maps
884+
<< superblock.osd_fsid << " maps " << superblock.get_maps()
885885
<< " tlb:" << superblock.cluster_osdmap_trim_lower_bound
886886
<< " pgs:" << pg_shard_manager.get_num_pgs()
887887
<< "}";
@@ -1197,7 +1197,7 @@ seastar::future<> OSD::_handle_osd_map(Ref<MOSDMap> m)
11971197
// even if this map isn't from a mon, we may have satisfied our subscription
11981198
monc->sub_got("osdmap", last);
11991199

1200-
if (!superblock.maps.empty()) {
1200+
if (!superblock.is_maps_empty()) {
12011201
pg_shard_manager.trim_maps(t, superblock);
12021202
// TODO: once we support pg splitting, update pg_num_history here
12031203
//pg_num_history.prune(superblock.get_oldest_map());

src/crimson/osd/shard_services.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,7 @@ void OSDSingletonState::trim_maps(ceph::os::Transaction& t,
547547
DEBUG("removing old osdmap epoch {}", superblock.get_oldest_map());
548548
meta_coll->remove_map(t, superblock.get_oldest_map());
549549
meta_coll->remove_inc_map(t, superblock.get_oldest_map());
550-
superblock.maps.erase(superblock.get_oldest_map());
550+
superblock.erase_oldest_maps();
551551
}
552552

553553
// we should not trim past osdmaps.cached_key_lower_bound()

src/osd/OSD.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2793,7 +2793,7 @@ void OSD::asok_command(
27932793
f->dump_stream("osd_fsid") << superblock.osd_fsid;
27942794
f->dump_unsigned("whoami", superblock.whoami);
27952795
f->dump_string("state", get_state_name(get_state()));
2796-
f->dump_stream("maps") << superblock.maps;
2796+
f->dump_stream("maps") << superblock.get_maps();
27972797
f->dump_stream("oldest_map") << superblock.get_oldest_map();
27982798
f->dump_stream("newest_map") << superblock.get_newest_map();
27992799
f->dump_unsigned("cluster_osdmap_trim_lower_bound",
@@ -6923,7 +6923,7 @@ void OSD::start_boot()
69236923
}
69246924
dout(1) << __func__ << dendl;
69256925
set_state(STATE_PREBOOT);
6926-
dout(10) << "start_boot - have maps " << superblock.maps << dendl;
6926+
dout(10) << "start_boot - have maps " << superblock.get_maps() << dendl;
69276927
monc->get_version("osdmap", CB_OSD_GetVersion(this));
69286928
}
69296929

@@ -8121,7 +8121,7 @@ void OSD::trim_maps(epoch_t oldest)
81218121
dout(20) << " removing old osdmap epoch " << superblock.get_oldest_map() << dendl;
81228122
t.remove(coll_t::meta(), get_osdmap_pobject_name(superblock.get_oldest_map()));
81238123
t.remove(coll_t::meta(), get_inc_osdmap_pobject_name(superblock.get_oldest_map()));
8124-
superblock.maps.erase(superblock.get_oldest_map());
8124+
superblock.erase_oldest_maps();
81258125
}
81268126

81278127
service.publish_superblock(superblock);
@@ -8422,16 +8422,16 @@ void OSD::handle_osd_map(MOSDMap *m)
84228422

84238423
track_pools_and_pg_num_changes(added_maps, t);
84248424

8425-
if (!superblock.maps.empty()) {
8425+
if (!superblock.is_maps_empty()) {
84268426
trim_maps(m->cluster_osdmap_trim_lower_bound);
84278427
pg_num_history.prune(superblock.get_oldest_map());
84288428
}
84298429
superblock.insert_osdmap_epochs(first, last);
8430-
if (superblock.maps.num_intervals() > 1) {
8430+
if (superblock.get_maps_num_intervals() > 1) {
84318431
// we had a map gap and not yet trimmed all the way up to
84328432
// cluster_osdmap_trim_lower_bound
84338433
dout(10) << __func__ << " osd maps are not contiguous"
8434-
<< superblock.maps << dendl;
8434+
<< superblock.get_maps() << dendl;
84358435
}
84368436
superblock.current_epoch = last;
84378437

@@ -8501,7 +8501,7 @@ void OSD::track_pools_and_pg_num_changes(
85018501
// lastmap should be the newest_map we have.
85028502
OSDMapRef lastmap;
85038503

8504-
if (superblock.maps.empty()) {
8504+
if (superblock.is_maps_empty()) {
85058505
dout(10) << __func__ << " no maps stored, this is probably "
85068506
<< "the first start of this osd" << dendl;
85078507
lastmap = added_maps.at(first);

src/osd/osd_types.cc

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5822,6 +5822,19 @@ void pg_hit_set_history_t::generate_test_instances(list<pg_hit_set_history_t*>&
58225822
ls.back()->history.push_back(pg_hit_set_info_t());
58235823
}
58245824

5825+
// -- GuardedMap --
5826+
void OSDSuperblock::GuardedMap::encode(ceph::buffer::list &bl) const
5827+
{
5828+
std::lock_guard lock(map_lock);
5829+
::encode(maps, bl);
5830+
}
5831+
5832+
void OSDSuperblock::GuardedMap::decode(ceph::buffer::list::const_iterator &bl)
5833+
{
5834+
std::lock_guard lock(map_lock);
5835+
::decode(maps, bl);
5836+
}
5837+
58255838
// -- OSDSuperblock --
58265839

58275840
void OSDSuperblock::encode(ceph::buffer::list &bl) const
@@ -5842,7 +5855,7 @@ void OSDSuperblock::encode(ceph::buffer::list &bl) const
58425855
encode(purged_snaps_last, bl);
58435856
encode(last_purged_snaps_scrub, bl);
58445857
encode(cluster_osdmap_trim_lower_bound, bl);
5845-
encode(maps, bl);
5858+
mapc.encode(bl);
58465859
ENCODE_FINISH(bl);
58475860
}
58485861

@@ -5889,7 +5902,7 @@ void OSDSuperblock::decode(ceph::buffer::list::const_iterator &bl)
58895902
cluster_osdmap_trim_lower_bound = 0;
58905903
}
58915904
if (struct_v >= 11) {
5892-
decode(maps, bl);
5905+
mapc.decode(bl);
58935906
} else {
58945907
insert_osdmap_epochs(oldest_map, newest_map);
58955908
}
@@ -5912,7 +5925,7 @@ void OSDSuperblock::dump(Formatter *f) const
59125925
f->dump_stream("last_purged_snaps_scrub") << last_purged_snaps_scrub;
59135926
f->dump_int("cluster_osdmap_trim_lower_bound",
59145927
cluster_osdmap_trim_lower_bound);
5915-
f->dump_stream("maps") << maps;
5928+
f->dump_stream("maps") << get_maps();
59165929
}
59175930

59185931
void OSDSuperblock::generate_test_instances(list<OSDSuperblock*>& o)

src/osd/osd_types.h

Lines changed: 121 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
#include "common/Formatter.h"
5050
#include "common/hobject.h"
5151
#include "common/snap_types.h"
52+
#include "common/ceph_mutex.h"
5253
#include "common/strtol.h" // for ritoa()
5354
#include "HitSet.h"
5455
#include "librados/ListObjectImpl.h"
@@ -5673,33 +5674,133 @@ inline std::ostream& operator<<(std::ostream& out, const ObjectExtent &ex)
56735674
// ---------------------------------------
56745675

56755676
class OSDSuperblock {
5676-
public:
5677-
uuid_d cluster_fsid, osd_fsid;
5678-
int32_t whoami = -1; // my role in this fs.
5679-
epoch_t current_epoch = 0; // most recent epoch
5680-
interval_set<epoch_t> maps; // oldest/newest maps we have.
5677+
private:
5678+
class GuardedMap {
5679+
private:
5680+
mutable ceph::mutex map_lock = ceph::make_mutex("map_lock");
5681+
interval_set<epoch_t> maps;
56815682

5682-
epoch_t get_oldest_map() const {
5683+
epoch_t calc_newest_map() const {
56835684
if (!maps.empty()) {
5684-
return maps.range_start();
5685+
// maps stores [oldest_map, newest_map) (exclusive)
5686+
return maps.range_end() - 1;
56855687
}
56865688
return 0;
56875689
}
5688-
5689-
epoch_t get_newest_map() const {
5690+
epoch_t calc_oldest_map() const {
56905691
if (!maps.empty()) {
5691-
// maps stores [oldest_map, newest_map) (exclusive)
5692-
return maps.range_end() - 1;
5692+
return maps.range_start();
56935693
}
56945694
return 0;
56955695
}
5696+
public:
5697+
GuardedMap() = default;
5698+
GuardedMap(const GuardedMap& other)
5699+
: map_lock(ceph::make_mutex("map_lock"))
5700+
{
5701+
std::lock_guard l(other.map_lock); // Lock before copying shared state
5702+
maps = other.maps;
5703+
}
5704+
5705+
GuardedMap& operator=(const GuardedMap& other) {
5706+
if (this != &other) {
5707+
std::scoped_lock l(map_lock, other.map_lock);
5708+
maps = other.maps;
5709+
}
5710+
return *this;
5711+
}
5712+
5713+
GuardedMap(GuardedMap&& other)
5714+
:map_lock(ceph::make_mutex("map_lock"))
5715+
{
5716+
std::lock_guard l(other.map_lock);
5717+
maps = std::move(other.maps);
5718+
}
5719+
5720+
GuardedMap& operator=(GuardedMap&& other) noexcept {
5721+
if (this != &other) {
5722+
std::scoped_lock l(map_lock, other.map_lock);
5723+
maps = std::move(other.maps);
5724+
}
5725+
return *this;
5726+
}
5727+
5728+
bool is_maps_empty() const {
5729+
std::lock_guard lock(map_lock);
5730+
return maps.empty();
5731+
}
5732+
5733+
void erase_oldest_maps() {
5734+
std::lock_guard lock(map_lock);
5735+
maps.erase(calc_oldest_map());
5736+
}
5737+
5738+
interval_set<epoch_t>::size_type get_maps_num_intervals() const {
5739+
std::lock_guard lock(map_lock);
5740+
return maps.num_intervals();
5741+
}
5742+
5743+
interval_set<epoch_t> get_maps() const {
5744+
std::lock_guard lock(map_lock);
5745+
return maps;
5746+
}
5747+
5748+
epoch_t get_oldest_map() const {
5749+
std::lock_guard lock(map_lock);
5750+
return calc_oldest_map();
5751+
}
5752+
5753+
epoch_t get_newest_map() const {
5754+
std::lock_guard lock(map_lock);
5755+
return calc_newest_map();
5756+
}
56965757

56975758
void insert_osdmap_epochs(epoch_t first, epoch_t last) {
56985759
ceph_assert(std::cmp_less_equal(first, last));
56995760
interval_set<epoch_t> message_epochs;
57005761
message_epochs.insert(first, last - first + 1);
5762+
std::lock_guard lock(map_lock);
57015763
maps.union_of(message_epochs);
5702-
ceph_assert(last == get_newest_map());
5764+
ceph_assert(last == calc_newest_map());
5765+
}
5766+
5767+
void encode(ceph::buffer::list &bl) const;
5768+
void decode(ceph::buffer::list::const_iterator &bl);
5769+
5770+
};
5771+
WRITE_CLASS_ENCODER(GuardedMap);
5772+
GuardedMap mapc;
5773+
public:
5774+
uuid_d cluster_fsid, osd_fsid;
5775+
int32_t whoami = -1; // my role in this fs.
5776+
epoch_t current_epoch = 0; // most recent epoch
5777+
5778+
bool is_maps_empty() const {
5779+
return mapc.is_maps_empty();
5780+
}
5781+
5782+
void erase_oldest_maps() {
5783+
mapc.erase_oldest_maps();
5784+
}
5785+
5786+
interval_set<epoch_t>::size_type get_maps_num_intervals() const {
5787+
return mapc.get_maps_num_intervals();
5788+
}
5789+
5790+
interval_set<epoch_t> get_maps() const {
5791+
return mapc.get_maps();
5792+
}
5793+
5794+
epoch_t get_oldest_map() const {
5795+
return mapc.get_oldest_map();
5796+
}
5797+
5798+
epoch_t get_newest_map() const {
5799+
return mapc.get_newest_map();
5800+
}
5801+
5802+
void insert_osdmap_epochs(epoch_t first, epoch_t last) {
5803+
mapc.insert_osdmap_epochs(first, last);
57035804
}
57045805

57055806
double weight = 0.0;
@@ -5719,6 +5820,13 @@ class OSDSuperblock {
57195820
void decode(ceph::buffer::list::const_iterator &bl);
57205821
void dump(ceph::Formatter *f) const;
57215822
static void generate_test_instances(std::list<OSDSuperblock*>& o);
5823+
5824+
// Allow default operators to avoid crimson related errors
5825+
OSDSuperblock(OSDSuperblock&&) noexcept = default;
5826+
OSDSuperblock& operator=(OSDSuperblock&&) noexcept = default;
5827+
OSDSuperblock(const OSDSuperblock&) = default;
5828+
OSDSuperblock& operator=(const OSDSuperblock&) = default;
5829+
OSDSuperblock() = default;
57225830
};
57235831
WRITE_CLASS_ENCODER(OSDSuperblock)
57245832

@@ -5728,7 +5836,7 @@ inline std::ostream& operator<<(std::ostream& out, const OSDSuperblock& sb)
57285836
<< " osd." << sb.whoami
57295837
<< " " << sb.osd_fsid
57305838
<< " e" << sb.current_epoch
5731-
<< " maps " << sb.maps
5839+
<< " maps " << sb.get_maps()
57325840
<< " lci=[" << sb.mounted << "," << sb.clean_thru << "]"
57335841
<< " tlb=" << sb.cluster_osdmap_trim_lower_bound
57345842
<< ")";

0 commit comments

Comments
 (0)