OpenStack快照分析:(三)从磁盘启动云主机离线(在线)快照分析 (11)

      卷快照完成后,会在Dashboard的云硬盘快照面板显示一条名为'snapshot for snapshot1'的卷快照记录

    """
    # 我理解这一步应该是继续保证卷操作处于冻结状态,并且是可进行快照,检查配额是否可用
    volume.assert_not_frozen()
 
  # cindersnapshot数据表中创建一条快照记录,即会在云硬盘快照面板显示一条名为“snapshot for snapshot1”的记录
    snapshot =
self.create_snapshot_in_db(context, volume, name, description, force, metadata, cgsnapshot_idTrue, group_snapshot_id)
   
kwargs = {'snapshot_id': snapshot.id'volume_properties': objects.VolumeProperties(size=volume.size)}
   
# 调用rpc.casecreate_snapshot的消息投递到消息队列该消息
   
self.scheduler_rpcapi.create_snapshot(context, volume, snapshotvolume.service_topic_queue, objects.RequestSpec(**kwargs))
   
return snapshot

至此,cinder-api的处理结束!

小结:卷快照过程中,cinder-api的操作总结为如下两个方面:

l  卷状态条件检查及配额检查

l  创建glance数据库快照记录(记录的是单个卷快照的信息)

1.2.2.  Cinder-volume的处理过程

cinder-volume从消息队列接收到来自cinder-api的创建快照的请求消息后,cinder-volume就会调用其VolumeManager.create_snapshot方法进行处理,代码位置:cinder/volume/manager.py,如下:

@objects.Snapshot.set_workers
def create_snapshot(self, context, snapshot):
   
"""Creates and exports the snapshot."""
   
# 获取请求上下文
   
context = context.elevated()
  
 # 通过消息队列,通知ceilometer快照发生变化
   
self._notify_about_snapshot_usage(context, snapshot, "create.start")

   
try:
       
"""异常处理代码,有任何异常则退出并设置快照状态为error"""
       
# 确保存储驱动已经初始化,否则抛出异常
       
utils.require_driver_initialized(self.driver)

       
# Pass context so that drivers that want to use it, can,
        # but it is not a requirement for all drivers.
       
snapshot.context = context

       
# 调用后端存储驱动执行快照,例如使用RBDDriver,下文具体分析
        model_update =
self.driver.create_snapshot(snapshot)
       
# 完成之后,更新数据库条目,若返回的是None,则不执行
       
if model_update:
            snapshot.update(model_update)
            snapshot.save()

   
except Exception:
       
# 若之前几步操作出现问题,则将快照的状态置为error
       
with excutils.save_and_reraise_exception():
            snapshot.status = fields.SnapshotStatus.ERROR
            snapshot.save()

   
# cinder的数据库中获取卷的信息
    vol_ref =
self.db.volume_get(context, snapshot.volume_id)
    # 如果该卷的bootable属性为True,表示该卷是启动卷,表示云主机是通过卷启动的,即系统盘,
    #
如果是非启动卷,则跳过
   
if vol_ref.bootable:
       
try:
           
# 用卷的metadata信息来更新snapshotmetadata信息,需要保证系统盘的元数据与其快照的元数据一致
           
self.db.volume_glance_metadata_copy_to_snapshot(context, snapshot.id, snapshot.volume_id)
       
except exception.GlanceMetadataNotFound:
          
 # 更新snapshot的元数据如果抛出GlanceMetadataNotFound
            #
表示从glance中找不到卷的元数据信息,可以直接跳过
           
pass
        except
exception.CinderException as ex:
            LOG.exception(
"Failed updating snapshot"
                          " metadata using the provided volumes"
                          " %(volume_id)s metadata"
,
                         
{'volume_id': snapshot.volume_id},
                         
resource=snapshot)
           
# 如果抛出cinder方面的异常,则有可能是快照出现问题,则直接将快照的状态置为error
            snapshot.status = fields.SnapshotStatus.ERROR
            snapshot.save()
           
raise exception.MetadataCopyFailure(reason=six.text_type(ex))

   
# 若一路过来没有出现异常,则代表快照完成,将快照状态标记为可用,进度为100%,并保存状态
    snapshot.status = fields.SnapshotStatus.AVAILABLE
    snapshot.progress =
'100%'
   
snapshot.encryption_key_id = vol_ref.encryption_key_id
    snapshot.save()
  
 # 通过消息队列,通知ceilometer快照完成
   
self._notify_about_snapshot_usage(context, snapshot, "create.end")
    LOG.info(
"Create snapshot completed successfully",
            
resource=snapshot)
   
return snapshot.id

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxggp.html