summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSage Weil <sage@inktank.com>2013-06-21 14:23:45 -0700
committerSage Weil <sage@inktank.com>2013-06-21 14:23:45 -0700
commitabd0ff64e108b7670a062b3fa39baaf3d3e48fb3 (patch)
tree6a8561395b4df04244f048fc0c59a1e2dc2f5630
parent4bf5b732cd8869276e87d4bbc4f261ee9e0c6a4c (diff)
downloadceph-abd0ff64e108b7670a062b3fa39baaf3d3e48fb3.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>
-rw-r--r--src/mds/MDLog.cc6
-rw-r--r--src/mds/MDLog.h4
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; }