]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mon: 'osd thrash <num epochs>'
authorSage Weil <sage@newdream.net>
Wed, 25 Apr 2012 16:23:49 +0000 (09:23 -0700)
committerSage Weil <sage@newdream.net>
Wed, 25 Apr 2012 20:43:41 +0000 (13:43 -0700)
Thrash the osdmap for N iterations.  Randomly mark OSDs up, down, in, out,
and up_thru in order to generate a difficult osdmap history for peering
to chew through.

Signed-off-by: Sage Weil <sage@newdream.net>
src/mon/OSDMonitor.cc
src/mon/OSDMonitor.h

index fa9c5929d32e4803fa866ac41d85335c3a126405..e6fb65f3f0751189e63ff3810046fd3f80d2e231 100644 (file)
@@ -58,7 +58,8 @@ static ostream& _prefix(std::ostream *_dout, Monitor *mon, OSDMap& osdmap) {
 
 /************ MAPS ****************/
 OSDMonitor::OSDMonitor(Monitor *mn, Paxos *p)
-  : PaxosService(mn, p)
+  : PaxosService(mn, p),
+    thrash_map(0), thrash_last_up_osd(-1)
 {
   // we need to trim this too
   p->add_extra_state_dir("osdmap_full");
@@ -149,9 +150,61 @@ void OSDMonitor::update_from_paxos()
   update_logger();
 }
 
+bool OSDMonitor::thrash()
+{
+  if (!thrash_map)
+    return false;
+
+  thrash_map--;
+  int o;
+
+  // mark a random osd up_thru.. 
+  if (rand() % 4 == 0 || thrash_last_up_osd < 0)
+    o = rand() % osdmap.get_num_osds();
+  else
+    o = thrash_last_up_osd;
+  if (osdmap.is_up(o)) {
+    dout(5) << "thrash_map osd." << o << " up_thru" << dendl;
+    pending_inc.new_up_thru[o] = osdmap.get_epoch();
+  }
+
+  // mark a random osd up/down
+  o = rand() % osdmap.get_num_osds();
+  if (osdmap.is_up(o)) {
+    dout(5) << "thrash_map osd." << o << " down" << dendl;
+    pending_inc.new_state[o] = CEPH_OSD_UP;
+  } else if (osdmap.exists(o)) {
+    dout(5) << "thrash_map osd." << o << " up" << dendl;
+    pending_inc.new_state[o] = CEPH_OSD_UP;
+    pending_inc.new_up_client[o] = entity_addr_t();
+    pending_inc.new_up_internal[o] = entity_addr_t();
+    pending_inc.new_hb_up[o] = entity_addr_t();
+    pending_inc.new_weight[o] = CEPH_OSD_IN;
+    thrash_last_up_osd = o;
+  }
+
+  // mark a random osd in
+  o = rand() % osdmap.get_num_osds();
+  if (osdmap.exists(o)) {
+    dout(5) << "thrash_map osd." << o << " in" << dendl;
+    pending_inc.new_weight[o] = CEPH_OSD_IN;
+  }
+
+  // mark a random osd out
+  o = rand() % osdmap.get_num_osds();
+  if (osdmap.exists(o)) {
+    dout(5) << "thrash_map osd." << o << " out" << dendl;
+    pending_inc.new_weight[o] = CEPH_OSD_OUT;
+  }
+  return true;
+}
+
 void OSDMonitor::on_active()
 {
   update_logger();
+
+  if (thrash_map && thrash())
+    propose_pending();
 }
 
 void OSDMonitor::update_logger()
@@ -1607,6 +1660,7 @@ bool OSDMonitor::prepare_unset_flag(MMonCommand *m, int flag)
 
 bool OSDMonitor::prepare_command(MMonCommand *m)
 {
+  bool ret = false;
   stringstream ss;
   string rs;
   int err = -EINVAL;
@@ -2289,6 +2343,12 @@ bool OSDMonitor::prepare_command(MMonCommand *m)
        ss << "SUCCESSFUL reweight-by-utilization: " << out_str;
       }
     }
+    else if (m->cmd.size() == 3 && m->cmd[1] == "thrash") {
+      thrash_map = atoi(m->cmd[2].c_str());
+      ss << "will thrash map for " << thrash_map << " epochs";
+      ret = thrash();
+      err = 0;
+    }
     else {
       ss << "unknown command " << m->cmd[1];
     }
@@ -2300,7 +2360,7 @@ out:
   if (err < 0 && rs.length() == 0)
     rs = cpp_strerror(err);
   mon->reply_command(m, err, rs, paxos->get_version());
-  return false;
+  return ret;
 }
 
 bool OSDMonitor::preprocess_pool_op(MPoolOp *m) 
index bc83279c4de523446050c4ee7f640d7c3fb16c78..e9081dcb40e2c458e8661a0a40116a3e3f415fcb 100644 (file)
@@ -49,6 +49,12 @@ private:
   map<int,utime_t>    down_pending_out;  // osd down -> out
 
   map<int,double> osd_weight;
+
+  // map thrashing
+  int thrash_map;
+  int thrash_last_up_osd;
+  bool thrash();
+
   // svc
 public:  
   void create_initial();