云计算国产化之路 vnc登录 文件系统直通(virtio-9p) 扩展qemu接口 gpg WARNING 珍藏博客 虚拟内存情况dommemstat分析 免密码自动登录脚本 Linux网桥 测试网段IP占用情况 Linux 进程状态 systemc强制依赖 调试openstack ut uefi p2v 重做ubuntu内核 virsh创建虚拟机简介 virtio IO路径 虚拟化层升级后磁盘无法卸载卷 vmtouch使用 Taint flags 主机和虚拟机文件共享处理的几种方法 kvm分析工具 kvm中对磁盘的io cache 虚拟化不同导致的guestos中软件安装差异(未解决) 设备直通(PCI Assignment)到底是咋整的 virtio到底是咋整的 内核启动参数 虚拟化实时性提升(零)之配置步骤 中断虚拟化(pic)到底是咋整的 中断虚拟化(apic)到底是咋整的 Raid卡配置丢失导致服务器无法启动 tainted kernels cpu stuck for 23s问题分析 虚拟化实时性提升(一)之hostOS切换为强实时系统 内存虚拟化到底是咋整的 qemu-kvm中vcpu虚拟化到底是咋整的 风河虚拟化技术点分析 使用qga的好处 qemu迁移代码分析 虚拟机串口配置及其导出到主机pts和console.log System-based I/O vs. Raw I/O 虚拟机使用Hugepage(大页) 硬件辅助分页(hardware assisted paging) 修改centos7默认启动项目 virtio的工作流程——kernel中virtio-pci初始化(2) virtio的工作流程——qemu中virtio-backend初始化(1) qmp ceilometer取不到memory.usage指标 Virtio-Balloon超详细分析 slabtop输出 虚拟机磁盘cache导致的host os kernel崩溃 虚拟机cpu和memory性能优化测评 PCI配置空间(PCI Configuration Space) centos下网卡设备直通(VT-dpci passthrough)遇到的问题及其解决思路 libguestfs详解 yum卸载软件包及其依赖 通过原始Centos ISO来定制自己的ISO centos下网卡设备直通(VT-d,pci passthrough) (占位符)window虚拟机中拔盘如何通知到libvirt和qemu后端的 cirrus漏洞分析CVE-2017-2615 XSA-208 qcow2随笔 控制寄存器概览 ceilometer对接postgresql 解压initrd和vmlinuz qemu guest agent验证 QEMU升级指南(待续) ubuntu中kdump的配置 qemu(2.3)接口梳理 热迁移导致的FC存储场景下的multipath卷残留问题分析 virsh命令(4)secret,snapshot,pool,volume部分 virsh命令(3)之interface,filter,network virsh命令(2)monitor,host,nodedev部分 virsh命令(1)之domain部分 QEMU内存管理之FlatView模型(QEMU2.0.0) ovirt基于sanock的高可用(主机粒度HA) Sanlock防脑裂场景功能测试用例 gnocchi配置及与ceilometer对接指南 make patch for libvirt in centos centos使用sanlock指导 高可用nfs资料 ubuntu14中使用sanlock指导 LVM操作指南 sanlock相关功能验证流程汇总 make patch for libvirt in ubuntu libvirt.so.0-version `LIBVIRT_PRIVATE_1.2.7' not found gdb debug libvirt 基于ubuntu社区源码包编译libvirt compile libvirt(centos) No PCI buses available nfs lead to Linux halt nfs install and config anti-virus for cloud platform nova fetch image from glance(something about _base) token auth process ovs入门指南 virt software anti-virus something about ceilometer disk sample context interview questions openstack vm injection openstack Restful and RPC murano 概览 创建虚拟机流程(compute节点)之网络创建 创建虚拟机流程之compute_api之虚拟机实例填充之配额检测 创建虚拟机流程之compute_api之基本参数生成 创建虚拟机流程之compute_api 创建虚拟机流程(主) 创建虚拟机之image 创建虚拟机流程之准备网桥 创建虚拟机流程之virt 创建虚拟机流程之compute节点 CI/CD研发流程之工程创建 CI/CD研发流程之代码合入 CI/CD研发流程之UT(单元测试) 向openstack社区合入代码记 openstack/ceilometer/gnocchi杂谈 影子页表原理 mem_add(exec.c) qemu编译安装调试 openstack/ceilometer/gnocchi之Grafana简介 openstack wiki etcd openstack计量ceilometer openstack计费cloudKitty enventlet backdoor USB 安装VMWARE ESX pycharm设置指南 无法执行modprobe -a kvm-intel解决办法 QEMU配置项 网络不通小记 libvirt之XML(虚拟机定义文件) openstack-horizon 证书认证 ceilometer与ceph对接 openstack定时任务剖析(TODO) 服务器重启后mongodb进程无法启动 ubuntu14下新增openstack服务到service的导引 ERROR 1045(28000)-数据库连不上 Python两个内置函数—locals和globals unknown exit, hardware reason 31

live migrate on FC SAN

2016年06月18日

一句话总结

一句话说不清楚,还是看全文吧

背景介绍

在之前的博客总有关config-drive有个BUG需要处理,具体看这里

最终使用博文中的规避的思路,但是没有做hard reboot
是把虚拟机xml中的cdrom盘的值置空规避

这篇博文题目是热迁移,为什么莫名其妙的说这么一通注入?
别着急,向下看

问题介绍

热迁移过程中,发现勾选block_migration会报错如下

若迁移过程中,发现不勾选block_migration会报错如下

诡异的是,测试的同事,测试的时候一次是成功的,一次是失败的

补充说明,由于这个环境后端没有使用ceph
故注释掉了相关配置项,如image_type

好,案情已经陈述完毕,让我们一探究竟。

问题分析

针对两种情况逐一分析

勾选了报错

根据勾选了的报错内容,找到代码如下

通过日志看block_device_mapping应该是有值的,看下其来源

在外面的compute.py中找到来源是

进去看,发现是从数据库中获取到信息

然后根据其形式转换(这里是volume方式)

总结下:
虚拟机在block_device_mapping表中有如下格式的盘
source_type=image destination_type=volume
source_type=snapshot destination_type=volume
source_type=snapshot destination_type=volume
热迁移不能勾选block_migration,否则报错
至于为什么,看这篇文章
简单说,为了防止错误,禁止挂在volume的虚拟机执行热迁移

没有勾选报错

根据报错内容找到源码位于
libvirt/driver.py的check_can_live_migrate_source方法中
也就是说,想执行带block_migration的热迁移,但是存储和虚拟机目录都不共享
这里会报错
注:这里这么判断是不太合理的,或者说很粗暴的
看最新版的nova代码,会发现对相关情况进行了细化判断

is_shared_block_storage和is_shared_instance_path都是在哪生成的

在本方法上面,分别_check_shared_storage_test_file和_is_shared_block_storage

_check_shared_storage_test_file我们就不具体看了
逻辑是,在热迁移的目标节点上,在instances_path目录下创建一个临时文件
然后在热迁移的源主机上,查看刚刚创建的文件,如果能看到说明共享,看不到说明不共享

下面重点分析_is_shared_block_storage

还记得一开始,我说过image_type注释掉了吗? 因为是rbd的情况下is_shared_block_storage直接返回True
注释后,这里使用的是default,也就是qcow2格式,is_shared_block_storage会使用父类方法
也就是返回False

如果dest_check_data.get(‘is_volume_backed’)
也就是说卷启动的虚拟机,这里会进入get_instance_disk_info方法

is_volume_backed是在外层调用的时候设置进来的

聚焦到get_instance_disk_info方法

首先获取到虚拟机的xml然后传入给_get_instance_disk_info获取磁盘信息

获取磁盘的挂载点,放到volume_devices中 本例中挂载点vol[‘mount_device’]为/dev/vda


过滤掉所有的cinder-volume,看看还有没有其他的盘信息

本例中由于使用了config-drive,生成了一个光驱盘

也就是说上述代码_get_instance_disk_info会返回光驱盘的信息

也就是说除了cinder-volume还存在其他盘
亦即_is_shared_block_storage最终返回False
触发上述错误

但是,为什么测试的同事这里会测试成功呢?
本文一开始的时候,说过,由于使用config-drive,做了规避:
虚拟机启动后,直接在xml中将光驱内容置为空
在使用ceph的场景下,次问题不出发,解决了热迁移失败的问题
但是,不使用ceph的情况系下,也就是上述过程
会触发问题

虚拟机做过hard-reboot
上面的规避方法,将数据库中的instances表中的config-drive标记位置为空
在hard_reboot过程中,重新构建虚拟机xml的时候,发现标记位为空,则不会生成光驱磁盘

由此,判断卷启动的虚拟机,是否是共享存储时,会只有cinder-volume
会得到共享存储情况为True

源码分析

有关热迁移的代码分析,之前的博客已经有了,具体看这里
注意:上面那篇之前的博文是基于liberty版本分析的,这里这篇文章是基于Kilo版本
虽然两个版本代码有重构,但是逻辑大同小异

现将kilo版本的代码时序图输出如下