CLIENT数据流向OSD

CLIENT数据流向OSD

ceph-osd.cc

ceph_osd.cc中main函数是ceph-osd守护进程的入口,目前OSD会创建注册7个Messenger实例

Messenger实例名称作用
ms_public用来处理OSD和Client之间的消息
ms_cluster用来处理OSD和集群其他OSD及MON之间的消息
ms_hb_back_client用来处理client接收心跳消息
ms_hb_front_client用来处理client发送心跳消息
ms_hb_back_server用来处理OSD接收心跳消息
ms_hb_front_server用来处理OSD发送心跳消息
ms_objecter用来处理OSD和Objecter之间的消息
ceph-osd.cc int main(int argc, const char **argv)
{
  Messenger *ms_public = Messenger::create(g_ceph_context, public_msg_type,
					   entity_name_t::OSD(whoami), "client", nonce);
  Messenger *ms_cluster = Messenger::create(g_ceph_context, cluster_msg_type,
					    entity_name_t::OSD(whoami), "cluster", nonce);
  Messenger *ms_hb_back_client = Messenger::create(g_ceph_context, cluster_msg_type,
					     entity_name_t::OSD(whoami), "hb_back_client", nonce);
  Messenger *ms_hb_front_client = Messenger::create(g_ceph_context, public_msg_type,
					     entity_name_t::OSD(whoami), "hb_front_client", nonce);
  Messenger *ms_hb_back_server = Messenger::create(g_ceph_context, cluster_msg_type,
						   entity_name_t::OSD(whoami), "hb_back_server", nonce);
  Messenger *ms_hb_front_server = Messenger::create(g_ceph_context, public_msg_type,
						    entity_name_t::OSD(whoami), "hb_front_server", nonce);
  Messenger *ms_objecter = Messenger::create(g_ceph_context, public_msg_type,
					     entity_name_t::OSD(whoami), "ms_objecter", nonce);

osdptr = new OSD(g_ceph_context,
		   std::move(store),
		   whoami,
		   ms_cluster,
		   ms_public,
		   ms_hb_front_client,
		   ms_hb_back_client,
		   ms_hb_front_server,
		   ms_hb_back_server,
		   ms_objecter,
		   &mc,
		   data_path,
		   journal_path,
		   poolctx);
ms_public->start();

err = osdptr->init();

ms_public->wait();
}

OSD.cc

ms_public 传到init中的是client_messenger,add_dispatcher_tail会将OSD dispatch添加到client_messenger,后期会调用OSD 类中的ms_fast_dispatch函数

int OSD::init(){
  // i'm ready!
  client_messenger->add_dispatcher_tail(&mgrc);
  client_messenger->add_dispatcher_tail(this);
  cluster_messenger->add_dispatcher_head(this);

  hb_front_client_messenger->add_dispatcher_head(&heartbeat_dispatcher);
  hb_back_client_messenger->add_dispatcher_head(&heartbeat_dispatcher);
  hb_front_server_messenger->add_dispatcher_head(&heartbeat_dispatcher);
  hb_back_server_messenger->add_dispatcher_head(&heartbeat_dispatcher);

  objecter_messenger->add_dispatcher_head(service.objecter.get());
}

Messenger.h

Messenger是一个基类,AsyncMessenger继承该类。add_dispatcher_head/add_dispatcher_tail都会调用 ready();Messenger中的ready()函数为虚函数,会执行子类(AsyncMessenger)中的ready()函数。

 /**
   * Add a new Dispatcher to the front of the list. If you add
   * a Dispatcher which is already included, it will get a duplicate
   * entry. This will reduce efficiency but not break anything.
   *
   * @param d The Dispatcher to insert into the list.
   */
  void add_dispatcher_head(Dispatcher *d) {
    bool first = dispatchers.empty();
    dispatchers.push_front(d);
    if (d->ms_can_fast_dispatch_any())
      fast_dispatchers.push_front(d);
    if (first)
      ready();
  }
  /**
   * Add a new Dispatcher to the end of the list. If you add
   * a Dispatcher which is already included, it will get a duplicate
   * entry. This will reduce efficiency but not break anything.
   *
   * @param d The Dispatcher to insert into the list.
   */
  void add_dispatcher_tail(Dispatcher *d) {
    bool first = dispatchers.empty();
    dispatchers.push_back(d);
    if (d->ms_can_fast_dispatch_any())
      fast_dispatchers.push_back(d);
    if (first)
      ready();
  }

AsyncMessenger.c

AsyncMessenger ready函数执行的是dispatch_queue类中的start函数。

void AsyncMessenger::ready()
{
  ldout(cct,10) << __func__ << " " << get_myaddrs() << dendl;

  stack->ready();
  if (pending_bind) {
    int err = bindv(pending_bind_addrs);
    if (err) {
      lderr(cct) << __func__ << " postponed bind failed" << dendl;
      ceph_abort();
    }
  }

  std::lock_guard l{lock};
  for (auto &&p : processors)
    p->start();
  dispatch_queue.start();
}

DispatchQueue.cc

DispatchQueue中的start函数会执行local_delivery_thread的create函数

void DispatchQueue::start()
{
  ceph_assert(!stop);
  ceph_assert(!dispatch_thread.is_started());
  dispatch_thread.create("ms_dispatch");
  local_delivery_thread.create("ms_local");
}

Thread.cc

local_delivery_thread.create会执行Thread::try_create函数,该函数是创建一个线程

int Thread::try_create(size_t stacksize)
{
  pthread_attr_t *thread_attr = NULL;
  pthread_attr_t thread_attr_loc;
  
  stacksize &= CEPH_PAGE_MASK;  // must be multiple of page
  if (stacksize) {
    thread_attr = &thread_attr_loc;
    pthread_attr_init(thread_attr);
    pthread_attr_setstacksize(thread_attr, stacksize);
  }

  int r;

  // The child thread will inherit our signal mask.  Set our signal mask to
  // the set of signals we want to block.  (It's ok to block signals more
  // signals than usual for a little while-- they will just be delivered to
  // another thread or delieverd to this thread later.)

  #ifndef _WIN32
  sigset_t old_sigset;
  if (g_code_env == CODE_ENVIRONMENT_LIBRARY) {
    block_signals(NULL, &old_sigset);
  }
  else {
    int to_block[] = { SIGPIPE , 0 };
    block_signals(to_block, &old_sigset);
  }
  r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
  restore_sigset(&old_sigset);
  #else
  r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
  #endif

  if (thread_attr) {
    pthread_attr_destroy(thread_attr);	
  }

  return r;
}

DispatchQueue.h

线程函数为local_delivery_thread中的entry函数,该函数会继续调用DispatchQueue中的run_local_delivery函数

  class LocalDeliveryThread : public Thread {
    DispatchQueue *dq;
  public:
    explicit LocalDeliveryThread(DispatchQueue *dq) : dq(dq) {}
    void *entry() override {
      dq->run_local_delivery();
      return 0;
    }
  } local_delivery_thread;

DispatchQueue.cc

run_local_delivery函数会执行fast_dispatch函数,进行分发消息

  void DispatchQueue::run_local_delivery()
{
  std::unique_lock l{local_delivery_lock};
  while (true) {
    if (stop_local_delivery)
      break;
    if (local_messages.empty()) {
      local_delivery_cond.wait(l);
      continue;
    }
    auto p = std::move(local_messages.front());
    local_messages.pop();
    l.unlock();
    const ref_t<Message>& m = p.first;
    int priority = p.second;
    fast_preprocess(m);
    if (can_fast_dispatch(m)) {
      fast_dispatch(m);
    } else {
      enqueue(m, priority, 0);
    }
    l.lock();
  }
}

DispatchQueue.h

fast_dispatch为重载函数,最终执行Messenger中的ms_fast_dispatch

void fast_dispatch(Message* m) {
    return fast_dispatch(ceph::ref_t<Message>(m, false)); /* consume ref */
  }
  
void DispatchQueue::fast_dispatch(const ref_t<Message>& m)
{
  uint64_t msize = pre_dispatch(m);
  msgr->ms_fast_dispatch(m);
  post_dispatch(m, msize);
}

Messenger.h

ms_fast_dispatch会调用dispatcher的ms_fast_dispatch2

  /**
   * Deliver a single Message via "fast dispatch".
   *
   * @param m The Message we are fast dispatching.
   * If none of our Dispatchers can handle it, ceph_abort().
   */
  void ms_fast_dispatch(const ceph::ref_t<Message> &m) {
    m->set_dispatch_stamp(ceph_clock_now());
    for (const auto &dispatcher : fast_dispatchers) {
      if (dispatcher->ms_can_fast_dispatch2(m)) {
	dispatcher->ms_fast_dispatch2(m);
	return;
      }
    }
    ceph_abort();
  }

Dispatcher.h

dispatcher的ms_fast_dispatch2会执行ms_fast_dispatch,dispatcher类中的ms_fast_dispatch为虚函数,会调用子类的ms_fast_dispatch函数,最终执行了OSD::ms_fast_dispatch

   virtual void ms_fast_dispatch2(const MessageRef &m) {
    /* allow old style dispatch handling that expects a Message * with a floating ref */
    return ms_fast_dispatch(MessageRef(m).detach()); /* XXX N.B. always consumes ref */
  }

流程图概览

Ceph-osd::main
	Messenger::create
	OSD::OSD
	OSD::init
		Messenger::add_dispatcher_tail
		Messenger::add_dispatcher_head
			AsyncMessenger::ready
				DispatchQueue::start
					local_delivery_thread::create
						local_delivery_thread::entry
							DispatchQueue::run_local_delivery
								DispatchQueue::fast_dispatch
									DispatchQueue::fast_dispatch(const ref_t<Message>& m)
										Messenger::ms_fast_dispatch
											Dispatcher::ms_fast_dispatch2
												OSD::ms_fast_dispatch
											
注:class OSD : public Dispatcher										
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值