nova volume-attach代码流程分析

最近遇到一个bug,是用户在nova端attach一个volume给instance后,再发起detach操作,导致该volume detach失败且一直处于detaching状态,借此走读nova volume-detach的代码流程,在此分享下心得笔记。

nova client端发起nova volume-attach动作,首先在api侧获取到请求信息,并进行简单解析:

nova/api/openstack/compute/volume.py

def _attach_volume(self, context, instance,             volume_id, device, disk_bus, device_type):
    """Attach an existing volume to an existing instance.This method is separated to make it possible for cells version to override it.
    """

根据请求来的body,获取volume及instance信息,直接调用compute api:

    device = self.compute_api.attach_volume(context, instance,volume_id, device)

compute api收到请求进行处理,
nova/compute/api.py:

def attach_volume(self, context, instance, volume_id, device=Nonedisk_bus=None, device_type=None):

这里比较简单,直接返回另一方法:

return self._attach_volume(context, instance, volume_id, device, disk_bus, device_type)

再看_attach_volume方法:

def _attach_volume(self, context, instance, volume_id, device, disk_bus, device_type):

这部分主要创建bdm,rpc调用nova compute:

self.compute_rpcapi.attach_volume(context, instance, volume_bdm)

openstack下的rpc调用,最终都是由manager.py处理,所以直接看compute下的manager.py
nova/compute/manager.py:

def attach_volume(self, context, instance, bdm):
return self._attach_volume(context, instance, driver_bdm)

def _attach_volume(self, context, instance, bdm):
bdm.attach(context, instance, self.volume_api, self.driver,
           do_driver_attach=True)

直接看第二个方法,发起调用bdm.attach,在nova/virt/block_device.py中:

def attach(self, context, instance, volume_api, virt_driver, do_driver_attach=False, **kwargs):

在这里有以下几部分操作:
1)获取connect_info
2)调用driver将volume挂载给instance的动作(修改xml配置等);

virt_driver.attach_volume

3)检查connect_info信息
4)如果volume状态是detached:

if volume['attach_status'] == "detached":

则调用cinder中attach方法,会将volume设置为in-use状态:

volume_api.attach(context, volume_id, instance.uuid,
                  self['mount_device'], mode=mode)

在调用cinder之前,有一个connect_info保存动作:

self.save()

正常在attach方法有装饰器修饰:

@update_db

在attach执行后更新数据库,保存connect_info信息。
在调用cinder之前加上保存的动作是为了防止在attach之后又
发生detach动作,此时cinder返回volume为in-use状态,但是connect_info尚未存储到数据库,在detach流程
中可能会因为获取不到有效的connect_info信息而导致detach失败:

TRACE oslo.messaging.rpc.dispatcher TypeError: <type 'NoneType'> can't be decoded

使得volume一直处于detaching状态。


小笨驴在吃草的时候创建了微信公众号,为方便更多觅食的“小笨驴”,为大家准备了大量的免费基础教学资料以及技术解决方案,还会定时发布一些好的技术文章,当然也会扯扯蛋、谈谈人生、呵呵,希望我们这群乐于分享技术的“小笨驴”团队越来越大!(技术干货分享群qq:128015753)


这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值