diff options
author | Sage Weil <sage@inktank.com> | 2013-06-21 14:23:45 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-06-24 10:58:08 -0700 |
commit | f046dab88fcfeda23391bcd694abc65ff1ed8cd8 (patch) | |
tree | 7b762757ec788fcd73310f4547641c67631ba7e0 | |
parent | 7ef921c8c27d206e1156c79cf135bbc50cd76857 (diff) | |
download | ceph-f046dab88fcfeda23391bcd694abc65ff1ed8cd8.tar.gz |
mds: do not assume segment list is non-empty in standby_trim_segments
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)
-rw-r--r-- | src/mds/MDLog.cc | 6 | ||||
-rw-r--r-- | src/mds/MDLog.h | 4 |
2 files changed, 8 insertions, 2 deletions
diff --git a/src/mds/MDLog.cc b/src/mds/MDLog.cc index c4773131d3c..b293c4cc10a 100644 --- a/src/mds/MDLog.cc +++ b/src/mds/MDLog.cc @@ -610,9 +610,11 @@ void MDLog::standby_trim_segments() 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(); diff --git a/src/mds/MDLog.h b/src/mds/MDLog.h index 9a547f0d791..46b34d26f69 100644 --- a/src/mds/MDLog.h +++ b/src/mds/MDLog.h @@ -177,6 +177,10 @@ public: return NULL; } + bool have_any_segments() { + return !segments.empty(); + } + void flush_logger(); size_t get_num_events() { return num_events; } |