]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: do not assume segment list is non-empty in standby_trim_segments
authorSage Weil <sage@inktank.com>
Fri, 21 Jun 2013 21:23:45 +0000 (14:23 -0700)
committerSage Weil <sage@inktank.com>
Mon, 24 Jun 2013 17:58:08 +0000 (10:58 -0700)
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)

src/mds/MDLog.cc
src/mds/MDLog.h

index c4773131d3c1a29f813215c948bed071f13d50ca..b293c4cc10a6fad91ede3252d2c9fd90b4a41cd6 100644 (file)
@@ -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();
index 9a547f0d79156d734804dc7fa2b4accef7bbad7e..46b34d26f69871f7a73654ec8218a57529e6230f 100644 (file)
@@ -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; }