cinder创建卷源码流程分析

  1. 调用/cinder/api/v3/volumes.py文件中VolumeController类下的create方法

    # 参数验证
    self.validate_name_and_description(volume, check_length=False)
    ...
    # 如果基于快照创建卷,通过下面方法获取快照数据
    kwargs['snapshot'] = self.volume_api.get_snapshot(context, snapshot_id)
    # 如果基于卷创建卷,通过下面方法获取源卷数据
    kwargs['source_volume'] = (self.volume_api.get_volume(context, ource_volid))
    # 基于一致性群组id或群组id获取组数据
    kwargs['group'] = self.group_api.get(context, consistencygroup_id)
    或者
    kwargs['group'] = self.group_api.get(context, group_id)
    # 如果基于镜像创建卷,通过下面方法获取镜像数据
    image_uuid = self._image_uuid_from_ref(image_ref, context)
    image_snapshot = self._get_image_snapshot(context, image_uuid)
    # 如果基于卷备份创建卷,通过下面方法获取备份数据
    kwargs['backup'] = self.backup_api.get(context, backup_id=backup_id)
    # 最后调用下面方法创建卷
    new_volume = self.volume_api.create(...)
    # 方法指向
    from cinder import volume as cinder_volume
    self.volume_api = cinder_volume.API()
    
  2. 调用/cinder/volume/api.py文件中API类下的create方法

    # 参数验证
    ...
    # 获取调度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())
    # 构建用于建立卷的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
        ->  # 调用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:这个类实现了注入字典信息create_what到flow中。
        ->  # 添加一个给定的task到flow: api_flow.add(ExtractVolumeRequestTask(...))。
            ->  # ExtractVolumeRequestTask:实现提取并验证输入的请求信息,并返回经过验证的参数信息。
        ->  # 添加给定的task到flow:   api_flow.add(QuotaReserveTask(), EntryCreateTask(), QuotaCommitTask())。
            ->  # QuotaReserveTask:根据给定的大小值和给定的卷类型信息实现保存单一的卷。
            ->  # EntryCreateTask:在数据库中为给定的卷建立相关条目。
                ->  # QuotaCommitTask:提交新的资源配额的预留信息到数据库中。
        ->  # 添加给定的task到flow:   api_flow.add(VolumeCastTask(scheduler_rpcapi, volume_rpcapi, db_api))。
            ->  # VolumeCastTask:远程调用实现卷的建立操作。
    # VolumeCastTask卷操作
        ->  # 首先调用`execute(...)`方法。
        ->  # 接着调用`self._cast_create_volume(...)`方法。
        ->  # 最后点用`self.scheduler_rpcapi.create_volume(...)`方法。
    # 运行用于建立卷的flow
    flow_engine.run()
    # 方法指向
    from cinder.scheduler import rpcapi as scheduler_rpcapi
    scheduler_rpcapi = scheduler_rpcapi.SchedulerAPI()
    self.scheduler_rpcapi = scheduler_rpcapi
    
  3. 调用/cinder/scheduler/rpcapi.py文件中SchedulerAPI类下的create_volume方法

    cctxt.cast(ctxt, 'create_volume', **msg_args)
    # 通过rpc服务将数据发送到mq队列中
    
  4. 调用/cinder/scheduler/manager.py文件中SchedulerManager类下的create_volume方法

    # 构建并返回用于通过远程调度建立卷的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:实现了从输入的参数中提取调度器的规范信息的操作。
      ->    # 添加一个给定的task到flow:scheduler_flow.add(ScheduleCreateVolumeTask(driver_api))。
            ->  # ScheduleCreateVolumeTask:远程调用实现卷的建立操作。
    # ScheduleCreateVolumeTask卷操作
        ->  # 首先调用`execute(...)`方法。
        ->  # 接着调用`self.driver_api.schedule_create_volume(...)`方法。
    # 运行用于建立卷的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. 调用/cinder/scheduler/filter_scheduler.py文件中FilterScheduler类下的schedule_create_volume方法

    # 过滤称重操作,获取最优后端
    backend = self._schedule(context, request_spec, filter_properties)
    # 数据库卷数据更新
    updated_volume = driver.volume_update_db(...)
    # 最后调用,远程调用实现创建卷
    self.volume_rpcapi.create_volume(...)
    # 方法指向
    from cinder.volume import rpcapi as volume_rpcapi
    self.volume_rpcapi = volume_rpcapi.VolumeAPI()
    
  6. 调用/cinder/volume/rpcapi.py文件中VolumeAPI类下的create_volume方法

    cctxt.cast(ctxt, 'create_volume', ...)
    # 通过rpc服务将数据发送到mq队列中
    
  7. 调用/cinder/volume/manager.py文件中VolumeManager类下的create_volume方法

    # 构建并返回用于通过管理器建立卷的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:触发一个发送进行重新调度的请求,当进行task恢复回滚操作的时候。
        ->  # 添加给定的task到flow:   volume_flow.add(ExtractVolumeSpecTask(db), NotifyVolumeActionTask(db, 
            # "create.start"), CreateVolumeFromSpecTask(...), CreateVolumeOnFinishTask(db, "create.end"))。
            ->  # ExtractVolumeSpecTask:提取一个用于建立卷的通用结构数据。
                ->  # NotifyVolumeActionTask:执行关于给定卷的相关通知操作,获取指定卷的使用率信息,并进行通知操作。
                ->  # CreateVolumeFromSpecTask:根据所提供的数据实现卷的建立操作。
                ->  # CreateVolumeOnFinishTask:当成功的建立卷之后,完成卷建立之后的通知操作。
    # 调用CreateVolumeFromSpecTask创建卷,/cinder/volume/flows/manager/create_volume.py下
        ->  # 首先调用`execute(...)`方法。
        ->  # 获取创建卷的方式:create_type = volume_spec.pop('type', None)
        ->  # 根据不同的方式创建卷
    # 以raw原始方式创建卷为例说明,接着是调用self._create_raw_volume(...)方法
    # 假设以rbd方式创建卷,那么self.driver即为/cinder/volume/drivers/rbd.py文件下`RBDDriver`类的实例化
    self.driver.create_volume(volume)
    ....
    # 运行用于建立卷的flow
    flow_engine.run()
    
  8. 调用/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(...)调用的是C扩展的rbd.pyx中的create(...)方法
    

    RBD的C扩展Github仓库地址

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容