Openstack:Nova中“从云硬盘启动”、“从镜像启动”、“从镜像启动(创建一个卷)”_prep_block_device中的差异

来源:互联网 发布:vscode php格式化插件 编辑:程序博客网 时间:2024/06/05 19:53

原文网址:http://blog.csdn.net/xiangpingli/article/details/47913059

在前面跟踪分析了:“从镜像启动”、“从镜像启动(创建一个新卷)”过程中,卷的创建是在_build_resources->_prep_block_device中创建的,而不是在

spawm->_create_image中创建的,而_create_image只是来在卷上创建镜像,或者说来组织镜像。

在这里看一下“从云硬盘启动”和“从镜像启动”、“从镜像启动(创建一个卷)”,在_prep_block_device中的差异.

(1)“从云硬盘启动”可以先不关注,肯定是在cinder这边创建的卷,不过是怎么_prep_block_device的?

(2)“从镜像启动(创建一个新卷)”确定是在cinder中创建的,nova调用了cinderclient的创建卷的命令,但其_prep_block_device做了什么?

(3)“从镜像启动”这里的卷(_base + disk)是在nova中创建的还是调cinder创建的?在_prep_block_device中做了什么?

(4)除了创建卷,还做了什么?不管在哪里建卷,都要_prep_block_device,是准备哪些东西?

再深入看一下_prep_block_device的流程:

[python] view plaincopy
  1. ->nova.compute.manager.ComputeManager._prep_block_device //准备块设备  
  2.   ->nova.compute.manager.ComputeManager.attach_block_devices   
  3.       ->nova.virt.block_device.attach_block_devices   
  4. ->nova.virt.block_device.DriverImageBlockDevice.attach:volume_api.create //怀疑这里在不同的创建方式下走不同的流程  
  5.       ->Nova.volume.API.create  
  6.         ->nova.volume.cinder.API.create  
  7.           -> client = cinderclient(context) ; client.volumes.create(size, **kwargs)//调用cinder创建卷  

确认:

nova.virt.block_device.DriverImageBlockDevice.attachvolume_api.create //怀疑这里在不同的创建方式下走不同的流程

确认这里在“从云硬盘启动”、“从镜像启动”、“从镜像启动(创建一个新卷)”三种方式下会走不同的流程

1)“从镜像启动”:

从镜像启动时,那几个类:DriverImageBlockDevice、DriverSnapshotBlockDevice、DriverBlankBlockDevice中的attach一个也没有调用

看下nova.compute.manager.ComputeManager.attach_block_devices 有没有被调用


[python] view plaincopy
  1. ->nova.compute.manager.ComputeManager._prep_block_device //准备块设备  
  2.     ->nova.compute.manager.ComputeManager.attach_block_devices   
  3.       ->nova.virt.block_device.attach_block_devices   

接下来调到哪儿去了?“从镜像启动”创建云硬盘,应该是在_create_image中做的,这里attach什么呢?是不是也要准备块设备?_create_image中只是下载?

看这时候有没有卷信息呢?

��看下nova.compute.manager.ComputeManager.attach_block_devices 有没有被调用?那几个类:DriverImageBlockDevice、DriverSnapshotBlockDevice、DriverBlankBlockDevice中的attach一个也没有调用


“从镜像启动”的_prep_block_device:在attach_block_devices这里就直接返回了,如下是“从镜像启动”的打印:


看这时候有没有卷信息呢?从镜像启动时,那几个类:DriverImageBlockDevice、DriverSnapshotBlockDevice、DriverBlankBlockDevice中的attach一个也没有调用

看下nova.compute.manager.ComputeManager.attach_block_devices 有没有被调用

“从镜像启动(创建一个新卷)”的_prep_block_device:这里会去调用cindercreate建卷,和调用cinderattach去挂载云硬盘。如下是“从镜像启动(创建一个新卷)”的log


这里的调用流程:
[python] view plaincopy
  1. ->nova.compute.manager.ComputeManager._prep_block_device //准备块设备  
  2.   ->nova.compute.manager.ComputeManager.attach_block_devices   
  3.     ->nova.virt.block_device.attach_block_devices   
  4.       ->nova.virt.block_device.DriverImageBlockDevice.attach  
  5.         ->nova.virt.driver.create  
  6.          ->nova.virt.libvrit.driver.create 创建一个新卷  
  7.       ->nova.virt.block_device.DriverVolumeBlockDevice.attach (DriverVolumeBlockDevice是DriverImageBlockDevice的父类)  
  8.         ->nova.virt.driver.attach  
  9.           ->nova.virt.libvirt.driver.attach 挂载这个卷    

“从云硬盘启动”的_prep_block_device:这里不会去创建卷,因为卷已经存在了,所以这里会直接调用attach去挂载云硬盘。如下是“从云硬盘启动”的Log


流程如下:

[python] view plaincopy
  1. ->nova.compute.manager.ComputeManager._prep_block_device //准备块设备  
  2.   ->nova.compute.manager.ComputeManager.attach_block_devices   
  3.     ->nova.virt.block_device.attach_block_devices   
  4.       ->nova.virt.block_device.DriverVolumeBlockDevice.attach (DriverVolumeBlockDevice是DriverImageBlockDevice的父类)  
  5.         ->nova.virt.driver.attach  
  6.           ->nova.virt.libvirt.driver.attach 挂载这个卷    

也就是说,在_prep_block_device中的差别:

“从镜像启动”,这里不会去创建卷,也不会去调用任何attach,因为这时候不存在一个卷,这个卷要在后面_create_image中创建

“从云硬盘启动”这里卷早已经建好了,但是会去调用cinderattach,去挂载这个卷,或者说挂载这个块设备,就是做block_device_mapping

“从镜像启动(创建一个新卷)”:这里会调用调用cindercreate去创建一个卷,并且会去调用cinderattach去挂载这个卷


这里的_prep_block_device方法的更深入的原理是什么?


【需要搞清楚】对这里的流程清楚了,就是调到了哪里。但原理还不够清楚,怎么调过去的,为什么就调到后面的nova.compute.manager.ComputeManager.attach_block_devices了,后面的nova.compute.manager.ComputeManager.attach_block_devices为什么有的会调createattach,有的会调用attach而不调用create,有的createattach都不会调用?【需要搞清楚】

详细解析:

这里主要是以attach_block_devices的返回值作为block_device_mapping的成员,所以attach_block_devices返回什么很重要。

attach_block_devices:


要明白map(func, {{},{}})是什么意思,map是将第二个参数中的所有成员,在第一个参数的函数中执行一遍!

“从镜像启动(创建一个新卷)”打印:



这里可以看到,会去调用_log_and_attach,去调用实际的createattach去创建卷和挂载卷。

“从镜像启动”打印:


这里可以看到,不会去调用_log_and_attach,这里不会去建卷,更不会去挂载卷,都在后面的_create_image中来处理。这里经过再次确认,确实不会调用。

“从云硬盘启动”,打印:



这里也会去执行map中的回调函数:_log_and_attach函数,去挂载已经创建好的云硬盘。

这里最根本的是要搞清楚:

block_device_mapping是什么?

map(_log_and_attach, block_device_mapping)做了什么?

这里还没搞明白,后面再研究。


0 0