ceph-mon.CC代码阅读记录

本文详细介绍了Ceph RadosGW的启动流程,包括创建ceph上下文、启动定时器线程、心跳线程及AdminSocket线程等内容。此外还探讨了RadosClient的工作原理及其与SimpleMessenger之间的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

main函数中的流程:

解析参数
创建ceph上下文-------->创建Log线程---等待日志消息(void Log::submit_entry(Entry *e) 为创建日志消息接口)
              -------->创建md_config_t(观察者模式,配置文件发生变化,通知所有观察者)
              -------->创建AdminSocket(处理命令消息)
              -------->创建钩子函数类_admin_hook,
              -------->绑定AdminSocket与_admin_hook,消息来后调用do_command函数,执行对应的钩子函数处理消息
rgw_main.cc
创建ceph上下文
启动safe_timer定时器线程 到时间做什么事情,比如启动时间超时,程序退出
启动心跳线程
启动admin_socket线程
加载appche的文件类型rgw_tools_init(g_ceph_context);
rgw初始化rados init_rados---》init_complete 链接上集群环境

r = rgw_perf_start(g_ceph_context);
rgw_rest_init(g_ceph_context, store, store->get_zonegroup());

  rgw_user_init(store);
  rgw_bucket_init(store->meta_mgr);
  rgw_log_usage_init(g_ceph_context, store);
 


启动radosgw进程,自己给自己发消息用

RadosClient启动启动safe_timer线程 到时间做什么事情,
RadosClient中的simpleMessenger中有两个队列:一个"fast dispatch“队列,一个非"fast dispatch”队列,调用add_dispatcher_tail会触发ready接口,创建线程处理两个队列的消息
RadosClient中创建“ms_reaper”线程,销毁管道当完成时


 SimpleMessenger中的几个管道list:
 /**
   * hash map of addresses to Pipes
   *
   * NOTE: a Pipe* with state CLOSED may still be in the map but is considered
   * invalid and can be replaced by anyone holding the msgr lock
   */
  ceph::unordered_map<entity_addr_t, Pipe*> rank_pipe;
  /**
   * list of pipes are in teh process of accepting
   *
   * These are not yet in the rank_pipe map.
   */
  set<Pipe*> accepting_pipes;
  /// a set of all the Pipes we have which are somehow active
  set<Pipe*>      pipes;
  /// a list of Pipes we want to tear down
  list<Pipe*>     pipe_reap_queue;
 
Messenger类的 add_dispatcher_head和add_dispatcher_tail调用SimpleMessenger类的ready()
SimpleMessenger类的ready接口创建两个线程:“ms_dispatch”(运行DispatchQueue->entry)和"ms_local"(运行DispatchQueue->run_local_delivery)
这两个线程的功能如下:
     “ms_dispatch”:安装优先级分发队列PrioritizedQueue<QueueItem, uint64_t> mqueue; QueueItem里面有智能指针ConnectionRef<Connection> con和MessageRef<Message> m;
*此功能将传入消息传递给信使。
*管道的消息被保留在队列中;当开始时
*交付的最高优先级队列被选中,管道从
*队列的前面被删除,并将其信息读取。如果管道
*将剩余的信息放在优先级别,将其重新放置到结束。如果队列是空的,它被删除。该消息随后被传递,进程重新启动

     "ms_local":处理本地消息队列list<pair<Message*, int> > local_messages 按照优先级分发到mqueue中
    
调用Accepter的start接口init_local_connection调用Messenger类的ms_deliver_handle_fast_connect便利fast_dispatchers list调用ms_handle_fast_connect
Accepter类负责socket的相关操作,例如socket,bind,listen等
          start接口创建一个“ms_accepter”线程,对端口进行监听接收消息,来新消息后创建一个Pipe类(里面有负责read消息和write消息),设置状态为accepting,启动一个“ms_pipe_read”线程读取消息(这里启动accept()方法启动writer线程),放入SimpleMessenger上述中的管道accepting_pipes list和pipes list中。

Dispatcher类调度分发类
包含所有管道的消息
他们要被派遣,仔细组织的信息优先级
允许将以循环的方式。
参见simplemessenger::dispatch_entry详情。


消息类型
/* used by message exchange protocol */
#define CEPH_MSGR_TAG_READY         1  /* server->client: ready for messages */
#define CEPH_MSGR_TAG_RESETSESSION  2  /* server->client: reset, try again */
#define CEPH_MSGR_TAG_WAIT          3  /* server->client: wait for racing
                      incoming connection */
#define CEPH_MSGR_TAG_RETRY_SESSION 4  /* server->client + cseq: try again
                      with higher cseq */
#define CEPH_MSGR_TAG_RETRY_GLOBAL  5  /* server->client + gseq: try again
                      with higher gseq */
#define CEPH_MSGR_TAG_CLOSE         6  /* closing pipe */
#define CEPH_MSGR_TAG_MSG           7  /* message */
#define CEPH_MSGR_TAG_ACK           8  /* message ack */
#define CEPH_MSGR_TAG_KEEPALIVE     9  /* just a keepalive byte! */
#define CEPH_MSGR_TAG_BADPROTOVER  10  /* bad protocol version */
#define CEPH_MSGR_TAG_BADAUTHORIZER 11 /* bad authorizer */
#define CEPH_MSGR_TAG_FEATURES      12 /* insufficient features */
#define CEPH_MSGR_TAG_SEQ           13 /* 64-bit int follows with seen seq number */
#define CEPH_MSGR_TAG_KEEPALIVE2     14
#define CEPH_MSGR_TAG_KEEPALIVE2_ACK 15  /* keepalive reply */


void Pipe::writer
write_message
do_sendmsg
sendmsg


pipe::reader
pipe::read_message
cond.Signal;  // 唤醒writer进入_get_next_outgoing
DispatchQueue::enqueue
DispatchQueue::cond.Signal  // 唤醒DispatchQueue::entry()分发给Messenger对应的方法(里面调用了Dispatcher相应的方法)


pthread_cond_wait的内部操作
   在调用之前需要锁定互斥对象,然后再调用pthread_cond_wait。
  1> pthread_cond_wait所做的第一件事就是同时对互斥对象解锁(这样其它线程就可以修改共享对象了,操作之前不要忘记加锁哦)。
  2> 等待条件通常是一个阻塞操作(这一点有点不明白,为什么是通常,难道说是还有其它动作,有知道的可以告诉我啊),这意味着线程将睡眠,在它苏醒之前不会消耗cpu周期(这正是我们想要的).线程睡呀睡呀,直到,有人叫它, 比如:另一个线程锁定了mymutex,并对共享对象对了某个动作.在对互斥对象解锁之后(this is very important),2号线程会立即调用函数pthread_cond_broadcast(&mycond)(这个地方也有点不明白, 我想不一定需要立即调用pthread_cond_broadcast,日比如有一个共享的线程数目 pthread_num = 5,当创建一个线程的时候pthread_num++,但是当该线程结束的时候pthread_num--,如果这个数小于5,我们就可以广播一下这个事件,激活一个线程,用以创建更多的线程)。
  3> 调用pthread_cond_wait的线程被叫醒之后,将重新锁定mymutex,之后才返回。
 
set scheduler-locking off|on|step 估计是实际使用过多线程调试的人都可以发现,在使用step或者continue命令调试当前被调试线程的时候,其他线程也是同时执行的,怎么只让被调试程序执行呢?通过这个命令就可以实现这个需求。off 不锁定任何线程,也就是所有线程都执行,这是默认值。 on 只有当前被调试程序会执行。 step 在单步的时候,除了next过一个函数的情况(熟悉情况的人可能知道,这其实是一个设置断点然后continue的行为)以外,只有当前线程会执行。

set scheduler-locking on|step

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值