PG的创建是由monitor节点发起,形成请求message发送给osd,在osd上创建pg。
1. 在monitor中由PGmonitor发现是否创建了pool,pool中是否存在pg需要进行创建。首先来看函数PGMonitor::register_new_pgs()
1059:循环遍历当前这个pool中的所有pg。
1061:根据当前这个pool中pg的序号和pool的id,形成pg_id。(pg_id 就是用来统计哪个pool中的第几个pg而已,使用mseed作为pg序号,mpool作为pool序号)。
1062:pg_map中统计了所有的pg,如果发现当前的pg不再pg_map中,说明这个pg是需要被创建的。
1068:使用register_pg函数开始处理申请这个pg。
2.register_pg()函数开始对pg的申请进行处理,这时已经有了pg_id 和pool的信息。
1007:将刚刚创建的pg_id统计到pending_inc.pg_stat_updates结构中。
1008:设置这个pg的状态为PG_STATE_CREATING。
接下来会将这个pending_inc 进行打包,然后推行propose_pending,开始提议议题,等待完成最后推行。
3.决策推行函数update_from_paxos,在这里会根据仲裁决定,然后处理结果,上面说道已经推行了创建pg。
0232:重新解码inc 的决议。
0242:将这个决议交给pg_map进行处理,调用PGMap::apply_incremental()
0295: map_pg_creates将需要创建的pg进行映射到 对应的pg上面。
0296:send_pg_creates 开始将已经准备下发给osd的message。
4.先来看看这个PGMap::apply_incremental(),在函数内会从新解析pg_stat_updates中的成员,获取每一个成员的pg_id和pg_state。然后将这两个参数交给stat_pg_add()
0482:如果当前的pg_state 状态是PG_STATE_CREATING,代表他需要被创建。
0484:将这个pg_id添加creating_pgs的队列中,等待被处理。
5.当需要被创建的pg_id已经添加到creating_pgs中之后,就会继续交给map_pg_creates()处理了,下面看看这个函数。
1143:开始尝试遍历creating_pgs的队列。
1146:重新解析pg_id。
1149:判断这个pg是否已经存在了。当然第一次创建pg这里是不会出现的。
1165:这里根据pg_id等信息可以找到osd的集合,并且知道那些是主osd。
1191:在pg_map中同样存在一个队列creating_pgs_by_osd,这个队列中保存着每个osd需要创建的pg。
6.这样这个创建pg的请求就转化成了creating_pgs_by_osd队列的处理了,下面看下处理这个队列的函数send_pg_creates().在这里按着osd进行处理继续分发到send_pg_creates(osd,con)中进行处理。
1239:这时创建一个用于传递创建pg的消息 MOSDPGCreate。
1240:开始整理这个osd上所有需要创建的pg_id.
1242:将这个需要创建的pg都封装到m的mkpg中。
接下来就是通过monitor的messager模块将消息发送给了osd。接下来看看osd的处理。消息封装解封的过程就不描述了。
osd这时会收到一个消息 根据消息命令字MSG_OSD_PG_CREATE,发现这是一个创建pg的消息,然后交给handle_pg_create进行处理。
7225:handle_pg_create开始处理创建pg的请求。
7227:从消息请求op中恢复出MOSDPGCreate 的message。
7269:在消息中恢复了所有的pg请求。
7280:解析出pg的编号pg_id到变量on上。
7320:根据pg_id的on开始创建出spg_t的pgid。spg_t结构中主要记录两个信息,一个是pg_id的序号,另外一个就是primary的osd序号。
7362:将history信息根据pgid添加到creating_pgs结构中。
7363:将parent信息根据pgid添加到creating_pgs结构中。
7364:将acting信息根据pgid添加到creating_pgs结构中。
7365:开始获取当前pg的所有osd信息 根据pgid添加到creating_pgs结构中。
7400:开始准备创建一个pg了,调用函数_create_lock_pg().该函数中继续调用_open_lock_pg()、_make_pg()来创建PG。
2548:判断这个pool的类型是replicated 还是erasure类型的。
2551:这里开始创建PG,这个PG的具体实现方式就是ReplicatedPG。
然后在回到函数handle_pg_create中继续进行pg->handle_create(&rctx);
pg->handle_create 开始一个pg的状态处理。后面的章节会描述pg状态的变化过程。pg的状态变化过程叫做peering。