把已经存在的volume挂载到instance
假设volume初始状态为available、in-use、error_attaching其中之一:
1.若指定的volume为共享的(volume[‘shareable’] == ‘true’)则volume的状态为available或者in-use,操作可以继续进行,否则操作异常终止。
2.若指定的volume非共享的(volume[‘shareable’] == ‘false’)则volume必须为available,操作可以继续运行,否则操作异常终止。
3.其他volume状态都会被终止。
4.当配置项cross_az_attach为true,volume和instance是否在同一个az不受限制,操作可继续;当其为false时,volume和instance必须在同一个az中。
5.当操作进入reserve volume时,volume的状态转变为attaching状态。
进入实际挂载操作:
Notify about instance usage
v Volume.attach.start
1.volume相对于admin的元信息(volume_admin_metadata)中只有volume_metadata[‘readly’]==’False’才可以否则抛无效挂载操作InvalidVolumeAttachMode异常。
2.若给定的volume的Volume_admin_metadata中的attached_mode有值且不同意指定的mode,则抛出异常,进入异常处理。(volume.attach.error)
3.若指定的volume的status是in-use且不为shareable,则抛出异常,进入异常处理(valume.attach.error)
4.若指定volume的volume_attachment表中有记录,则与volume的相关的表已经更新,重后续操作,返回。
Nitity about volume usage
--attach.start
5.在volume_attachment中插入指定volume的挂载记录,attach_status为attaching。
6.如果instance_uuid格式非法,则更新volume_attachment attach_status为error_attaching,抛出异常,进入异常处理(volume.attach.error)
7.如果volume相对于admin的metadata(volume_admin_metadata)的readonly为true,而指定mode不为‘ro’,则更新volume的status为error_attaching,抛出异常,进入异常处理(volume.attach.error)
8.如果dirver.attach_volume(...)出现异常,则更新volume_attachment attach_status为error_attaching
如果一切顺利,则更新表volume_attachment attach_status为attached;表volume status为in-use
--attach.end
v Volume.attach.error
unreserve volume,attach volume过程中异常的处理:
如果volume的status为attaching,且该volume在volume_attachment中已有记录,则volume status更新为in-use否则available。
v Volume.attach.end
OVER
****************详细分析过程***************
该过程手搞没有详细整理。
l Attachment a volume to instance
Volume处于初始状态:available
假定已有创建好的volume用于instance做持久化。
---nova.api.openstack.compute.contrib.volumes.VolumeAttachmentController.create()
1.RequestBody来至于用户挂载volume的请求体,先判断请求体是否符合请求要求,yes就提前请求体中的volume Id,否则抛出“volumeAttachment not specified”HTTPBadRequest异常。
2.提取volume Id--->volume_id时如果没有该值则抛出“volumeId must be specified”HTTPBadRequest异常。
3.从请求体中获取被挂载的device---->device。
4.验证提取的volume_id值是否符合volume id的格式要求,不符合就抛出“Bad volumeId format: volumeId is not in proper format (%s)"”HTTPBadRequest异常。
5.获取挂载的instance实例。
6.执行attachment volume操作。(compute_api.attach_volume())
---nova.compute.api.API (compute_api=API())
7.检测device格式是否有效和device是否存在,若不存在或者device无效则抛出InvalidDevicePath异常。
8.进入rpc远程过程调用实现attachment volume。
---nova.compute.rpcai.ComputeAPI(compute_rpcapi=ComputeAPI())
9.reserve block device name(rcp call)
10.获取指定的volume实例。nova.volume.cinder.API
11.检测将要被挂载的volume是否符合要求:
如果volume shareable 是true 则volume status必须是available或者in-use; 若volume shareable 是false则volume status 必须为available。
另外instance所在的host所在的az与volume所在的az不相同时也将抛出IvalidVolume异常。
12.reserve volume。
Nova.volume.cinder.reserver_volume()-->Cinder.volume.cinder.cinderclient()--->cinderclient.v2.client.Client()(通cinderclient向cinder-api服务提交请求)--->cinderclient.v2.volumes.VolumeManager.reserve()-->cinder.api.contrib.volume_actions._reserve()(mark volume as reserved)--->cinder.volume.api.API.reserve_volume()
cinder.volume.api.reserver_voluem()
从数据库中提取指定被挂载的volume的信息,如果volume的status为available则更新其状态为attaching;如果为in-use且volume shareable为true则更新其状态为attaching,否则抛InvalidVolume异常;如果为其他状态则该volume无效,抛InvalidVolume异常。
13.被挂载的volume处于Attaching状态
14.compute_rpcapi.attach_volume() attach volume。nova.compute.manager.ComputeManager().attach_volume()
self._notify_about_instance_usage(
context, instance, "volume.attach.start", extra_usage_info=info) 通知volume attach start
----------------------------
Attaching volume
bdm.attach(context, instance, self.volume_api, self.driver,do_check_attach=False,do_driver_attach=True)
extra_usage_info=info)
Nova.virt.block_device.DriverVolumeblockDevice().attach()
-------------------
cinder.volume.rpcapi.VolumeAPI().attach_volume()
-----------------
cinder.volume.managerr.VolumeManager().attach_volume()(updates db to show volume is attached)
获取指定volume administrator的具有的all metadata
volume = self.db.volume_get(context, volume_id)
volume_metadata = self.db.volume_admin_metadata_get(
context.elevated(), volume_id)
如果volume的metadata的attached_mode属性有值且其值与给定的mode(如mode=‘rw’)不同,则表面该volume正在其他tack中被使用,抛出InvalidVolume异常。
如果指定的volume的status为in-use且shareable属性为false则抛出InvalidVolume异常。
获取volume_attachment信息。如果有值说明已经挂载了,直接跳出,如果为空则就行挂载操作。
self._notify_about_volume_usage(context, volume,
"attach.start")
--------------------------
更新数据库的volume_attach attach_status-->attaching
如果提供的instance_uuid格式错误则volume_attachment 的attach_status的状态更新为error_attaching
---------------------------
volume_metadata 的readonly为true且指定的mode不为‘ro’则
volume status更新为error_attaching状态。
self.driver.attach_volume(context,volume,instance_uuid,host_name_sanitized,mountpoint)
若无异常则volume_attachment attach_status更新attached,volume status更新为in-use。
如果dirver在attach_volume的过程中出现异常则:
Volume_attachment status 更新为error_attaching
--------------------------------
self._notify_about_volume_usage(context, volume, "attach.end")
-------------------
若有异常:
self._notify_about_instance_usage(
context, instance, "volume.attach.error", extra_usage_info=info) 通知attach error
Reserve volume :self.volume_api.unreserve_volume(context, bdm.volume_id)
------------------------
self._notify_about_instance_usage(
context, instance, "volume.attach.end", ...)
extra_usage_info=info)通知 volume attach end
Nova.virt.block_device.DriverVolumeblockDevice().attach()
-------------------
cinder.volume.rpcapi.VolumeAPI().attach_volume()
-----------------
cinder.volume.managerr.VolumeManager().attach_volume()(updates db to show volume is attached)
获取指定volume administrator的具有的all metadata
volume = self.db.volume_get(context, volume_id)
volume_metadata = self.db.volume_admin_metadata_get(
context.elevated(), volume_id)
如果volume的metadata的attached_mode属性有值且其值与给定的mode(如mode=‘rw’)不同,则表面该volume正在其他tack中被使用,抛出InvalidVolume异常。
如果指定的volume的status为in-use且shareable属性为false则抛出InvalidVolume异常。
获取volume_attachment信息。如果有值说明已经挂载了,直接跳出,如果为空则就行挂载操作。
self._notify_about_volume_usage(context, volume,
"attach.start")
--------------------------
更新数据库的volume_attach attach_status-->attaching
如果提供的instance_uuid格式错误则volume_attachment 的attach_status的状态更新为error_attaching
---------------------------
volume_metadata 的readonly为true且指定的mode不为‘ro’则
volume status更新为error_attaching状态。
self.driver.attach_volume(context,volume,instance_uuid,host_name_sanitized,mountpoint)
如果dirver在attach_volume的过程中出现异常则:
Volume_attachment status 更新为error_attaching
--------------------------------
self._notify_about_volume_usage(context, volume, "attach.end")
Detach a volume from instance
假设volume的当前状态为in-use、 available、attaching、error_attaching之一:
1.只有volume的状态为in-use时,才可以继续detach操作。
2.Volume处于in-use且不处于迁移过程中,则将其状态设置为detaching。
Notify about instance usage:
v Volume_detach_start
1.detach volume。
2.如果detach volume失败,则volume恢复in-use状态。
Notify about volume usage:
--detach.start
3.如果detach volume成功,则volume的状态设置为available,attach_status为detached。
--detach.end
v Volume_detach_end