Openstack Cinder源码分析-创建Volume(二)

openstack cinder 创建volume源码分析 cinder volume 备注: 为方便源码阅读, 列出的部分的源码将被省略, 如需要阅读完整代码, 建议在官网进行下载 cinder实现相对比较简单 基本结构: api --> volume API --> db api --> volume API --> rpc --> volume manager --> drivers API 入口 目前ci... 阅读详情

上文讲过创建volume最终是使用taskflow创建几个任务:


    // 构建了如下几个任务,依次是:
	// ExtractVolumeRequestTask   构造请求
	// QuotaReserveTask           预留配额
	// QuotaCommitTask            提交配额
	// VolumeCastTask             创建volume
    api_flow.add(ExtractVolumeRequestTask(
        image_service_api,
        availability_zones,
        rebind={'size': 'raw_size',
                'availability_zone': 'raw_availability_zone',
                'volume_type': 'raw_volume_type'}))
    api_flow.add(QuotaReserveTask(),
                 EntryCreateTask(),
                 QuotaCommitTask())

    if scheduler_rpcapi and volume_rpcapi:
        # This will cast it out to either the scheduler or volume manager via
        # the rpc apis provided.
        api_flow.add(VolumeCastTask(scheduler_rpcapi, volume_rpcapi, db_api))

ExtractVolumeRequestTask:

该任务主要是对参数进行基本的校验和重新封装,所有没有revert函数(也不需要)

def execute(self, context, size, snapshot, image_id, source_volume,
            availability_zone, volume_type, metadata, key_manager,
            consistencygroup, cgsnapshot, group, group_snapshot, backup):

    .... // 对参数的校验和封装,最终返回给下个任务的参数如下:

    return {
        'size': size,
        'snapshot_id': snapshot_id,
        'source_volid': source_volid,
        'availability_zone': availability_zone,
        'volume_type': volume_type,
        'volume_type_id': volume_type_id,
        'encryption_key_id': encryption_key_id,
        'qos_specs': specs,
        'consistencygroup_id': consistencygroup_id,
        'cgsnapshot_id': cgsnapshot_id,
        'group_id': group_id,
        'replication_status': replication_status,
        'refresh_az': refresh_az,
        'backup_id': backup_id,
    }

 

QuotaReserveTask

该任务是检查当前的配额是否足够,并将即将创建的配额预留;

当该任务失败后的revert任务则是回滚(释放)预留的配额

def execute(self, context, size, volume_type_id, group_snapshot,
            optional_args):
    try:
        values = {'per_volume_gigabytes': size}
	// 检查当前的配额
        QUOTAS.limit_check(context, project_id=context.project_id,
                           **values)
    except exception.OverQuota as e:
        quotas = e.kwargs['quotas']
        raise exception.VolumeSizeExceedsLimit(
            size=size, limit=quotas['per_volume_gigabytes'])

    try:
        if group_snapshot:
            reserve_opts = {'volumes': 1}
        else:
            reserve_opts = {'volumes': 1, 'gigabytes': size}
        if ('update_size' in optional_args
                and optional_args['update_size']):
            reserve_opts.pop('volumes', None)
        QUOTAS.add_volume_type_opts(context, reserve_opts, volume_type_id)
	// 配额的预留主要是volume个数和大小
        reservations = QUOTAS.reserve(context, **reserve_opts)
        return {
            'reservations': reservations,
        }
    except exception.OverQuota as e:
        quota_utils.process_reserve_over_quota(context, e,
                                               resource='volumes',
                                               size=size)
def revert(self, context, result, optional_args, **kwargs):
    # We never produced a result and therefore can't destroy anything.
    if isinstance(result, ft.Failure):
        return

    if optional_args['is_quota_committed']:
        # The reservations have already been committed and can not be
        # rolled back at this point.
        return
    # We actually produced an output that we can revert so lets attempt
    # to use said output to rollback the reservation.
    reservations = result['reservations']
    try:
        QUOTAS.rollback(context, reservations)
    except exception.CinderException:
        # We are already reverting, therefore we should silence this
        # exception since a second exception being active will be bad.
        LOG.exception("Failed rolling back quota for"
                      " %s reservations", reservations)

 

QuotaCommitTask

 

当配额检查通过后,则提交预留的配额;

该任务失败后,则回滚提交的配额

def execute(self, context, reservations, volume_properties,
            optional_args):
    QUOTAS.commit(context, reservations)
    # updating is_quota_committed attribute of optional_args dictionary
    optional_args['is_quota_committed'] = True
    return {'volume_properties': volume_properties}

def revert(self, context, result, **kwargs):
    # We never produced a result and therefore can't destroy anything.
    if isinstance(result, ft.Failure):
        return

    volume = result['volume_properties']
    try:
        // 减去volume个数及大小
        reserve_opts = {'volumes': -1, 'gigabytes': -volume['size']}
        QUOTAS.add_volume_type_opts(context,
                                    reserve_opts,
                                    volume['volume_type_id'])
        reservations = QUOTAS.reserve(context,
                                      project_id=context.project_id,
                                      **reserve_opts)
        if reservations:
            QUOTAS.commit(context, reservations,
                          project_id=context.project_id)
    except Exception:
        LOG.exception("Failed to update quota for deleting "
                      "volume: %s", volume['id'])

VolumeCastTask

该任务则是调用cinder-scheduler模块开始进行任务的volume的调度工作

def _cast_create_volume(self, context, request_spec, filter_properties):

    // 进行backend的选择,代码省略
    ....

    self.scheduler_rpcapi.create_volume(
        context,
        volume,
        snapshot_id=snapshot_id,
        image_id=image_id,
        request_spec=request_spec,
        filter_properties=filter_properties,
        backup_id=backup_id)


def execute(self, context, **kwargs):
    scheduler_hints = kwargs.pop('scheduler_hints', None)
    db_vt = kwargs.pop('volume_type')
    kwargs['volume_type'] = None
    if db_vt:
        kwargs['volume_type'] = objects.VolumeType()
        objects.VolumeType()._from_db_object(context,
                                             kwargs['volume_type'], db_vt)
    request_spec = objects.RequestSpec(**kwargs)
    filter_properties = {}
    if scheduler_hints:
        filter_properties['scheduler_hints'] = scheduler_hints
    self._cast_create_volume(context, request_spec, filter_properties)

self.scheduler_rpcapi.create_volume对应的入口是:cinder/scheduler/rpcapi.py

def create_volume(self, ctxt, volume, snapshot_id=None, image_id=None,
                  request_spec=None, filter_properties=None,
                  backup_id=None):
    volume.create_worker()
    cctxt = self._get_cctxt()
    msg_args = {'snapshot_id': snapshot_id, 'image_id': image_id,
                'request_spec': request_spec,
                'filter_properties': filter_properties,
                'volume': volume, 'backup_id': backup_id}
    if not self.client.can_send_version('3.10'):
        msg_args.pop('backup_id')
    // 发送rpc请求
    return cctxt.cast(ctxt, 'create_volume', **msg_args)

RPC请求被cinder/scheduler/manager.py中的create_volume函数接收:

cinder-scheduler一样使用taskflow对任务进行管理

@objects.Volume.set_workers
def create_volume(self, context, volume, snapshot_id=None, image_id=None,
                  request_spec=None, filter_properties=None,
                  backup_id=None):
    self._wait_for_scheduler()

    try:
        // cinder-scheduler一样使用taskflow管理自己的任务
        flow_engine = create_volume.get_flow(context,
                                             self.driver,
                                             request_spec,
                                             filter_properties,
                                             volume,
                                             snapshot_id,
                                             image_id,
                                             backup_id)
    except Exception:
        msg = _("Failed to create scheduler manager volume flow")
        LOG.exception(msg)
        raise exception.CinderException(msg)

    with flow_utils.DynamicLogListener(flow_engine, logger=LOG):
        flow_engine.run()

create_volume.get_flow函数入口:cinder/scheduler/flows/create_volume.py

从代码可以看到主要是2个任务,具体的任务分析,参考下一章

def get_flow(context, driver_api, request_spec=None,
             filter_properties=None,
             volume=None, snapshot_id=None, image_id=None, backup_id=None):

    """Constructs and returns the scheduler entrypoint flow.

    This flow will do the following:

    1. Inject keys & values for dependent tasks.
    2. Extract a scheduler specification from the provided inputs.
    3. Use provided scheduler driver to select host and pass volume creation
       request further.
    """
    create_what = {
        'context': context,
        'raw_request_spec': request_spec,
        'filter_properties': filter_properties,
        'volume': volume,
        'snapshot_id': snapshot_id,
        'image_id': image_id,
        'backup_id': backup_id,
    }

    flow_name = ACTION.replace(":", "_") + "_scheduler"
    scheduler_flow = linear_flow.Flow(flow_name)

    # This will extract and clean the spec from the starting values.
    // 封装相关的参数
    scheduler_flow.add(ExtractSchedulerSpecTask(
        rebind={'request_spec': 'raw_request_spec'}))

    # This will activate the desired scheduler driver (and handle any
    # driver related failures appropriately).
    // 真正的调度任务
    scheduler_flow.add(ScheduleCreateVolumeTask(driver_api))

    # Now load (but do not run) the flow using the provided initial data.
    return taskflow.engines.load(scheduler_flow, store=create_what)

 

【LCMM实战指南】从增长混合模型到潜在类别轨迹分析的纵向数据建模 本文深入解析了LCMM(潜在类别混合模型)在纵向数据建模中的应用,对比了LCGA与GMM的核心差异与选择策略。通过R语言lcmm包的实战演练,详细展示了从数据模拟、模型拟合、类别数选择到结果解读的全流程,为识别数据中不同的发展轨迹亚型提供了系统指南。 阅读详情

相关推荐

本地部署ComfyUI:开源AI生图与视频生成完整实战指南

在生成式AI应用快速普及的今天,云端工具常受制于排队、积分和素材管理等问题,而本地化部署正成为开发者与创作者的高效替代方案。其核心思路是基于开源工作流引擎,将图像生成、视频生成与后期处理整合到同一套可离线运行的系统中。ComfyUI作为当前最受关注的节点式工作流平台,凭借灵活的模块组合和强大的自定义能力,降低了从图像模型调用到视频扩展的工程门槛。本文从环境配置与依赖安装入手,系统讲解如何部署ComfyUI、加载Checkpoint模型、跑通文生图基础流程,再通过自定义节点接入视频生成能力,同时介绍API批量

weixin_30985047的博客 562

Create Volume 操作(Part I) - 每天5分钟玩转 OpenStack(50)

前面已经学习了 Cinder 的架构和相关组件,从本节我们开始详细分析 Cinder 的各种操作,首先讨论 Cinder 如何创建 volume。 Create 操作流程如下: 客户(可以是 OpenStack 最终用户,也可以是其他程序)向 API(cinder-api)发送请求:“帮我创建一个 volume”。 ...

weixin_34302561的博客 166

OMNET++ INET框架学习教程(一)

在自组网学习的道路上摸石头过河,帮你快速入门OIMNET++平台下的INET框架。

NLDwangzhe的博客 6563

OpenStack----cinder 块存储服务理论部分

文章目录前言:一、cinder块存储服务器简介二、cinder 主要组件及功能三、cinder 模块架构3.1 cinder模块架构图3.2 cinder工作流程简述四、cinder常用命令4.1 查询类4.2 创建类4.3 帮助4.4 显示详情类4.5 删除类4.6 分页浏览类 前言: 本篇博客为OpenStack—cinder组件基础理论,之后会持续更新~~ 一、cinder块存储服务器简介 ...

weixin_45726050的博客 1314

服务器报错:“Unhealthy status reported by this UEFI driver without specific error message”.. 记录解决过程

服务器开机报错:Unhealthy status reported by this UEFI driver without specific...

ayychiguoguo的博客 4398

新手别怕!用‘东北天’和‘右前上’坐标系,5分钟搞懂惯性导航姿态矩阵(含Python验证代码)

本文通过‘东北天(ENU)’和‘右前上(RFU)’坐标系,详细解析惯性导航中的姿态矩阵概念。包含Python代码验证,帮助新手快速理解坐标变换、欧拉角及旋转矩阵的构建与应用,特别强调有限转动不可交换性与无限转动次序无关的区别。

weixin_29062255的博客 332

08.存储Cinder→5.场景学习→02.Create Volume→1.cinder-api处理过程

返回总目录 1.在创建volume时将所有的日志都实时打开以便记笔记2.在运行完创建volume的过程,停掉xshell,否则由于xshell显示屏有数量限制,新生成的日志会冲掉之前的日志。而且日志本身也有大小限制,时间太久的日志也会丢失。 描述详细 客户(可以是 OpenStack最终用户,也可以是其他程序)向 cinder-api发送请求:“帮我创建一个 volume。GUI 上操作的菜单为 ...

xiangrongweng0547的博客 254

MRI脑影像分析从哲学到技术:一文搞懂VBM预处理基本原理(全网最详细解析)

   分析大脑解剖学差异最常用方法之一是基于体素的形态学方法(voxel-based morphometry, VBM)。 VBM的基本思想是测量大脑组织,尤其是灰质的局部浓度的差异。在大脑的每个体素处进行操作,然后在两个或多个实验组之间进行统计比较,从而在受调查的组之间建立特定大脑区域中脑组织浓度的统计学显着差异。 VBM分析基于(高分辨率)MRI脑部扫描,涉及大量处理步骤,主要是空间归一化,分割,平滑和统计分析,最终结果是统计图,显示了各组之间组织类型明显不同的区域[^1]。 参考 [^1] ..

意疏的学习笔记 3万+

Openstack Cinder源码分析-创建Volume(三)

上文已经分析到,请求最终通过RPC到了cinder-scheduler中 cinder-scheduler通过taskflow管理了2个任务(cinder/scheduler/flows/create_volume.py): ExtractSchedulerSpecTask 该任务主要是封装参数给下一任务,无revert函数 def _populate_request_spec(self...

iov_aaron的专栏 1733

PTPX功耗分析实战——从脚本配置到报告解读

本文详细介绍了PTPX功耗分析的全流程,从脚本配置到报告解读,帮助工程师快速掌握芯片设计中的功耗估算技术。文章涵盖了环境搭建、波形文件处理、功耗报告解析等关键环节,并提供了实战经验和优化建议,特别适合需要提升PTPX功耗分析效率的开发者。

weixin_29248313的博客 279

当SLAM遇上FPGA:打造一个会“硬件加速”的激光雷达SLAM系统

点云数据的运动畸变校正特征点提取与匹配、以及ICP迭代最近点配准。在传统方案中,我们通常用ARM核完成所有计算。但点云配准中的最近邻搜索(KD-Tree)需要大量分支判断,CPU处理起来效率很低;而ICP中的矩阵分解(SVD)虽然计算量大,但非常适合并行化。ZYNQ的特殊之处在于它把ARM(PS端)和FPGA(PL端)集成在同一颗芯片上。ARM擅长跑操作系统、处理复杂逻辑和调度,FPGA擅长做高吞吐量的并行计算。两者之间通过AXI总线高速互联,数据交换延迟只有几十个时钟周期。

QQ_778132974的博客 374

openstack cinder volume创建流程以及源码分析(二)

FilterScheduler. schedule_create_volume 函数对创建请求调度选出backend,如果没有合适的backend则抛异常报no weighed backend, 调用 _get_weighted_candidates 从 cinder service中根据scheduler的filter选出合适的backends,再调用 get_weighed_backends 选出最优的backends, 最终调用volume rpc 来创建volume。

一名运维开发工程师的日常记录 645

FineReport FCP模拟题五

新建决策报表,设置 移动端 格式,采用绝对布局。数据来源:FRDemo中的订单表/雇员表。

Davina_yu的博客 723

openstack cinder volume创建流程以及源码分析(一)

d. Volume调用Driver创建卷,volume通过指定Driver进行卷的创建。(2) cinder\volume\api.py API.create函数对source_volume、volume_type等参数进行进一步检查,确保无误,并调用cinder.volume.flows.api.get_flow来创建。cast_create_volume函数,如果未传入host,则会经过调度进行创建卷,通过scheduler_rpcapi.create_volume创建卷;

一名运维开发工程师的日常记录 1227

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

OpenStack Cinder 创建卷

OpenStack Cinder卷创建流程分析 摘要:本文详细分析了OpenStack Cinder创建卷的完整流程,包括客户端请求、API处理、调度器选择、卷服务执行和存储后端操作等关键环节。重点剖析了调度器的过滤(CapacityFilter、AvailabilityZoneFilter)和权重(CapacityWeigher)机制,以及LVM驱动的具体实现方式。同时介绍了cinder.conf的核心配置项,如默认卷类型、容量限制、多后端部署等配置参数,为理解Cinder块存储服务的运作机制提供了完整的

weixin_55010563的博客 980

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Source code analysis openstack master cinder create volume

Source code analysis openstack master cinder create volume

yenai2008的专栏 1101

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Openstack Cinder源码分析-删除Volume(一)

删除API入口:cinder/api/v2/volumes.py def delete(self, req, id): """Delete a volume.""" context = req.environ['cinder.context'] cascade = utils.get_bool_param('cascade', req.params) L...

iov_aaron的专栏 627

openstack cinder volume创建流程以及源码分析(三)

CreateVolumeFromSpecTask 中又根据创建类型,是普通volume,还是image,还是备份还是快照等动作会有区别,这里已使用ceph的image创建为例,最终调用rbd的 _clone 函数clone 出一个块设备,最终resize 一下大小,同时更新根据image 元数据更新volume相关信息,最终更新volume 数据库相关信息。CreateVolumeOnFinishTask 当volume创建完之后,更新volume 数据库状态信息。支持volume 已经创建完成!

一名运维开发工程师的日常记录 408

OpenStack源码分析之cinder-volume服务

版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处! cat /usr/lib/python2.6/site-packages/cinder-2013.1.g3-py2.6.egg/EGG-INFO/scripts/cinder-volume """Starter script for Cinder Volume.""" import eventlet

Thinking -Walking@未名 5626

Openstack Cinder源码分析-创建Volume(一)

Cinder创建卷的请求如下:openstack volume create <name> --size <size>  对应的restapi请求: POST /v2/{project_id}/volumes { "volume": { "size": 10, "availability_zone": null, ...

iov_aaron的专栏 1808

Openstack liberty 创建实例快照源码分析2

这是创建云主机实例快照源码分析系列的第二篇,在第一篇文章中分析了从镜像启动云主机,创建在线/离线快照的过程;本篇将分析从启动盘启动的云主机创建快照的过程,下面请看正文: 磁盘启动云主机,离线(在线)快照 函数入口和前述一样,还是 nova/api/openstack/compute/servers.py/ServersController._action_create_image,下面一

梦幻之巅 7899

cinder 服务启动与请求流程源码分析

文章以ocata版本进行分析 cinderapi的创建和启动,和novaapi类似,都是通过在api-paste.ini中定义app,然后将app加载之后,启动wsgi服务 走keystone验证的cinder服务,最后走apiv3 由此,cinderapi的入口就找到了。 api请求的router,指定了cinder...

weixin_30737433的博客 280

openstack源码架构_OpenStack源码分析

目录1. Cinder创卷整体流程如整体架构图所示,创建卷涉及的答题步骤主要有以下几步:a. Client发送请求,通过RESTFUL接口访问cinder-api。b. Api解析响应请求,api解析由Client发送来的请求,并通过rpc进一步调用cinder-scheduler。c. Scheduler对资源进行调度,scheduler选择合适的节点进行。d. Volume调用Driver创建...

weixin_36473056的博客 444

查看journalnode节点状态信息_OpenStack Cinder服务状态排错

作者:舒祝最近手动搭建了一个openstack环境,创建硬盘时失败,查看日志,提示无法进行调度,怀疑是cinder节点出现问题,去cinder节点查看服务 ,状态显示正常。systemctl status openstack-cinder-volume.service然后在控制节点查看cinder服务,openstack volume service list正常情况下显示:结果显示cinder-...

weixin_32243309的博客 1083

OpenStack Cinder源码分析之四

同前~~~

溜溜小哥 4063
上一篇: Openstack Cinder源码分析-创建Volume(一)
下一篇: Openstack Cinder源码分析-创建Volume(三)
Aaron.com
博客等级 码龄17年 25粉丝 39原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值