nova 热迁移卷 的关键代码 rebase说明

cinder的migrate功能,如果遇到热迁移(卷已经挂载在虚机)的情况:cinder在目标后端host上创建好卷,然后交给nova;nova保证两个卷都挂着,然后调用nova.virt.libvirt.guest.BlockDevice的几个方法,实现硬盘数据从原卷到新卷的拷贝,然后修改虚机的xml配置文件(即virsh dumpxml instance-xxxxx 出来的xml文件,保存了虚拟机的配置信息)。

  1. abort_job():
    同步终止关于硬盘的所有读写操作。
  2. rebase(new_path, copy=True, reuse_ext=True):
    在路径new_path(即新硬盘)为磁盘创建一个备份,同时reuse_ext=True指定了在拷贝过程中还可以写硬盘,但是此时不是写在块设备中,而是写在nova本地的一个文件中。
  3. dev.is_job_complete()检查job是否完成。
  4. dev.abort_job(pivot=True):
    停止磁盘的读写,并且将过程2中的读写内容合并。
  5. self._host.write_instance_config(xml):

nova.virt.libvirt.driver.LibvirtDriver#_swap_volume

    def _swap_volume(self, guest, disk_path, conf, resize_to):
        """Swap existing disk with a new block device."""
        dev = guest.get_block_device(disk_path)

        # Save a copy of the domain's persistent XML file
        xml = guest.get_xml_desc(dump_inactive=True, dump_sensitive=True)

        # Abort is an idempotent operation, so make sure any block
        # jobs which may have failed are ended.
        try:
            dev.abort_job()
        except Exception:
            pass

        try:
            # NOTE (rmk): blockRebase cannot be executed on persistent
            #             domains, so we need to temporarily undefine it.
            #             If any part of this block fails, the domain is
            #             re-defined regardless.
            if guest.has_persistent_configuration():
                support_uefi = self._has_uefi_support()
                guest.delete_configuration(support_uefi)

            try:
                # Start copy with VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT flag to
                # allow writing to existing external volume file. Use
                # VIR_DOMAIN_BLOCK_REBASE_COPY_DEV if it's a block device to
                # make sure XML is generated correctly (bug 1691195)
                copy_dev = conf.source_type == 'block'
                dev.rebase(conf.source_path, copy=True, reuse_ext=True,
                           copy_dev=copy_dev)
                while not dev.is_job_complete():
                    time.sleep(0.5)

                dev.abort_job(pivot=True)

            except Exception as exc:
                LOG.exception("Failure rebasing volume %(new_path)s on "
                    "%(old_path)s.", {'new_path': conf.source_path,
                                      'old_path': disk_path})
                raise exception.VolumeRebaseFailed(reason=six.text_type(exc))

            if resize_to:
                dev.resize(resize_to * units.Gi / units.Ki)
        finally:
            self._host.write_instance_config(xml)

nova.virt.libvirt.guest.BlockDevice#rebase

    def rebase(self, base, shallow=False, reuse_ext=False,
               copy=False, relative=False, copy_dev=False):
        """Copy data from backing chain into a new disk

        This copies data from backing file(s) into overlay(s), giving
        control over several aspects like what part of a disk image
        chain to be copied, whether to reuse an existing destination
        file, etc.  And updates the backing file to the new disk

        :param shallow: Limit copy to top of the source backing chain
        :param reuse_ext: Reuse an existing external file that was
                          pre-created
        :param copy: Start a copy job
        :param relative: Keep backing chain referenced using relative names
        :param copy_dev: Treat the destination as type="block"
        """
        flags = shallow and libvirt.VIR_DOMAIN_BLOCK_REBASE_SHALLOW or 0
        flags |= reuse_ext and libvirt.VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT or 0
        flags |= copy and libvirt.VIR_DOMAIN_BLOCK_REBASE_COPY or 0
        flags |= copy_dev and libvirt.VIR_DOMAIN_BLOCK_REBASE_COPY_DEV or 0
        flags |= relative and libvirt.VIR_DOMAIN_BLOCK_REBASE_RELATIVE or 0
        return self._guest._domain.blockRebase(
            self._disk, base, self.REBASE_DEFAULT_BANDWIDTH, flags=flags)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值