cinder創建卷源碼分析

本文以kilo版本的cinder為例

代碼整體流程如下:

如整體架構圖所示,創建卷涉及的大體步驟主要有以下幾步:
a. Client發送請求,通過RESTFUL接口訪問cinder-api。
b. Api解析響應請求,api解析由Client發送來的請求,并通過rpc進一步調用cinder-scheduler。
c. Scheduler對資源進行調度,scheduler選擇合適的節點進行。
d. Volume調用Driver創建卷,volume通過指定Driver進行卷的創建。

cinder api

cinder client
POST  /v2/{tenant_id}/volumes  
    ↓
cinder.api.v2.volumes.VolumeController.create:
    # 對volume_type、metadata、snapshot等信息進行檢查
    new_volume = self.volume_api.create(context,
                                        size,
                                        volume.get('display_name'),
                                        volume.get('display_description'),
                                        **kwargs)
    ↓
cinder.volume.api.API.create:
    # 對source_volume、volume_type等參數進行進一步檢查
    flow_engine = create_volume.get_flow()
    ↓
cinder.volume.flows.api.create_volume.get_flow:
    api_flow.add(ExtractVolumeRequestTask())
    api_flow.add(QuotaReserveTask(),
                 EntryCreateTask(db_api),
                 QuotaCommitTask())
    api_flow.add(VolumeCastTask())
    ↓
cinder.volume.api.API.create:
    flow_engine.run()
    ↓
cinder.volume.flows.api.create_volume.ExtractVolumeRequestTask.execute:
    # 獲取 request 信息并返回
cinder.volume.flows.api.create_volume.QuotaReserveTask.execute:
    # 預留配額
cinder.volume.flows.api.create_volume.EntryCreateTask.execute:
    # 在數據庫中創建 volume 條目,此時卷的狀態為”creating”
cinder.volume.flows.api.create_volume.QuotaCommitTask.execute:
    # 確認配額
cinder.volume.flows.api.create_volume.VolumeCastTask.execute:
    self._cast_create_volume(context, request_spec, filter_properties)
    ↓
cinder.volume.flows.api.create_volume.VolumeCastTask._cast_create_volume:
    if not host: # 如果未傳入host,則會經過調度進行創建卷
        self.scheduler_rpcapi.create_volume()
    else: # 如果傳入host,直接交由Volume Manager去創建卷
        self.volume_rpcapi.create_volume()
    ↓
cinder.scheduler.rpcapi.SchedulerAPI.create_volume: # 以未傳入host為例
    return cctxt.cast(ctxt, 'create_volume', ···)

cinder scheduler

cinder.scheduler.manager.SchedulerManager.create_volume:
    flow_engine = create_volume.get_flow(context,···)
    ↓
cinder.scheduler.flows.create_volume.get_flow:
    scheduler_flow.add(ExtractSchedulerSpecTask())
    scheduler_flow.add(ScheduleCreateVolumeTask())
    ↓
cinder.scheduler.manager.SchedulerManager.create_volume:
    flow_engine.run()
    ↓
cinder.scheduler.flows.create_volume.ExtractSchedulerSpecTask.execute:
    # 獲取用于調度的信息
    ↓ 
cinder.scheduler.flows.create_volume.ScheduleCreateVolumeTask.execute:
    self.driver_api.schedule_create_volume()
    ↓
cinder.scheduler.filter_scheduler.FilterScheduler.schedule_create_volume:
    weighed_host = self._schedule()
    # 更新數據庫
    updated_volume = driver.volume_update_db(context, volume_id, host)
    self.volume_rpcapi.create_volume()
    ↓
cinder.volume.rpcapi.VolumeAPI.create_volume:
    cctxt.cast(ctxt, 'create_volume',···)

cinder volume

cinder.volume.manager.VolumeManage.create_volume:
    flow_engine = create_volume.get_flow()
    ↓
cinder.volume.flows.manager.create_volume.get_flow:
    volume_flow.add(ExtractVolumeRefTask(db, host))
    if allow_reschedule and request_spec: # 如果允許重新調度
        volume_flow.add(OnFailureRescheduleTask())
    volume_flow.add(ExtractVolumeSpecTask(db),
                    NotifyVolumeActionTask(db, "create.start"),
                    CreateVolumeFromSpecTask(db, driver),
                    CreateVolumeOnFinishTask(db, "create.end"))
    ↓                 
cinder.volume.manager.VolumeManage.create_volume:
    flow_engine.run()
    ↓
cinder.volume.flows.manager.create_volume.ExtractVolumeRefTask.execute:
    #從數據庫中獲得volume信息
    volume_ref = self.db.volume_get(context, volume_id)
    return volume_ref
    ↓
cinder.volume.flows.manager.create_volume.OnFailureRescheduleTask.execute:
    # 當進行task恢復回滾操作的時候,觸發一個發送進行重新調度的請求
    ↓ 
cinder.volume.flows.manager.create_volume.ExtractVolumeSpecTask.execute:
    # 返回要創建volume的通用結構規范
    return specs
    #
    ↓
cinder.volume.flows.manager.create_volume.NotifyVolumeActionTask.execute:
    # 執行關于給定卷的相關通知操作,獲取指定卷的使用率信息,并進行通知操作
    ↓
cinder.volume.flows.manager.create_volume.CreateVolumeFromSpecTask.execute:
    # 根據創建的不同類別,去創建卷
    create_type = volume_spec.pop('type', None)
    if create_type == 'raw':
        model_update = self._create_raw_volume(context,···)
    elif create_type == 'snap':
        model_update = self._create_from_snapshot(context,···)
    elif create_type == 'source_vol':
        model_update = self._create_from_source_volume(···)
    elif create_type == 'source_replica':
        model_update = self._create_from_source_replica(···)
    elif create_type == 'image':
        model_update = self._create_from_image(context,···)
    ↓
cinder.volume.flows.manager.create_volume.CreateVolumeFromSpecTask._create_raw_volume:
    # 以原始創建方式為例
    return self.driver.create_volume(volume_ref)
    ↓
cinder.volume.flows.manager.create_volume.CreateVolumeOnFinishTask.execute: 
    # 當成功的建立卷之后,完成卷建立之后的通知操作,啟動更新數據庫,將卷更新為available狀態。               

參考

yikun's blog

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,837評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,196評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,688評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,654評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,456評論 6 406
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,955評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,044評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,195評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,725評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,608評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,802評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,318評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,048評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,422評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,673評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,424評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,762評論 2 372

推薦閱讀更多精彩內容

  • 第一章 OpenStack基礎 OpenStack管理的資源及提供的服務OpenStack做為一個操作系統,...
    sgt_tiger閱讀 12,967評論 4 72
  • cinder RPC 分析 [TOC] 我們都知道在Cinder內部,各組件之間通訊是通過RPC api,比如c...
    笨手笨腳越閱讀 1,835評論 0 3
  • 1. 創建卷可以通過命令發送請求,例如cinder create 1 2. 由cinder-api處理,代碼在/c...
    chendihao閱讀 1,806評論 0 1
  • rest_api os-initialize_connection 邏輯分析 收到nova請求,POST /vo...
    笨手笨腳越閱讀 1,705評論 0 3
  • 又重復著每天忍耐蕁麻疹的生活又該站在稀里嘩的水龍頭面前提著郁悶走進小賣鋪翻找著冰涼冰涼的礦泉水 過敏的瘙癢總是讓人...
    左陌閱讀 233評論 0 0