ceph df 命令的实现

内核ACPI函数API之acpi_parse_spcr

monitor 所有的命令都在void Monitor::handle_command(MonOpRequestRef op) 中实现
我们以ceph df的实现为例分析,下面这个函数就是handle_command 这个函数中对df 命令的解析
else if (prefix == "df") {
      bool verbose = (detail == "detail");
      if (f)
        f->open_object_section("stats");

      mgrstatmon()->dump_fs_stats(&ds, f.get(), verbose);
      if (!f)
        ds << '\n';
      mgrstatmon()->dump_pool_stats(osdmon()->osdmap, &ds, f.get(), verbose);

      if (f) {
        f->close_section();
        f->flush(ds);
        ds << '\n';
      }
    }
可以看到df命令主要会更新fs和pool的status。我们这里以fs stat的更新为例
ceph-master\src\mon\PGMap.cc
void PGMapDigest::dump_fs_stats(stringstream *ss, Formatter *f, bool verbose) const
{
  if (f) {
    f->open_object_section("stats");
    f->dump_int("total_bytes", osd_sum.kb * 1024ull);
    f->dump_int("total_used_bytes", osd_sum.kb_used * 1024ull);
    f->dump_int("total_avail_bytes", osd_sum.kb_avail * 1024ull);
    if (verbose) {
      f->dump_int("total_objects", pg_sum.stats.sum.num_objects);
    }
    f->close_section();
  }
}
这里假定f不为null,可以主要的信息是从osd_sum 中获得的,这个osd_sum 是所有osd值得累加,那单个osd的统计信息是在哪里更新的呢?
\ceph-master\src\osd\OSD.cc
void OSDService::update_osd_stat(vector<int>& hb_peers)
{
  // load osd stats first
  struct store_statfs_t stbuf;
  #调用filestore的statfs函数,
  int r = osd->store->statfs(&stbuf);
  if (r < 0) {
    derr << "statfs() failed: " << cpp_strerror(r) << dendl;
    return;
  }
	#根据从filestore得到的值给osd_sum 赋值
  auto new_stat = set_osd_stat(stbuf, hb_peers, osd->get_num_pgs());
  dout(20) << "update_osd_stat " << new_stat << dendl;
  assert(new_stat.kb);
  float ratio = ((float)new_stat.kb_used) / ((float)new_stat.kb);
  check_full_status(ratio);
}


osd_stat_t OSDService::set_osd_stat(const struct store_statfs_t &stbuf,
                                    vector<int>& hb_peers,
				    int num_pgs)
{
  uint64_t bytes = stbuf.total;
  uint64_t used = bytes - stbuf.available;
  uint64_t avail = stbuf.available;

  osd->logger->set(l_osd_stat_bytes, bytes);
  osd->logger->set(l_osd_stat_bytes_used, used);
  osd->logger->set(l_osd_stat_bytes_avail, avail);

  {
    Mutex::Locker l(stat_lock);
    osd_stat.hb_peers.swap(hb_peers);
    osd->op_tracker.get_age_ms_histogram(&osd_stat.op_queue_age_hist);
    osd_stat.kb = bytes >> 10;
    osd_stat.kb_used = used >> 10;
    osd_stat.kb_avail = avail >> 10;
    osd_stat.num_pgs = num_pgs;
    return osd_stat;
  }
}
从set_osd_stat 中很清楚的可以看出从filestore 中得到值赋值给osd_stat的过程
最后我们再看看 osd->store->statfs的实现。
int FileStore::statfs(struct store_statfs_t *buf0)
{
  struct statfs buf;
  buf0->reset();
  if (::statfs(basedir.c_str(), &buf) < 0) {
    int r = -errno;
    assert(!m_filestore_fail_eio || r != -EIO);
    assert(r != -ENOENT);
    return r;
  }
  buf0->total = buf.f_blocks * buf.f_bsize;
  buf0->available = buf.f_bavail * buf.f_bsize;
  return 0;
}
原来filestore 中直接调用statfs来读取统计值得

猜你喜欢

转载自blog.csdn.net/tiantao2012/article/details/80054959