博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
openstack ice resize 详解(三)
阅读量:4182 次
发布时间:2019-05-26

本文共 15321 字,大约阅读时间需要 51 分钟。

感谢朋友支持本博客,欢迎共同探讨交流,由于能力和时间有限,错误之处在所难免,欢迎指正!

如有转载,请保留源作者博客信息。

如需交流,欢迎大家博客留言。

由于篇幅较长:上接之前博文:
三、resize完毕后的确认confirm_resize代码详解分析
1、/nova/api/openstack/compute/servers.py
@wsgi.response(202)
    @wsgi.serializers(xml=FullServerTemplate)
    @wsgi.deserializers(xml=ActionDeserializer)
    @wsgi.action('confirmResize')
    def _action_confirm_resize(self, req, id, body):
        context = req.environ['nova.context']
        instance = self._get_server(context, req, id) 
#从数据库获取实例信息
        try:
            self.
compute_api.confirm_resize
(context, instance)#跟进到2
        except exception.MigrationNotFound:
            msg = _("Instance has not been resized.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'confirmResize')
        return exc.HTTPNoContent()
2、/nova/compute/api.py
   
 @wrap_check_policy
    @check_instance_lock
    @check_instance_cell
    @check_instance_state(vm_state=[vm_states.RESIZED])
    def confirm_resize(self, context, instance, migration=None):
        """Confirms a migration/resize and deletes the 'old' instance."""
        elevated = context.elevated()
        if migration is None:
            migration = migration_obj.Migration.get_by_instance_and_status(
                elevated, instance.uuid, 'finished')
        # reserve quota only for any decrease in resource usage
        deltas = self._downsize_quota_delta(context, instance)
        quotas = self._reserve_quota_delta(context, deltas)
        migration.status = 'confirming' 
#设置迁移状态为正在confirming
        migration.save() 
#保存
        # With cells, the best we can do right now is commit the reservations
        # immediately...
        if CONF.cells.enable:
            quotas.commit(context)
        self._record_action_start(context, instance, #通知实例确认resize
                                  instance_actions.CONFIRM_RESIZE)
        self.
compute_rpcapi.confirm_resize
(context, 
#跟进代码至3
                                           instance,
                                           migration,
                                           migration.source_compute,
                                           quotas.reservations or [])
3、/nova/compute/rpcapi.py
 
   def confirm_resize(self, ctxt, instance, migration, host,
            reservations=None, cast=True):
        # NOTE(russellb) Havana compat
        version = self._get_compat_version('3.0', '2.39')
        cctxt = self.client.prepare(server=_compute_host(host, instance),
                version=version)
        rpc_method = cctxt.cast if cast else cctxt.call
        return rpc_method(
ctxt, 'confirm_resize
', 
#rpc调用confirm_resize,跟进到4
                          instance=instance, migration=migration,
                          reservations=reservations)
4、/nova/compute/manage.py
    
@wrap_exception()
    @wrap_instance_event
    @wrap_instance_fault
    def confirm_resize(self, context, instance, reservations, migration):
        @utils.synchronized(instance['uuid'])
        def do_confirm_resize(context, instance, migration_id):
            # NOTE(wangpan): Get the migration status from db, if it has been
            #                confirmed, we do nothing and return here
            LOG.debug(_("Going to confirm migration %s") % migration_id,
                        context=context, instance=instance)
            try:
                # TODO(russellb) Why are we sending the migration object just
                # to turn around and look it up from the db again?
               
 #从migrate表中获取该instance resize记录
                migration = migration_obj.Migration.get_by_id(
                                    context.elevated(), migration_id)
            except exception.MigrationNotFound:
                LOG.error(_("Migration %s is not found during confirmation") %
                            migration_id, context=context, instance=instance)
                return
            if migration.status == 'confirmed': 
#如果已经被确认,则不能再次确认
                LOG.info(_("Migration %s is already confirmed") %
                            migration_id, context=context, instance=instance)
                return
           
 
#如果迁移状态不是完成或者正在迁移,则数据有异常,直接return退出
            elif migration.status not in ('finished', 'confirming'):
                LOG.warn(_("Unexpected confirmation status '%(status)s' of "
                           "migration %(id)s, exit confirmation process") %
                           {"status": migration.status, "id": migration_id},
                           context=context, instance=instance)
                return
            # NOTE(wangpan): Get the instance from db, if it has been
            #                deleted, we do nothing and return here
            expected_attrs = ['metadata', 'system_metadata']
            try:
 #根据uuid获取instance信息
                instance = instance_obj.Instance.get_by_uuid(context,
                                instance.uuid, expected_attrs=expected_attrs)
            except exception.InstanceNotFound:
                LOG.info(_("Instance is not found during confirmation"),
                            context=context, instance=instance)
                return
           
#跟进到5
            self.
_confirm_resize
(context, instance, reservations=reservations,
                                 migration=migration)
        do_confirm_resize(context, instance, migration.id)
#调用自身函数
5、/nova/compute/manage.py

    
def _confirm_resize(self, context, instance, reservations=None,
                        migration=None):
        """Destroys the source instance."""
        
#通知实例确认resize开始
        self._notify_about_instance_usage(context, instance,
                                          "resize.confirm.start")
        with self._error_out_instance_on_exception(context, instance['uuid'],
                                                   reservations):
            
#删除之前保存的迁移信息,并更新instance为新的flavor数据
            # NOTE(danms): delete stashed migration information
            sys_meta, instance_type = self._cleanup_stored_instance_types(
                migration, instance)
            sys_meta.pop('old_vm_state', None)
            instance.system_metadata = sys_meta
            instance.save()
            # NOTE(tr3buchet): tear down networks on source host
            
#清理源主机的网络信息
            self.network_api.setup_networks_on_host(context, instance,
                               migration.source_compute, teardown=True)
           
#获取当前实例的网络信息
            network_info = self._get_instance_nw_info(context, instance)
            self.
driver.confirm_migration
(migration, instance, 
#跟进到代码6
                                          network_info)
            migration.status = 'confirmed' 
#设置迁移状态为确认完成
            migration.save(context.elevated())
            rt = self._get_resource_tracker(migration.source_node)
            
#清理resize过程中claim的migrate信息
            rt.drop_resize_claim(instance, prefix='old_')
            # NOTE(mriedem): The old_vm_state could be STOPPED but the user
            # might have manually powered up the instance to confirm the
            # resize/migrate, so we need to check the current power state
            # on the instance and set the vm_state appropriately. We default
            # to ACTIVE because if the power state is not SHUTDOWN, we
            # assume _sync_instance_power_state will clean it up.
            p_state = instance.power_state 
#根据迁移前虚拟机状态设置vm_state 
            vm_state = None
            if p_state == power_state.SHUTDOWN:
                vm_state = vm_states.STOPPED
                LOG.debug(_("Resized/migrated instance is powered off. "
                          "Setting vm_state to '%s'."), vm_state,
                          instance=instance)
            else:
                vm_state = vm_states.ACTIVE
            instance.vm_state = vm_state
            instance.task_state = None
            instance.save(expected_task_state=[None, task_states.DELETING])
            self._notify_about_instance_usage(
 #通知实例resize确认完成
                context, instance, "resize.confirm.end",
                network_info=network_info)
            self._quota_commit(context, reservations)
#更新配额信息
6、/nova/virt/libvirt/driver.py

    
def confirm_migration(self, migration, instance, network_info):
        """Confirms a resize, destroying the source VM."""
        self.
_cleanup_resize
(instance, network_info)
#代码跟进到7
7、/nova/virt/libvirt/driver.py

   
 def _cleanup_resize(self, instance, network_info):
        target = libvirt_utils.get_instance_path(instance) + "_resize"
        if os.path.exists(target):
            # Deletion can fail over NFS, so retry the deletion as required.
            # Set maximum attempt as 5, most test can remove the directory
            # for the second time.
            
#删除_resize文件夹,为了避免失败,重试5次
            utils.execute('rm', '-rf', target, delay_on_retry=True,
                          attempts=5)
        if instance['host'] != CONF.host:
            
#调用libvirt接口,将该虚拟机undefine
            self._undefine_domain(instance)
            
#网络及防火墙信息、配置清理
            self.unplug_vifs(instance, network_info)
            self.firewall_driver.unfilter_instance(instance, network_info)
确认confirm_resize完成。
四、resize完毕后的确认revert_resize代码详解分析

1、/nova/api/openstack/compute/servers.py
    @wsgi.response(202)
    @wsgi.serializers(xml=FullServerTemplate)
    @wsgi.deserializers(xml=ActionDeserializer)
    @wsgi.action('revertResize')
    def _action_revert_resize(self, req, id, body):
        context = req.environ['nova.context']
        instance = self._get_server(context, req, id) 
#从数据库获取instance信息
        try:
            self.
compute_api.revert_resize
(context, instance) 
#跟进到2
        except exception.MigrationNotFound:
            msg = _("Instance has not been resized.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.FlavorNotFound:
            msg = _("Flavor used by the instance could not be found.")
            raise exc.HTTPBadRequest(explanation=msg)
        except exception.InstanceIsLocked as e:
            raise exc.HTTPConflict(explanation=e.format_message())
        except exception.InstanceInvalidState as state_error:
            common.raise_http_conflict_for_instance_invalid_state(state_error,
                    'revertResize')
        return webob.Response(status_int=202)
2、/nova/compute/api.py

   
 @wrap_check_policy
    @check_instance_lock
    @check_instance_cell
    @check_instance_state(vm_state=[vm_states.RESIZED])
    def revert_resize(self, context, instance):
        """Reverts a resize, deleting the 'new' instance in the process."""
        
#回滚resize,并将new实例删除
        elevated = context.elevated()
        
#从数据库migration 表中,获取迁移信息
        migration = migration_obj.Migration.get_by_instance_and_status(
            elevated, instance.uuid, 'finished') #
        # reverse quota reservation for increased resource usage
        
#回滚配额信息
        deltas = self._reverse_upsize_quota_delta(context, migration)
        quotas = self._reserve_quota_delta(context, deltas)
        #实例状态设置为回滚
        instance.task_state = task_states.RESIZE_REVERTING
        try:
            instance.save(expected_task_state=[None])
        except Exception:
            with excutils.save_and_reraise_exception():
                quotas.rollback(context)
        migration.status = 'reverting' 
#迁移信息设置为回滚
        migration.save()
      &.bsp; # With cells, the best we can do right now is commit the reservations
        # immediate,y...
      &n"sp; if CONF.cells.enable:
            quotas.commit(context)
        self._record_action_start(context, instance, 
#通知实例回滚resize
                                  instance_actions.REVERT_RESIZE)
        self.
compute_rpcapi.revert_resize
(context, instance, 
#跟进到3
                                          migration,
                                          migration.dest_compute,
                                          quotas.reservations or [])
3、/nova/compute/rpcapi.py

  
  def revert_resize(self, ctxt, instance, migration, host,
                      reservations=None):
        # NOTE(russellb) Havana compat
        version = self._get_compat_version('3.0', '2.39')
        cctxt = self.client.prepare(server=_compute_host(host, instance),
                version=version)
        cctxt.cast(ctxt, '
revert_resize
', 
#rpc调用,跟进到4
                   instance=instance, migration=migration,
                   reservations=reservations)
4、/nova/compute/manage.py

    
@wrap_exception()
    @reverts_task_state
    @wrap_instance_event
    @wrap_instance_fault
    def revert_resize(self, context, instance, migration, reservations):
        """Destroys the new instance on the destination machine.
        Reverts the model changes, and powers on the old instance on the
        source machine.
        """
       
 #删除目的机器的new实例,回滚resize改变、将源主机的实例断电
        # NOTE(comstud): A revert_resize is essentially a resize back to
        # the old size, so we need to send a usage event here.
        self.conductor_api.notify_usage_exists(
                context, instance, current_period=True)
        with self._error_out_instance_on_exception(context, instance['uuid'],
                                                   reservations):
            # NOTE(tr3buchet): tear down networks on destination host
            
#目标主机的网络信息清除
            self.network_api.setup_networks_on_host(context, instance,
                                                    teardown=True)
           
#获取原始的实例,迁移信息
            instance_p = obj_base.obj_to_primitive(instance)
            migration_p = obj_base.obj_to_primitive(migration)
            
#网络迁移开始
            self.conductor_api.network_migrate_instance_start(context,
                                                              instance_p,
                                                              migration_p)
           
#获取实例网络及磁盘设备信息
            network_info = self._get_instance_nw_info(context, instance)
            bdms = (block_device_obj.BlockDeviceMappingList.
                    get_by_instance_uuid(context, instance.uuid))
            block_device_info = self._get_instance_volume_block_device_info(
                                context, instance, bdms=bdms)
           
#销毁实例
            self.driver.destroy(context, instance, network_info,
                                block_device_info)
           
#断开与卷连接
            self._terminate_volume_connections(context, instance, bdms)
           
#设置迁移状态
            migration.status = 'reverted'
            migration.save(context.elevated())
            rt = self._get_resource_tracker(instance.node)
            rt.drop_resize_claim(instance)
        %r6nbsp;  
#跟进到5
            self.
compute_rpcapi.finish_revert_resize
(context, instance,
                    migration, migration.source_compute,
                    reservations=reservations)
5、/nova/compute/rpcapi.py

    def finish_revert_resize(self, ctxt, instance, migration, host,
                             reservations=None):
        # NOTE(russellb) Havana compat
        version = self._get_compat_version('3.0', '2.47')
        cctxt = self.client.prepare(server=host, version=version)
        cctxt.cast(
ctxt, 'finish_revert_resize
', 
#rpc调用,跟进到6
                   instance=instance, migration=migration,
                   reservations=reservations)
6、/nova/compute/manage.py

   
 @wrap_exception()
    @reverts_task_state
    @wrap_instance_event
    @wrap_instance_fault
    def finish_revert_resize(self, context, instance, reservations, migration):
        """Finishes the second half of reverting a resize.
        Bring the original source instance state back (active/shutoff) and
        revert the resized attributes in the database.
        """
        with self._error_out_instance_on_exception(context, instance.uuid,
                              %2vnbsp;                    reservations):
            network_info = self._get_instance_nw_info(context, instance)
            self._notify_about_instance_usage( 
#通知resize回滚开始
                    context, instance, "resize.revert.start")
            sys_meta, instance_type = self._cleanup_stored_instance_types(
                migration, instance, True)
            # NOTE(mriedem): delete stashed old_vm_state information; we
            # default to ACTIVE for backwards compatibility if old_vm_state
            # is not set
            old_vm_state = sys_meta.pop('old_vm_state', vm_states.ACTIVE)
           
#回滚数据库实例信息
            instance.system_metadata = sys_meta
            instance.memory_mb = instance_type['memory_mb']
            instance.vcpus = instance_type['vcpus']
            instance.root_gb = instance_type['root_gb']
            instance.ephemeral_gb = instance_type['ephemeral_gb']
            instance.instance_type_id = instance_type['id']
            instance.host = migration['source_compute']
            instance.node = migration[gsource_node']
        &n"sp;   instance.save()
            
#源主机上创建网络
            self.network_api.setup_networks_on_host(context, instance,
                                            migration['source_compute'])
            
#获取磁盘信息
            block_device_info = self._get_instance_volume_block_device_info(
                    context, instance, refresh_conn_info=True)
            power_on = old_vm_state != vm_states.STOPPED
            
#完成回滚迁移,跟进到7
            self.
driver.finish_revert_migration
(context, instance,
                                       network_info,
                                       block_device_info, power_on)
            
#设置虚拟机状态信息
            instance.launched_at = timeutils.utcnow()
            instance.save(expected_task_state=task_states.RESIZE_REVERTING)
            instance_p = obj_base.obj_to_primitive(instance)
            migration_p = obj_base.obj_to_primitive(migration)
            
#迁移虚拟机网络
            self.conductor_api.network_migrate_instance_finish(context,
                                                               instance_p,
                                                               migration_p)
            # if the original vm state was STOPPED, set it back to STOPPED
            LOG.info(_("Updating instance to original state: '%s'") %
                     old_vm_state)
            
#设置虚拟机相应运行状态
            if power_on:
                instance.vm_state = vm_states.ACTIVE
                instance.task_state = None
                instance.save()
            else:
                instance.task_state = task_states.POWERING_OFF
                instance.save()
                self.stop_instance(context, instance=instance)
            self._notify_about_instance_usage(
#通知回滚完成
                    context, instance, "resize.revert.end")
            self._quota_commit(context, reservations)
#配额更新
7、/nova/compute/virt/libvirt/driver.py

    
def finish_revert_migration(self, context, instance, network_info,
                                block_device_info=None, power_on=True):
        LOG.debug(_("Starting finish_revert_migration"),
                   instance=instance)
       
#获取实例路径及resize路径
        inst_base = libvirt_utils.get_instance_path(instance)
        inst_base_resize = inst_base + "_resize"
        # NOTE(danms): if we're recovering from a failed migration,
        # make sure we don't have a left-over same-host base directory
        # that would conflict. Also, don't fail on the rename if the
        # failure happened early.
        if os.path.exists(inst_base_resize): 
#inst_base_resize 路径存在,清理
            self._cleanup_failed_migration(inst_base)
            utils.execute('mv', inst_base_resize, inst_base)
       
#获取磁盘信息
        disk_info = blockinfo.get_disk_info(CONF.libvirt.virt_type,
                                            instance,
                                            block_device_info)
        
#根据上述信息及配置,生成xml文件,创建虚拟机
        xml = self.to_xml(context, instance, network_info, disk_info,
                          block_device_info=block_device_info)
        self._create_domain_and_network(context, xml, instance, network_info,
                                        block_device_info, power_on)
        if power_on:
            timer = loopingcall.FixedIntervalLoopingCall(
                                                    self._wait_for_running,
                                                    instance)
            timer.start(interval=0.5).wait()
至此回滚resize分析结束。
你可能感兴趣的文章
怎样使用sqlplus连接oracle11g数据库
查看>>
JDBC连接数据库
查看>>
java日志组件介绍(common-logging,log4j,slf4j,logback )
查看>>
java运行jar命令提示没有主清单属性
查看>>
使用Maven为一个项目生成多个Jar包,将一个目录打成jar包
查看>>
CMD命令名详细大全
查看>>
C、C++、MATLAB、Python、Go 哪个比较适合写算法
查看>>
Spring的一个命名空间的名称空间处理程序没有找到
查看>>
Maven常用插件配置和使用
查看>>
spring.schemas、spring.handlers的使用
查看>>
命名空间
查看>>
数据总线技术框架说明
查看>>
ifconfig和ipconfig有什么区别
查看>>
linux配置ip地址后重启哪个服务
查看>>
git的安装
查看>>
Sublime 和webstorm的区别
查看>>
dblink是什么
查看>>
Greenplum数据库的dblink功能之搭建
查看>>
数据库的模式
查看>>
spark与storm的对比
查看>>