文章以ocata版本进行分析

cinder   api 的创建和启动,和 nova   api 类似,都是通过在 api-paste.ini 中定义 app ,然后将 app 加载之后,启动 wsgi 服务

走 keystone 验证的 cinder 服务,最后走 apiv3

由此, cinder   api 的入口就找到了。

api 请求的 router ,指定了 cinder/api/v3/volumes.py:VolumeController   作为实现 volume 增删改查的控制器。其中包括了 create /delete/get 等方法。

以 create 方法举例,先取出 request 的 body 数据,然后对 body 中的数据进行验证,重组,然后调用 volume_api

这里的 volume_api 指的是 cinder/volume/api.py:create   方法还是针对数据进行进一步格式化,然后使用 taskflow ,完成复杂的 volume 的创建。这个taskflow工具的大致工作方式是,创建一个 flow ,然后再 flow 中添加task ,每一个 task 要实现一个 execute 方法,作为执行函数,然后按步骤执行 task ,每一个 task 必须在前一个 task 成功执行的前提下才能执行,并支持回滚,需要继承指定类,重写 execute 执行方法和 revert 回滚方法。

这里的 api_flow 使用了 linear_flow ,也就是线形顺序依次执行,回滚也是按照倒叙依次回滚, revert 回滚方法会接收到 execute 方法执行的结果作为参数,以便进行相应的回滚操作。

首先第一个 task 是: ExtractVolumeRequestTask

这个 task 主要是完成对数据的检查,权限的验证等等,最后返回的还是创建参数 dict :

然后进入下一个 task : QuotareserveTask 。

这个 task 主要是对 quota (配额)进行预展,保证创建的资源不会超过 quota 配额。

查看这个 task 下的 execute 方法:

先调用 QUOTAS 模块( cinder/quotas.py )的 limit_check   检查 values 参数中的 quota 是否满足条件,这里可以看到检查的是 per_volume_gigabytes 。这个 quota 的含义是每一个 volume 的最大容量上限。其他的 quota 项可以通过 cinder 命令查看:

通过 quota 验证之后,再进行预占资源:

还是调用 QUOTAS 模块中的方法,这里预占的资源是, volume : 1 指占用 volume 一个, gigabytes : size 指占用资源 size 。

QUOTAS.reserve 方法将要预占的资源项目写入到数据库中,对应的相关数据可以查看 mysql cinder 库中的 reservations 表:

这里的数据表示了每一次的资源预占情况,之后 满足条件的情况下 ,则预占资源会更新到实际的 quota_usages 表中(下图),然后将 reservations 中的数据逻辑删除(上图: deleted=1 )

回到 task 中。

预占资源成功之后会返回对应的数据结果 :

如果失败,会调用 revert 方法:

可以看到这里会获取 reservations ,然后做 quota 的 rollback 。其他的 task 也是类似,不再赘述。

进入下一个 task:EntryCreateTask:

这个 task 的任务是生成 volume 对象,然后写入数据库:

再下一个 task 是: QuotaCommitTask :这个 task 将占用的 quota ( reservations )   更新到   正式的 quota 表中:

这时,数据验证和数据库方面的工作就完成了,接下来的工作就是下发创建 volume 的实际任务给 cinder   volume :

可以看到后续的 VolumeCastTask 包括 scheduler 和 volume ,一个是调度,一个是创建。

这个 task 的 execute 方法:

继续调用 cast_create_volume 方法:

这块根据传参决定是由 cinder   scheduler 调度选择节点创建 volume   还是   指定 host 创建。

这里按照普通的步骤,从 scheduler 调度开始往下跟踪,因为最终还是会调用 volume_rpcapi.create_volume 的。

进入 cinder/scheduler/rpcapi.py : create_volume :

这里先创建一个 worker ,用来记录工作的开始。

然后向 scheduler 发送消息: create_volume

接收这个消息的是 cinder/scheduler/manager.py:create_volume:

这里有个装饰器,对应上面的 worker 。

方法调用了 create_volume.get_flow 方法,这个方法也是一个 taskflow 实现的工作流:

这个方法是 cinder   scheduler 的工作流实现:

这个 flow 也是一个线性 flow : linear   flow ,里面添加了两个 task:ExtractSchedulerSpecTask   和 SchedulerCreateVolumeTask

ExtractSchedulerSpecTask :   整合 volume 的数据

具体细看下面的 task

SchedulerCreateVolumeTask :调用对应 driver ,进行创建 volume 的动作。

execute 方法,直接调用了 driver 的 scheduler_create_volume 方法:

这里的 self.driver_api 是在 schedulerManager 的 init 方法中初始化的

默认配置使用的是: cinder.scheduler.filter_scheduler.FilterScheduler

先调用 scheduler 方法,选择一个调度创建的存储后端 backend ,然后将这个后端信息更新到 volume 的数据库对象中,

这里有一步 post   select   populate   filter   properties ,好像是将此次调度到的存储节点保存,以确保当此次失败之后,重试操作不会再一次调度到这个节点上。

最后使用 rpc 发送创建消息,这里的 volume_rpcapi 是 cinder   volume 的 rpc   client ,这个 client 负责向 cinder   volume 服务发送 create_volume 的消息,接受并处理此消息

的是 cinder/volume/manager.py : create_volume 。跟踪此方法,还是使用了 taskflow 实现的

这个 flow 里添加的 task 包括

ExtractVolumeRefTask :刷新数据库 volume 的数据

OnFailureRescheduleTask:   主要是 task 失败 revert 的相关处理

ExtractVolumeSpecTask: 针对创建的参数进行数据重组,例如从 snapshot 创建, clone 等

NotifyVolumeActionTask: 想对应的 host 发送 create.start   的 notifier

CreateVolumeFromSpecTask: 根据对应的 create_type ,调用对应的方法,比如:创建 raw 类型的 volume ,会调用对应 driver 的创建方法:

CreateVolumeOnFinishTask: 这一步根据上一步的创建结果,更新数据库的 volume 状态

接下来深入到 driver 的创建方法中:

以 lvm 为例, lvm 的 driver 为例。

在 cinder/volume/manager.py   : VolumeManager   中,初始化了

跟踪代码到 LVMVolumeDriver 下的 create_volume 中:

这里使用了 self.vg, 这个 vg 是在哪里初始化的呢?

回到最初的 cinder   service 的启动代码里: cinder/service.py

这里有个 self.manager.init_host 调用,这个 manager 也就是上面的 VolumeManager ,这里调用了 init_host 方法,那 VolumeManager 的 init_host 有哪些内容?

可以看到调用了 driver 的 check_for_setup_error()

这个方法的实现,在对应的 lvm   driver 中:

在这里初始化了 self.vg 。

所以这个 self.vg 就跟踪到了 cinder/brick/local_dev/lvm.py 。

也就是说 cinder/volume/drivers/lvm.py 中的方法最终调用到 cinder/brick/local_dev/lvm.py

当前分析的 create_volume 如下:

可以看到调用了 lvcreate 命令,进行了最终的 volume 的创建

cinder 服务启动与请求流程源码分析的更多相关文章

  1. SpringMVC请求流程源码分析

    一.SpringMVC使用 1.工程创建 创建maven工程. 添加java.resources目录. 引入Spring-webmvc 依赖. <dependency> <group ...

  2. CBV请求流程源码分析

    一.CBV流程解析 urls.py urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^book/', views.BookView.as ...

  3. [Android]从Launcher开始启动App流程源码分析

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5017056.html 从Launcher开始启动App流程源码 ...

  4. Spark(五十一):Spark On YARN(Yarn-Cluster模式)启动流程源码分析(二)

    上篇<Spark(四十九):Spark On YARN启动流程源码分析(一)>我们讲到启动SparkContext初始化,ApplicationMaster启动资源中,讲解的内容明显不完整 ...

  5. Spark(四十九):Spark On YARN启动流程源码分析(一)

    引导: 该篇章主要讲解执行spark-submit.sh提交到将任务提交给Yarn阶段代码分析. spark-submit的入口函数 一般提交一个spark作业的方式采用spark-submit来提交 ...

  6. [Android]Android系统启动流程源码分析

    以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5013863.html Android系统启动流程源码分析 首先 ...

  7. Spring加载流程源码分析03【refresh】

      前面两篇文章分析了super(this)和setConfigLocations(configLocations)的源代码,本文来分析下refresh的源码, Spring加载流程源码分析01[su ...

  8. spring boot 加载web容器tomcat流程源码分析

    spring boot 加载web容器tomcat流程源码分析 我本地的springboot版本是2.5.1,后面的分析都是基于这个版本 <parent> <groupId>o ...

  9. Android笔记--View绘制流程源码分析(二)

    Android笔记--View绘制流程源码分析二 通过上一篇View绘制流程源码分析一可以知晓整个绘制流程之前,在activity启动过程中: Window的建立(activit.attach生成), ...

随机推荐

  1. Sed 命令详解 正则表达式元字符

    1.简介 sed是非交互式的编辑器.它不会修改文件,除非使用shell重定向来保存结果.默认情况下,所有的输出行都被打印到屏幕上. sed编辑器逐行处理文件(或输入),并将结果发送到屏幕.具体过程如下 ...

  2. 【BZOJ 3238】差异 后缀自动机+树形DP

    题意 给定字符串,令$s_i$表示第$i$位开始的后缀,求$\sum_{1\le i < j \le n} len(s_i)+len(s_j)-2\times lcp(s_i,s_j)$ 先考虑 ...

  3. 如何定义一个接口(接口Interface只在COM组件中定义了,MFC和C++都没有接口的概念)

    接口是COM中的关键词,在c++中并没有这个概念.接口是一种极度的抽象.接口用在COM组件中有自己的GUID值,因此定义接口时一定要指定它的GUID值. 实际上接口就是struct,即#define ...

  4. linux命令学习笔记(21):find命令之xargs

    xargs是一条Unix和类Unix操作系统的常用命令.它的作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题 xargs的作用一般等同于大多数Unix shell中的反引号,但更 ...

  5. 【转】CSS制作图形速查表-存档

      http://www.w3cplus.com/css/css-simple-shapes-cheat-sheet http://www.cnblogs.com/powertoolsteam/p/c ...

  6. 汇编题目:在屏幕中间显示a-z的所有字母,按ESC键改变字符颜色

    在屏幕中显示a-z字母,按ESC键改变字符颜色. ;程序功能:在屏幕中间同一点显示a-z的所有字符 ; 1.使用cpu循环空运行实现延迟 ; 2.按ESC键改变正在循环显示的字符的颜色 ; 3.程序完 ...

  7. 功能强大的Northwoods GoDiagram控件库

    Northwoods GoDiagram控件库用于开发图形应用 Northwoods GoDiagram控件库是付费软件,其官方网址为http://www.nwoods.com/ Northwoods ...

  8. MVC4.0 里的分析器错误

    这种错误有很多,今天碰到了,代码段写在if里就回出错,应该是认冲了吧 @if (Web.Common.UserInfo.CurrentUserInfo != null)                ...

  9. Linux查看并修改mysql的编码

    系统:阿里云 一.查看mysql字符集 输入:show variables like 'character_set_%'; 二.修改某一个数据库的编码 输入:alter database dbname ...

  10. web实现本地缓存的方法

    Cookie(或者Cookies) 指一般网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密). cookie一般通过http请求中在头部一起发送到服务器端.一条c ...