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阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容

  • 第一章 OpenStack基础 OpenStack管理的资源及提供的服务OpenStack做为一个操作系统,...
    sgt_tiger阅读 12,861评论 4 72
  • cinder RPC 分析 [TOC] 我们都知道在Cinder内部,各组件之间通讯是通过RPC api,比如c...
    笨手笨脚越阅读 1,778评论 0 3
  • 1. 创建卷可以通过命令发送请求,例如cinder create 1 2. 由cinder-api处理,代码在/c...
    chendihao阅读 1,797评论 0 1
  • rest_api os-initialize_connection 逻辑分析 收到nova请求,POST /vo...
    笨手笨脚越阅读 1,669评论 0 3
  • 又重复着每天忍耐荨麻疹的生活又该站在稀里哗的水龙头面前提着郁闷走进小卖铺翻找着冰凉冰凉的矿泉水 过敏的瘙痒总是让人...
    左陌阅读 227评论 0 0