把已经存在的volume挂载到instance

把已经存在的volume挂载到instance

假设volume初始状态为availablein-useerror_attaching其中之一

1.若指定的volume为共享的(volume[‘shareable’] == ‘true’)volume的状态为available或者in-use,操作可以继续进行,否则操作异常终止。

2.若指定的volume非共享的(volume[‘shareable’] == ‘false’)volume必须为available,操作可以继续运行,否则操作异常终止。

3.其他volume状态都会被终止。

4.当配置项cross_az_attachtruevolumeinstance是否在同一个az不受限制,操作可继续;当其为false时,volumeinstance必须在同一个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.若给定的volumeVolume_admin_metadata中的attached_mode有值且不同意指定的mode,则抛出异常,进入异常处理。(volume.attach.error)
3.若指定的volumestatusin-use且不为shareable,则抛出异常,进入异常处理(valume.attach.error
4.若指定volumevolume_attachment表中有记录,则与volume的相关的表已经更新,重后续操作,返回。
Nitity about volume usage
 --attach.start
5.volume_attachment中插入指定volume的挂载记录,attach_statusattaching
6.如果instance_uuid格式非法,则更新volume_attachment attach_statuserror_attaching,抛出异常,进入异常处理(volume.attach.error
7.如果volume相对于adminmetadata(volume_admin_metadata)readonlytrue,而指定mode不为‘ro’,则更新volumestatuserror_attaching,抛出异常,进入异常处理(volume.attach.error)
8.如果dirver.attach_volume(...)出现异常,则更新volume_attachment attach_statuserror_attaching
如果一切顺利,则更新表volume_attachment attach_statusattached;表volume statusin-use

  --attach.end

v Volume.attach.error
unreserve volumeattach volume过程中异常的处理:
如果volumestatusattaching,且该volumevolume_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 specifiedHTTPBadRequest异常。

2.提取volume Id--->volume_id时如果没有该值则抛出“volumeId must be specifiedHTTPBadRequest异常。

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 falsevolume status 必须为available

另外instance所在的host所在的azvolume所在的az不相同时也将抛出IvalidVolume异常。

12.reserve volume

Nova.volume.cinder.reserver_volume()-->Cinder.volume.cinder.cinderclient()--->cinderclient.v2.client.Client()(cinderclientcinder-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的信息,如果volumestatusavailable则更新其状态为attaching;如果为in-usevolume shareabletrue则更新其状态为attaching,否则抛InvalidVolume异常;如果为其他状态则该volume无效,抛InvalidVolume异常。

13.被挂载的volume处于Attaching状态

14.compute_rpcapi.attach_volume()  attach volumenova.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)

如果volumemetadataattached_mode属性有值且其值与给定的mode(mode=rw)不同,则表面该volume正在其他tack中被使用,抛出InvalidVolume异常。

如果指定的volumestatusin-useshareable属性为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 readonlytrue且指定的mode不为‘ro’则

volume status更新为error_attaching状态。

self.driver.attach_volume(context,volume,instance_uuid,host_name_sanitized,mountpoint)

若无异常则volume_attachment attach_status更新attachedvolume status更新为in-use

如果dirverattach_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)

如果volumemetadataattached_mode属性有值且其值与给定的mode(mode=rw)不同,则表面该volume正在其他tack中被使用,抛出InvalidVolume异常。

如果指定的volumestatusin-useshareable属性为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 readonlytrue且指定的mode不为‘ro’则

volume status更新为error_attaching状态。

self.driver.attach_volume(context,volume,instance_uuid,host_name_sanitized,mountpoint)

如果dirverattach_volume的过程中出现异常则:

Volume_attachment status 更新为error_attaching

--------------------------------

 self._notify_about_volume_usage(context, volume, "attach.end")

 

 

 

 

 

 

 

 

 

 

 

 

Detach a volume from instance

假设volume的当前状态为in-use、 availableattachingerror_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的状态设置为availableattach_statusdetached
--detach.end

v Volume_detach_end

你可能感兴趣的:(把已经存在的volume挂载到instance)