If we restart standby replay shortly after startup, before we actually have
any segments, we an trigger a segfault here:
ceph version
0.64-441-gc39b99c (
c39b99cdecceaca77f66eafbcc38387406826406)
1: ceph-mds() [0x975caa]
2: (()+0xfcb0) [0x7fc33b5a5cb0]
3: (MDLog::standby_trim_segments()+0x192) [0x78a932]
4: (MDS::C_MDS_StandbyReplayRestartFinish::finish(int)+0x39) [0x595f69]
5: (Journaler::_finish_reprobe(int, unsigned long, Context*)+0x190) [0x7917b0]
6: (Filer::_probed(Filer::Probe*, object_t const&, unsigned long, utime_t)+0x558) [0x7c6b38]
7: (Objecter::C_Stat::finish(int)+0xc0) [0x7c7930]
8: (Objecter::handle_osd_op_reply(MOSDOpReply*)+0xe48) [0x7b2c78]
9: (MDS::handle_core_message(Message*)+0xae8) [0x589858]
10: (MDS::_dispatch(Message*)+0x2f) [0x589a1f]
11: (MDS::ms_dispatch(Message*)+0x1d3) [0x58b4a3]
12: (DispatchQueue::entry()+0x3f1) [0x943861]
13: (DispatchQueue::DispatchThread::entry()+0xd) [0x86e32d]
Fixes: #5333
Signed-off-by: Sage Weil <sage@inktank.com>
Reviewed-by: Greg Farnum <greg@inktank.com>
(cherry picked from commit
abd0ff64e108b7670a062b3fa39baaf3d3e48fb3)
dout(10) << "standby_trim_segments" << dendl;
uint64_t expire_pos = journaler->get_expire_pos();
dout(10) << " expire_pos=" << expire_pos << dendl;
- LogSegment *seg = NULL;
bool removed_segment = false;
- while ((seg = get_oldest_segment())->end <= expire_pos) {
+ while (have_any_segments()) {
+ LogSegment *seg = get_oldest_segment();
+ if (seg->end > expire_pos)
+ break;
dout(10) << " removing segment " << seg->offset << dendl;
seg->dirty_dirfrags.clear_list();
seg->new_dirfrags.clear_list();
return NULL;
}
+ bool have_any_segments() {
+ return !segments.empty();
+ }
+
void flush_logger();
size_t get_num_events() { return num_events; }