卷快照完成后,会在Dashboard的云硬盘快照面板显示一条名为'snapshot for snapshot1'的卷快照记录
"""
# 我理解这一步应该是继续保证卷操作处于冻结状态,并且是可进行快照,检查配额是否可用
volume.assert_not_frozen()
# 在cinder的snapshot数据表中创建一条快照记录,即会在云硬盘快照面板显示一条名为“snapshot for
snapshot1”的记录
snapshot = self.create_snapshot_in_db(context, volume, name, description, force, metadata, cgsnapshot_id, True, group_snapshot_id)
kwargs = {'snapshot_id': snapshot.id, 'volume_properties':
objects.VolumeProperties(size=volume.size)}
# 调用rpc.case将create_snapshot的消息投递到消息队列该消息
self.scheduler_rpcapi.create_snapshot(context, volume, snapshot, volume.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信息来更新snapshot的metadata信息,需要保证系统盘的元数据与其快照的元数据一致
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