Ceph网络模块代码的示例分析

这篇文章主要为大家展示了“Ceph网络模块代码的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Ceph网络模块代码的示例分析”这篇文章吧。

创新互联建站是一家集成都做网站、成都网站设计、网站页面设计、网站优化SEO优化为一体的专业的建站公司,已为成都等多地近百家企业提供网站建设服务。追求良好的浏览体验,以探求精品塑造与理念升华,设计最适合用户的网站页面。 合作只是第一步,服务才是根本,我们始终坚持讲诚信,负责任的原则,为您进行细心、贴心、认真的服务,与众多客户在蓬勃发展的市场环境中,互促共生。

1. 创建消息管理类Messenger.

Messenger *ms_public = Messenger::create(g_ceph_context,
                                           entity_name_t::OSD(whoami), "client",
                                           getpid());

在这里函数这里创建了若干个Messenger实例,ms_public实例只是其中的一个.从这个函数参数"client"也能看出一些端倪,说明这个Messenger是专门用于
处理"客户端"的消息的,这里的客户端指的是诸如RGW, RBD这样的客户端. 而后面的ms_cluster则处理与其它OSD的消息。

2. 绑定端口和地址

然后在后面,就像Linux Socket编程一样, 在这里也需要调用bind()函数完成端口以及地址的绑定, 只不过这里bind()函数是经过特殊封装后的.

ms_public->bind(g_conf->public_addr);

Messenger是一个抽象类, ms_public是一个基类指针.
而类SimpleMessenger继承自Messenger.

最终调用的bind()函数是子类SimpleMessenger::bind(const entity_addr_t &bind_addr)

int SimpleMessenger::bind(const entity_addr_t &bind_addr)
{
  lock.Lock();
  if (started) {
    ldout(cct,10) << "rank.bind already started" << dendl;
    lock.Unlock();
    return -1; 
  }
  ldout(cct,10) << "rank.bind " << bind_addr << dendl;
  lock.Unlock();

  // bind to a socket
  set avoid_ports;
  int r = accepter.bind(bind_addr, avoid_ports);
  if (r >= 0)
    did_bind = true;
  return r;
}

这里的entity_addr_t实际是socket通信中需要用到的sockaddr_in,AF_INET/AF_INET6的集合.
继续调用成员accepter.bind(bind_addr, avoid_ports);
在msg/Accepter.cc中可以看到:

int Accepter::bind(const entity_addr_t &bind_addr, const set& avoid_ports)

这个函数执行了:

1)创建一个socket fd.

2)执行bind()

3)执行listen()
以上都是socket编程中基本操作步骤.

3. 启动"服务端"

ms_public->start();


实际上调用的是:
 

int SimpleMessenger::start()
{
  lock.Lock();
  ldout(cct,1) << "messenger.start" << dendl;

  // register at least one entity, first!
  assert(my_type >= 0);

  assert(!started);
  started = true;

  if (!did_bind) {
    my_inst.addr.nonce = nonce;
    init_local_connection();
  }

  lock.Unlock();

  reaper_started = true;
  reaper_thread.create();
  return 0;
}

从这里可以看出,reaper_thread.create()创建了一个reaper线程.找到它的void *entry()函数.//SimpleMessenger.h

reaper线程实际上执行的是void SimpleMessenger::reaper_entry(), 它最终执行/调用的是:

void SimpleMessenger::reaper()
{
  ldout(cct,10) << "reaper" << dendl;
  assert(lock.is_locked());

  while (!pipe_reap_queue.empty()) {
    Pipe *p = pipe_reap_queue.front();
    pipe_reap_queue.pop_front();
    ldout(cct,10) << "reaper reaping pipe " << p << " " << p->get_peer_addr() << dendl;
    p->pipe_lock.Lock();
    p->discard_out_queue();
    if (p->connection_state) {
      // mark_down, mark_down_all, or fault() should have done this,
      // or accept() may have switch the Connection to a different
      // Pipe... but make sure!
      bool cleared = p->connection_state->clear_pipe(p);
      assert(!cleared);
    }
    p->pipe_lock.Unlock();
    p->unregister_pipe();
    assert(pipes.count(p));
    pipes.erase(p);
    p->join();
    if (p->sd >= 0)
      ::close(p->sd);
    ldout(cct,10) << "reaper reaped pipe " << p << " " << p->get_peer_addr() << dendl;
    p->put();
    ldout(cct,10) << "reaper deleted pipe " << p << dendl;
  }
  ldout(cct,10) << "reaper done" << dendl;
}

从这里可以看出做出了清理Pipe的操作. (?)

4. 最后一步:

delete ms_public;


通过以上4步, OSD(服务端)关于网络方面的工作算是初始化完毕了.工作只是准备阶段,并不复杂.

以上是“Ceph网络模块代码的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!


标题名称:Ceph网络模块代码的示例分析
新闻来源:http://myzitong.com/article/pejhhd.html