ceph源码分析--Monitor对osd report进行报down处理

上一篇讲到Monitor的tick处理,顺带讲解Monitor对osd report超时的处理
该部分在PGMonitor的tick中调用

void Monitor::tick()
{
  // ok go.
  dout(11) << "tick" << dendl;
  ···
  //调用paxosservice的tick()
  for (vector<PaxosService*>::iterator p = paxos_service.begin(); p != paxos_service.end(); ++p) {
    (*p)->tick();
    (*p)->maybe_trim();
  }

  ···
  new_tick();
}

在这里调用了PGMonitor的tick()

void PGMonitor::tick()
{
  if (!is_active()) return;
  if (mon->osdmon()->osdmap.require_osd_release >= CEPH_RELEASE_LUMINOUS) {
    return;
  }
  //处理osdreport超时
  handle_osd_timeouts();

  if (!pg_map.pg_sum_deltas.empty()) {
    utime_t age = ceph_clock_now() - pg_map.stamp;
    if (age > 2 * g_conf->mon_delta_reset_interval) {
      dout(10) << " clearing pg_map delta (" << age << " > " << g_conf->mon_delta_reset_interval << " seconds old)" << dendl;
      pg_map.clear_delta();
    }
  }

  /* If we have deltas for pools, run through pgmap's 'per_pool_sum_delta' and
   * clear any deltas that are old enough.
   *
   * Note that 'per_pool_sum_delta' keeps a pool id as key, and a pair containing
   * the calc'ed stats delta and an absolute timestamp from when those stats were
   * obtained -- the timestamp IS NOT a delta itself.
   */
  if (!pg_map.per_pool_sum_deltas.empty()) {
    ceph::unordered_map<uint64_t,pair<pool_stat_t,utime_t> >::iterator it;
    for (it = pg_map.per_pool_sum_delta.begin();
         it != pg_map.per_pool_sum_delta.end(); ) {
      utime_t age = ceph_clock_now() - it->second.second;
      if (age > 2*g_conf->mon_delta_reset_interval) {
    dout(10) << " clearing pg_map delta for pool " << it->first
             << " (" << age << " > " << g_conf->mon_delta_reset_interval
             << " seconds old)" << dendl;
    pg_map.per_pool_sum_deltas.erase(it->first);
    pg_map.per_pool_sum_deltas_stamps.erase(it->first);
    pg_map.per_pool_sum_delta.erase((it++)->first);
      } else {
    ++it;
      }
    }
  }

  dout(10) << pg_map << dendl;
}

调用了void PGMonitor::handle_osd_timeouts()

void PGMonitor::handle_osd_timeouts()
{
  if (!mon->is_leader())
    return;
  if (did_delete)
    return;

  utime_t now(ceph_clock_now());
  utime_t timeo(g_conf->mon_osd_report_timeout, 0);
  if (now - mon->get_leader_since() < timeo) {
    // We haven't been the leader for long enough to consider OSD timeouts
    //
    return;
  }

  if (mon->osdmon()->is_writeable())
  //调用了osdmon的handle_osd_timeouts
    mon->osdmon()->handle_osd_timeouts(now, last_osd_report);
}

bool OSDMonitor::handle_osd_timeouts(const utime_t &now,std::map

bool OSDMonitor::handle_osd_timeouts(const utime_t &now,
                     std::map<int,utime_t> &last_osd_report)
{
  utime_t timeo(g_conf->mon_osd_report_timeout, 0);
  if (now - mon->get_leader_since() < timeo) {
    // We haven't been the leader for long enough to consider OSD timeouts
    return false;
  }

  int max_osd = osdmap.get_max_osd();
  bool new_down = false;

  for (int i=0; i < max_osd; ++i) {
    dout(30) << __func__ << ": checking up on osd " << i << dendl;
    if (!osdmap.exists(i)) {
      last_osd_report.erase(i); // if any
      continue;
    }
    if (!osdmap.is_up(i))
      continue;
    const std::map<int,utime_t>::const_iterator t = last_osd_report.find(i);
    if (t == last_osd_report.end()) {
      // it wasn't in the map; start the timer.
      last_osd_report[i] = now;
    } else if (can_mark_down(i)) {
      utime_t diff = now - t->second;
      if (diff > timeo) {
    mon->clog->info() << "osd." << i << " marked down after no beacon for "
              << diff << " seconds";
    derr << "no beacon from osd." << i << " since " << t->second
         << ", " << diff << " seconds ago.  marking down" << dendl;
    pending_inc.new_state[i] = CEPH_OSD_UP;
    new_down = true;
      }
    }
  }
  return new_down;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值