KVM的driver_mirror功能相关实验

原创,转载请务必注明出处及URL,谢谢!


早前做的一些KVM功能相关的实验,分享一下。

mirror相关实验1【mirror功能基本测试】:
vm运行时,执行镜像操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'drive_mirror -f xxxblock_device  /data/xxxxxx-mirror.img'

查看完成状态:
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block-jobs' 

在mirror镜像过程中,vnc、ssh、console连接到vmxxxxxxx,执行一些touch文件、创建目录、删除目录、dd写入数据的操作

当mirror-img的大小与原大小相同时,执行取消mirro操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'block_job_cancel xxxblock_device'

以上过程完成后,使用/data/xxxxxx-mirror.img创建虚拟机,进入新创建的虚拟机,查看mirror创建过程中的文件目录创建、删除、写入操作是否被同步。

实验结论:
mirror过程中关于文件、目录的创建、删除、写入操作均被同步的保存到新创建的mirror-img中。


mirror相关实验2【mirror过程中踢出存储服务】:
host1: 开启nfs服务,设置共享路径为/data/mirror
host2:  mount挂载host1的nfs共享存储路径到本地的 /data/mirror

再host2上vm运行时,执行镜像操作,mirror-img保存到/data/mirror路径下:
virsh qemu-monitor-command --hmp vmxxxxxxx  'drive_mirror -f xxxblock_device  /data/mirror/xxxxxx-mirror.img'

查看完成状态:
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block-jobs' 

在mirror镜像过程中,在host1中执行service nfs stop服务,将nfs共享存储断开

在host2上多次执行查看mirror状态的操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block-jobs'
mirror镜像状态保持停止

连接到vmxxxxxxx,执行一些touch文件、创建目录、删除目录、dd写入数据的操作

在host1中执行service nfs start服务,将nfs共享存储开启

在host2上多次执行查看mirror状态的操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block-jobs'
mirror镜像状态从停止状态(持续了一段时间)变成进行状态

查看完成状态,直到mirror-img的大小与原大小相同时,执行取消mirro操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'block_job_cancel xxxblock_device'

以上过程完成后,使用/data/xxxxxx-mirror.img创建虚拟机,进入新创建的虚拟机,查看mirror创建过程中的文件目录创建、删除、写入操作是否被同步。

实验结论:
mirror过程可以被中断,mirror过程中关于文件、目录的创建、删除、写入操作均被同步的保存到新创建的mirror-img中。

stop/commit相关实验1【stop状态下执行commit操作的对象】:

vm运行时,执行如下操作挂起:
virsh qemu-monitor-command --hmp vmxxxxxxx  'stop'

查看vm的系统镜像:
ll /data/kvm/disk.img

查看vm系统镜像的back文件路径:
qemu-img info /data/kvm/disk.img

查看back文件的信息:
ll /data/kvm/base/base.img

对块设备做commit操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'commit xxxblock_device'

完成后,查看vm的系统镜像:
ll /data/kvm/disk.img

查看back文件的信息:
ll /data/kvm/base/base.img

实验结论:
stop状态下可以对block_device做commit操作,commit操作将vm系统中的产生的数据刷新到base文件中。


mirror相关实验3【block_job_complete操作(运行时切换vm系统镜像)】:

vm运行时,执行镜像操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'drive_mirror -f xxxblock_device  /data/xxxxxx-mirror.img'

查看完成状态:
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block-jobs' 


执行如下动作挂起vm:
virsh qemu-monitor-command --hmp vmxxxxxxx  'stop'

当mirror-img的大小与原大小相同时,执行complete操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'block_job_complete xxxblock_device'

执行如下动作取消vm挂起:
virsh qemu-monitor-command --hmp vmxxxxxxx  'c'

查看block-jobs,已经没有活动的job:
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block-jobs'

执行如下命令,查看block的信息,vm的系统镜像仍指向原镜像
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block'

查看虚拟机镜像文件及mirro生成文件:
ll /data/

连接vm,进入后执行一个dd写入操作:
dd if=/dev/vda  of=test.img bs=1MB count=512

查看虚拟机镜像文件及mirro生成文件:
ll /data/

可以看到,vm的原系统镜像大小没有发生变化,但mirror镜像大小增加了512MB既,block_job_complete操作实际上切换了vm的系统镜像。


vm中执行shutdown操作

删除刚创建的镜像
rm -f /data/xxxxxx-mirror.img

再次运行vm,执行镜像操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'drive_mirror -f xxxblock_device  /data/xxxxxx-mirror.img'

当mirror-img的大小与原大小相同时,执行complete操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'block_job_complete xxxblock_device'

查看block-jobs,已经没有活动的job:
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block-jobs'

执行如下命令,查看block的信息,vm的系统镜像仍指向原镜像
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block'

查看虚拟机镜像文件及mirro生成文件:
ll /data/

连接vm,进入后执行一个dd写入操作:
dd if=/dev/vda  of=test.img bs=1MB count=512

vm中执行shutdown操作:

查看虚拟机镜像文件及mirro生成文件:
ll /data/

可以看到,vm的原系统镜像大小没有发生变化,但mirror镜像大小增加了512MB既,block_job_complete操作实际上切换了vm的系统镜像。


实验结论:
无论是否对vm做挂起操作,block_job_complete操作均会切换vm的系统镜像到新生成的mirror镜像



mirror相关实验4【执行两次drive_mirror和block_job_complete操作】:
继续上一次的实验环境

再次执行镜像操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'drive_mirror -f xxxblock_device  /data/mirror-xxxxxx-mirror.img'

完成后,查看虚拟机镜像文件及mirro生成文件:
ll /data/

可以看到新生成的镜像文件与上一次执行的生成的mirror镜像文件大小相同,既镜像的是切换后的镜像文件。

再次执行complete操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'block_job_complete xxxblock_device'

查看虚拟机镜像文件及mirro生成文件:
ll /data/

连接vm,进入后执行一个dd写入操作:
dd if=/dev/vda  of=test__0000.img bs=1MB count=512

vm中执行reboot操作:

查看虚拟机镜像文件及mirro生成文件:
ll /data/

可以看到,vm的原系统镜像大小没有发生变化,第一次mirror生成的镜像大小也没有发生变化,第二次mirro镜像大小增加了512MB

实验结论:
可以连续的执行block_job_complete操作,连续切换系统镜像。


mirror相关实验5【block_job_complete操作后,物理上移除原系统镜像】

vm运行时,执行镜像操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'drive_mirror -f xxxblock_device  /data/xxxxxx-mirror.img'

查看完成状态:
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block-jobs' 

当mirror-img的大小与原大小相同时,执行complete操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'block_job_complete xxxblock_device'

执行mv操作将vm系统镜像文件mv到另外一个文件系统

实验结论:
block_job_complete操作后可以物理上移除原系统镜像


mirror相关实验6【mirror使用-n参数】

centso6.2的基础镜像base.img

qemu-img create -f qcow2 -o  backing_file=/data/kvm/base.img  /data/kvm/centos6.2-qcow2.img
qemu-img create -f qcow2 -o  backing_file=/data/kvm/base.img  /data/kvm/mirror-centos6.2.img

vm使用centos6.2-qcow2.img 为系统镜像,启动vm

进入vm,做写入操作:
dd if=/dev/vda of=test.img bs=1MB count=1024

在host上查看写入的情况, centos6.2-qcow2.img不断增长:
ll /data/kvm

host上执行镜像操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'drive_mirror -n xxxblock_device  /data/kvm/mirror-centos6.2.img'

在host上查看写入的情况, mirror-centos6.2.img不断增长:
ll /data/kvm

查看完成状态:
virsh qemu-monitor-command --hmp vmxxxxxxx  'info block-jobs' 

在mirror镜像过程中,vnc、ssh、console连接到vmxxxxxxx,执行一些touch文件、创建目录、删除目录的操作

当mirror-img的大小与原大小相同时,执行取消mirro操作:
virsh qemu-monitor-command --hmp vmxxxxxxx  'block_job_cancel xxxblock_device'

以上过程完成后,使用mirror-centos6.2.img创建虚拟机,进入新创建的虚拟机,查看mirror创建过程中的文件目录创建、删除、写入操作是否被同步。

实验结论:
mirror过程中关于文件、目录的创建、删除、写入操作均被同步的保存到新创建的mirror-centos6.2.img。
使用-n参数方法并以base.img镜像为基础,可以保证使用mirror功能保存尽可能少的数据,并以最快的速度创建mirror镜像。


总结:
    1》以上实验,基本验证了使用mirror功能做快照的可行性,同时,针对系统盘和数据盘可采用不同的参数来进行快照,保证可用性。
    2》对于qemu-kvm的drive,当指定cache为none模式时,理论上用户系统只要做了写入磁盘操作,均会被同步的写入到镜像文件中,但对于用户系统中没有落入磁盘的文件系统/数据修改,该方法不能保证数据的一致性。
    3》在不对用户系统做挂起操作的情况下,目前没有手段可以保证数据100%一致。

<think>好的,我需要解释kvm_make_request()函数的功能和用法。首先,我应该回忆一下KVM(Kernel-based Virtual Machine)的基本知识。KVM是Linux内核的一个模块,允许将Linux转变为虚拟机监控程序,运行多个虚拟机。在内核编程中,请求处理是常见的机制,用于协调虚拟机和宿主之间的操作。 接下来,kvm_make_request()这个函数的名字暗示了它与创建请求有关。可能是在虚拟机监控中,当某些事件需要由宿主处理时,会生成一个请求。函数可能用来标记需要处理的事件类型。例如,当虚拟机触发一个需要宿主介入的中断或异常时,KVM可能需要生成请求来通知宿主进行处理。 然后,我需要查找相关的Linux内核文档或源代码中的注释。根据引用[1]提到的系统使用KVM Switch和X11显示服务器,这可能与虚拟机的显示处理有关,但不确定是否直接相关。不过,用户的问题是关于kvm_make_request(),所以应聚焦于该函数。 根据经验,内核中的这类函数通常用于设置请求标志。例如,每个请求可能对应一个位掩码中的某一位,函数可能将指定的请求位设置到虚拟机或虚拟CPU的结构体中。这样后续的处理流程可以检查这些标志位,执行相应的处理。 参数方面,函数可能需要两个参数:请求类型和一个指向kvm_vcpu结构的指针。请求类型通常是预定义的枚举值,如KVM_REQ_MMU_RELOAD,表示需要重新加载MMU(内存管理单元)。用法可能是在检测到需要处理的事件时调用该函数,设置对应的请求位,然后可能触发中断或其他机制让宿主处理。 此外,函数的实现可能涉及原子操作,以确保多核环境下的安全性。例如,使用原子位操作来设置标志位,避免竞态条件。 需要确认的是,这个函数是否直接触发处理,还是仅仅标记请求,由其他机制处理。通常,设置请求后,可能还需要调用类似kvm_vcpu_kick()的函数来通知宿主CPU立即处理请求。 总结,kvm_make_request()的功能是设置虚拟CPU的请求标志,用于异步事件处理,确保宿主及时响应虚拟机的需求。使用时需传入正确的请求类型和vcpu结构,通常在需要宿主干预的事件处理流程中调用。</think>### `kvm_make_request()` 函数的功能与用法 `kvm_make_request()` 是 Linux 内核中与 KVM(Kernel-based Virtual Machine)模块相关的核心函数,主要用于**标记虚拟机(VM)或虚拟 CPU(vCPU)需要处理的异步事件**。它在 KVM 的事件处理机制中扮演关键角色,帮助宿主(Host)与虚拟机(Guest)之间协调资源或状态更新。 --- #### **功能解析** 1. **请求标记** 该函数通过设置 `kvm_vcpu` 结构体中的请求位(`requests` 字段),将特定事件标记为“待处理”。例如: - 虚拟机触发 I/O 操作需要模拟(如磁盘读写) - 时钟中断注入 - 内存管理单元(MMU)同步需求(如页表更新) ```c // 示例:标记 MMU 重新加载请求 kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu); ``` 2. **异步事件通知** 请求标记后,宿主通过中断或轮询机制感知这些事件,并调用对应的处理函数(如 `kvm_check_request()`)执行具体操作[^1]。 --- #### **参数说明** - **`request`**:预定义的请求类型,对应枚举值(如 `KVM_REQ_MMU_RELOAD`) - **`vcpu`**:指向目标虚拟 CPU 的指针(`struct kvm_vcpu *`) --- #### **典型使用场景** 1. **MMU 页表更新** 当虚拟机的页表发生修改时,需触发宿主重新加载 MMU: ```c kvm_make_request(KVM_REQ_MMU_RELOAD, vcpu); kvm_vcpu_kick(vcpu); // 通知宿主立即处理 ``` 2. **中断注入** 在需要向虚拟机注入中断时(如时钟中断): ```c kvm_make_request(KVM_REQ_IRQ_PENDING, vcpu); ``` 3. **虚拟机退出(VM Exit)处理** 在 `kvm_arch_vcpu_ioctl_run()` 等函数中,根据退出原因设置请求以执行后续操作[^2]。 --- #### **底层实现** 函数内部通过原子操作设置请求位,确保多核环境下的安全性: ```c static inline void kvm_make_request(int request, struct kvm_vcpu *vcpu) { set_bit(request & KVM_REQUEST_MASK, (void *)&vcpu->requests); } ``` --- #### **注意事项** - **请求类型范围**:`request` 必须小于 `KVM_REQUEST_MASK`(通常为 32),否则可能覆盖其他位。 - **与事件处理的配合**:标记请求后通常需调用 `kvm_vcpu_kick()` 通知宿主立即处理,避免延迟[^4]。 - **调试支持**:可通过内核日志或 `tracepoints` 跟踪请求标记和处理流程。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值