cinder創(chuàng)建卷源碼流程分析

  1. 調(diào)用/cinder/api/v3/volumes.py文件中VolumeController類下的create方法

    # 參數(shù)驗(yàn)證
    self.validate_name_and_description(volume, check_length=False)
    ...
    # 如果基于快照創(chuàng)建卷究孕,通過下面方法獲取快照數(shù)據(jù)
    kwargs['snapshot'] = self.volume_api.get_snapshot(context, snapshot_id)
    # 如果基于卷創(chuàng)建卷瞭亮,通過下面方法獲取源卷數(shù)據(jù)
    kwargs['source_volume'] = (self.volume_api.get_volume(context, ource_volid))
    # 基于一致性群組id或群組id獲取組數(shù)據(jù)
    kwargs['group'] = self.group_api.get(context, consistencygroup_id)
    或者
    kwargs['group'] = self.group_api.get(context, group_id)
    # 如果基于鏡像創(chuàng)建卷芥喇,通過下面方法獲取鏡像數(shù)據(jù)
    image_uuid = self._image_uuid_from_ref(image_ref, context)
    image_snapshot = self._get_image_snapshot(context, image_uuid)
    # 如果基于卷備份創(chuàng)建卷,通過下面方法獲取備份數(shù)據(jù)
    kwargs['backup'] = self.backup_api.get(context, backup_id=backup_id)
    # 最后調(diào)用下面方法創(chuàng)建卷
    new_volume = self.volume_api.create(...)
    # 方法指向
    from cinder import volume as cinder_volume
    self.volume_api = cinder_volume.API()
    
  2. 調(diào)用/cinder/volume/api.py文件中API類下的create方法

    # 參數(shù)驗(yàn)證
    ...
    # 獲取調(diào)度rpc接口
    sched_rpcapi = (self.scheduler_rpcapi if (not cgsnapshot and not source_cg and not group_snapshot and not source_group) else None)
    # 獲取卷操作rpc接口
    volume_rpcapi = (self.volume_rpcapi if (not cgsnapshot and not source_cg and not group_snapshot and not source_group) else None)
    # 獲取鏡像操作的api接口
    self.image_service = (image_service or glance.get_default_image_service())
    # 構(gòu)建用于建立卷的flow
    flow_engine = create_volume.get_flow(self.db, self.image_service, availability_zones, create_what, sched_rpcapi, volume_rpcapi)     # /cinder/volume/flows/api/create_volume.py
        ->  # 調(diào)用get_flow(...)方法百匆。
        ->  # flow_name = ACTION.replace(":", "_") + "_api, 即為volume_create_api。
        ->  # 初始化flow類:api_flow = linear_flow.Flow(flow_name)逗嫡。
        ->  # 添加一個task到flow中:api_flow.add(base.InjectTask(create_what, addons=[ACTION]))育瓜。
            ->  # InjectTask:這個類實(shí)現(xiàn)了注入字典信息create_what到flow中葫隙。
        ->  # 添加一個給定的task到flow: api_flow.add(ExtractVolumeRequestTask(...))。
            ->  # ExtractVolumeRequestTask:實(shí)現(xiàn)提取并驗(yàn)證輸入的請求信息躏仇,并返回經(jīng)過驗(yàn)證的參數(shù)信息恋脚。
        ->  # 添加給定的task到flow:   api_flow.add(QuotaReserveTask(), EntryCreateTask(), QuotaCommitTask())腺办。
            ->  # QuotaReserveTask:根據(jù)給定的大小值和給定的卷類型信息實(shí)現(xiàn)保存單一的卷。
            ->  # EntryCreateTask:在數(shù)據(jù)庫中為給定的卷建立相關(guān)條目慧起。
                ->  # QuotaCommitTask:提交新的資源配額的預(yù)留信息到數(shù)據(jù)庫中菇晃。
        ->  # 添加給定的task到flow:   api_flow.add(VolumeCastTask(scheduler_rpcapi, volume_rpcapi, db_api))。
            ->  # VolumeCastTask:遠(yuǎn)程調(diào)用實(shí)現(xiàn)卷的建立操作蚓挤。
    # VolumeCastTask卷操作
        ->  # 首先調(diào)用`execute(...)`方法。
        ->  # 接著調(diào)用`self._cast_create_volume(...)`方法驻子。
        ->  # 最后點(diǎn)用`self.scheduler_rpcapi.create_volume(...)`方法灿意。
    # 運(yùn)行用于建立卷的flow
    flow_engine.run()
    # 方法指向
    from cinder.scheduler import rpcapi as scheduler_rpcapi
    scheduler_rpcapi = scheduler_rpcapi.SchedulerAPI()
    self.scheduler_rpcapi = scheduler_rpcapi
    
  3. 調(diào)用/cinder/scheduler/rpcapi.py文件中SchedulerAPI類下的create_volume方法

    cctxt.cast(ctxt, 'create_volume', **msg_args)
    # 通過rpc服務(wù)將數(shù)據(jù)發(fā)送到mq隊(duì)列中
    
  4. 調(diào)用/cinder/scheduler/manager.py文件中SchedulerManager類下的create_volume方法

    # 構(gòu)建并返回用于通過遠(yuǎn)程調(diào)度建立卷的flow
    flow_engine = create_volume.get_flow()  # /cinder/scheduler/flows/create_volume.py
        ->  # flow_name = ACTION.replace(":", "_") + "_scheduler", 即為volume_create_scheduler。
      ->    # 初始化flow類:scheduler_flow = linear_flow.Flow(flow_name)崇呵。
      ->    #   添加一個給定的task到flow:scheduler_flow.add(ExtractSchedulerSpecTask(...))缤剧。
            ->  # ExtractSchedulerSpecTask:實(shí)現(xiàn)了從輸入的參數(shù)中提取調(diào)度器的規(guī)范信息的操作。
      ->    # 添加一個給定的task到flow:scheduler_flow.add(ScheduleCreateVolumeTask(driver_api))域慷。
            ->  # ScheduleCreateVolumeTask:遠(yuǎn)程調(diào)用實(shí)現(xiàn)卷的建立操作荒辕。
    # ScheduleCreateVolumeTask卷操作
        ->  # 首先調(diào)用`execute(...)`方法。
        ->  # 接著調(diào)用`self.driver_api.schedule_create_volume(...)`方法犹褒。
    # 運(yùn)行用于建立卷的flow
    flow_engine.run()
    # 方法指向
    scheduler_driver = CONF.scheduler_driver        # 即為cinder.scheduler.filter_scheduler.FilterScheduler
    self.driver = importutils.import_object(scheduler_driver)   # 加載類
    driver_api = self.driver
    self.driver_api = driver_api
    
  5. 調(diào)用/cinder/scheduler/filter_scheduler.py文件中FilterScheduler類下的schedule_create_volume方法

    # 過濾稱重操作抵窒,獲取最優(yōu)后端
    backend = self._schedule(context, request_spec, filter_properties)
    # 數(shù)據(jù)庫卷數(shù)據(jù)更新
    updated_volume = driver.volume_update_db(...)
    # 最后調(diào)用,遠(yuǎn)程調(diào)用實(shí)現(xiàn)創(chuàng)建卷
    self.volume_rpcapi.create_volume(...)
    # 方法指向
    from cinder.volume import rpcapi as volume_rpcapi
    self.volume_rpcapi = volume_rpcapi.VolumeAPI()
    
  6. 調(diào)用/cinder/volume/rpcapi.py文件中VolumeAPI類下的create_volume方法

    cctxt.cast(ctxt, 'create_volume', ...)
    # 通過rpc服務(wù)將數(shù)據(jù)發(fā)送到mq隊(duì)列中
    
  7. 調(diào)用/cinder/volume/manager.py文件中VolumeManager類下的create_volume方法

    # 構(gòu)建并返回用于通過管理器建立卷的flow
    flow_engine = create_volume.get_flow(...) # /cinder/volume/flows/manager/create_volume.py
        ->  # flow_name = ACTION.replace(":", "_") + "_manager", 即為volume_create_manager。
        ->  # 初始化flow類:volume_flow = linear_flow.Flow(flow_name)叠骑。
        ->  # 添加一個給定的task到flow:volume_flow.add(ExtractVolumeRefTask(...))李皇。
            ->  #   ExtractVolumeRefTask:提取給定卷的引用。
        ->  # 添加一個給定的task到flow:volume_flow.add(OnFailureRescheduleTask(...))宙枷。
            ->  # OnFailureRescheduleTask:觸發(fā)一個發(fā)送進(jìn)行重新調(diào)度的請求掉房,當(dāng)進(jìn)行task恢復(fù)回滾操作的時候。
        ->  # 添加給定的task到flow:   volume_flow.add(ExtractVolumeSpecTask(db), NotifyVolumeActionTask(db, 
            # "create.start"), CreateVolumeFromSpecTask(...), CreateVolumeOnFinishTask(db, "create.end"))慰丛。
            ->  # ExtractVolumeSpecTask:提取一個用于建立卷的通用結(jié)構(gòu)數(shù)據(jù)卓囚。
                ->  # NotifyVolumeActionTask:執(zhí)行關(guān)于給定卷的相關(guān)通知操作,獲取指定卷的使用率信息诅病,并進(jìn)行通知操作哪亿。
                ->  # CreateVolumeFromSpecTask:根據(jù)所提供的數(shù)據(jù)實(shí)現(xiàn)卷的建立操作。
                ->  # CreateVolumeOnFinishTask:當(dāng)成功的建立卷之后睬隶,完成卷建立之后的通知操作锣夹。
    # 調(diào)用CreateVolumeFromSpecTask創(chuàng)建卷,/cinder/volume/flows/manager/create_volume.py下
        ->  # 首先調(diào)用`execute(...)`方法苏潜。
        ->  # 獲取創(chuàng)建卷的方式:create_type = volume_spec.pop('type', None)
        ->  # 根據(jù)不同的方式創(chuàng)建卷
    # 以raw原始方式創(chuàng)建卷為例說明银萍,接著是調(diào)用self._create_raw_volume(...)方法
    # 假設(shè)以rbd方式創(chuàng)建卷,那么self.driver即為/cinder/volume/drivers/rbd.py文件下`RBDDriver`類的實(shí)例化
    self.driver.create_volume(volume)
    ....
    # 運(yùn)行用于建立卷的flow
    flow_engine.run()
    
  8. 調(diào)用/cinder/volume/drivers/rbd.py文件下RBDDriver類下的create_volume`方法

    # 主要該方法
    with RADOSClient(self) as client:
            self.RBDProxy().create(client.ioctx, ...)
    # 方法指向
    from eventlet import tpool
    self.RBDProxy() = tpool.Proxy(self.rbd.RBD())
    # self.RBDProxy().create(...)調(diào)用的是C擴(kuò)展的rbd.pyx中的create(...)方法
    

    RBD的C擴(kuò)展Github倉庫地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末恤左,一起剝皮案震驚了整個濱河市贴唇,隨后出現(xiàn)的幾起案子搀绣,更是在濱河造成了極大的恐慌,老刑警劉巖戳气,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件链患,死亡現(xiàn)場離奇詭異,居然都是意外死亡瓶您,警方通過查閱死者的電腦和手機(jī)麻捻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來呀袱,“玉大人贸毕,你說我怎么就攤上這事∫拐裕” “怎么了明棍?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長寇僧。 經(jīng)常有香客問我摊腋,道長,這世上最難降的妖魔是什么嘁傀? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任兴蒸,我火速辦了婚禮,結(jié)果婚禮上心包,老公的妹妹穿的比我還像新娘类咧。我一直安慰自己,他們只是感情好蟹腾,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布痕惋。 她就那樣靜靜地躺著,像睡著了一般娃殖。 火紅的嫁衣襯著肌膚如雪值戳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天炉爆,我揣著相機(jī)與錄音堕虹,去河邊找鬼。 笑死芬首,一個胖子當(dāng)著我的面吹牛赴捞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播郁稍,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼赦政,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起恢着,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤桐愉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后掰派,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體从诲,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年靡羡,在試婚紗的時候發(fā)現(xiàn)自己被綠了系洛。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡略步,死狀恐怖碎罚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情纳像,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布拯勉,位于F島的核電站竟趾,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏宫峦。R本人自食惡果不足惜岔帽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望导绷。 院中可真熱鬧犀勒,春花似錦、人聲如沸妥曲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽檐盟。三九已至褂萧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間葵萎,已是汗流浹背导犹。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留羡忘,地道東北人谎痢。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像卷雕,于是被迫代替她去往敵國和親节猿。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容