一 基础概念

1 外部快照

当一个快照被创建时,创建时当前的状态保存在当前使用的磁盘文件中,即成为一个backing file。此时一个新的overlay被创建出来保存往后的数据。

2 backing file和overlay

对基础镜像做外部快照,生成的快照文件被称为overlay,基础镜像成为backing file。backing file是只读的。示例链路如下:

base-img <-- overlay-1 <-- overlay-2 <-- overlay-3

仅支持base-img为raw file,其他节点为qcow2 file的链路,或者所有节点为qcow2 file的链路。

3 更多名词解释

  • cluster: qcow2镜像存储数据的最小单位,默认64K。
  • L2 entry: 描述cluster offset及其相关标志位的入口,长度为64位。
  • cluster offset: normal cluster位于镜像中的起始地址,长度为64位。
  • cluster type: cluster类型,根据存储内容分为normal,compressed,unallocated,zeroplain, zeroalloc。

二 COW

COW是外部快照的读写流程中最重要的部分。

1 什么是COW

COW(Copy-On-Write),也被称之为「即写即拷」快照技术或「写时复制」快照技术,这种方式通常也被称为“元数据(源数据指针表)”拷贝。顾名思义,如果有人试图改写源数据块上的原始数据,首先将原始数据拷贝到新数据块中,然后再进行改写。

2 为何需要COW

当写请求发生在backing file上,要先分配new cluster。如果只是把要写的数据写到new cluster上,那数据是不完整的,因为每次写入的数据并非刚刚是cluster的整数倍,可能是几个或几个sector,所以需要我们把剩下的部分从old cluster上复制到new cluster,最后把这个cluster标记为allocated cluster。

当我们下次读该cluster,在overlay上就可以读到,且数据是完整的,不是残缺不全的。

3 如何COW

qcow2的COW并非先复制再写入,而是先写入再复制。步骤如下:

  • 分配new cluster。
  • 标记写时复制的范围cow_startcow_end,保存在结构体QCowL2Meta
  • 写入要写的数据到new cluster。
  • 把剩下的部分从old cluster复制到new cluster。
  • 用新的cluster offset更新l2 table,加上QCOW_OFLAG_COPIED标记。

三 cluster类型

1 cluster类型

typedef enum QCow2ClusterType {
QCOW2_CLUSTER_UNALLOCATED, //未分配
QCOW2_CLUSTER_ZERO_PLAIN,
QCOW2_CLUSTER_ZERO_ALLOC,
QCOW2_CLUSTER_NORMAL, //normal
QCOW2_CLUSTER_COMPRESSED, //压缩
} QCow2ClusterType;

QCOW2_CLUSTER_NORMAL类型,且标记QCOW_OFLAG_COPIED,才无需分配cluster。其他情况均需要分配cluster。

2 如何获取cluster类型

qcow2_get_cluster_type获取cluster类型。

四 分配cluster

谁来决定分配cluster呢,是由l2 entry决定的,这里要搞清楚它的含义。

1 l2 entry各位含义,以standard clusters为例。

2 根据l2 entry决定是否分配cluster

  • l2 entry满足以下条件,为normal cluster,不分配新cluster。

  • l2 entry的每一位都为0,为unallocated cluster,需分配新cluster。

  • 满足63bit=0,且l2 entry & L2E_OFFSET_MASK != 0。该cluster被内部快照过,需分配cluster.

五 读写流程

1 读流程

发生在qcow2_co_preadv中,分为两种情况:

  • 要读的数据在overlay上。
  • 要读的数据在backing file上。
qcow2_co_preadv
ret = qcow2_get_cluster_offset //计算cluster offset,并返回cluster type。
switch (ret)
case QCOW2_CLUSTER_UNALLOCATED:
if (bs->backing) //读取backing file上的数据。
bdrv_co_preadv
case QCOW2_CLUSTER_NORMAL:
bdrv_co_preadv //读取overlay上的数据。

2 写流程

发生在qcow2_co_pwritev中,流程如下:

  • 如果不需要分配new cluster,将数据写入overlay。
  • 如果需要分配new cluster,但是没有backing file,或者backing file上找不到cluster offset,将数据写入new cluster。
  • 如果需要分配new cluster,且在backing file能找到cluster offset,执行COW。
qcow2_co_pwritev
qcow2_alloc_cluster_offset //获取cluster offset,如果获取失败,分配new cluster。
handle_alloc_space //new cluster填充零。
bdrv_co_pwritev //将数据写入cluster。
qcow2_handle_l2meta //当需要COW时,该函数执行COW。

qemu的外部快照实现原理的更多相关文章

  1. Libvirt外部快照

    外部快照的创建 实验环境 CentOS 7 升级QEMU CentOS 7自带的qemu版本太低需要升级 $ sudo yum install -y gcc $ sudo yum install -y ...

  2. ROW/COW 快照技术原理解析

    NOTE:ROW/COW 最新更新请跳转<再谈 COW.ROW 快照技术> 目录 目录 快照与备份的区别 Snapshot 快照技术 全量快照 增量快照 COW 写时拷贝快照技术 ROW ...

  3. KVM&amp;Libvirt基本概念及开发杂谈

    导读 大家好,本次肖力分享的主题是KVM&Libvirt基本概念及开发杂谈,内容有些凌乱松散,主要基于自己早期整理的笔记内容和实践感悟,有些内容难免有失偏颇,望见谅.前面先介绍下需要了解的基本 ...

  4. KVM 介绍(7):使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照 (Nova Instances Snapshot Libvirt)

    学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分 ...

  5. 使用libvirtAPI打快照原理

    参考: https://blog.51cto.com/3646344/2096347 https://blog.51cto.com/3646344/2096351(磁盘外部快照) API接口: htt ...

  6. KVM(七)使用 libvirt 做 QEMU/KVM 快照和 Nova 实例的快照

    本文将梳理 QEMU/KVM 快照相关的知识,以及在 OpenStack Nova 中使用 libvirt 来对 QEMU/KVM 虚机做快照的过程. 1. QEMU/KVM 快照 1.1 概念 QE ...

  7. qemu-img 快照的一些总结

    qemu-img 快照的一些总结 http://www.openext.org/2014/06/qemu-img-snapshot-re http://blog.csdn.net/muge0913/a ...

  8. 使用virsh命令创建KVM虚拟机快照

    查看虚拟机所在主机和虚拟机名称:[root@node-1 ~]# nova show a88dcf5d-c8b2-46a5-af27-a176d8235c9d|grep hyper| OS-EXT-S ...

  9. KVM虚拟机快照备份

    KVM 快照的定义:快照就是将虚机在某一个时间点上的磁盘.内存和设备状态保存一下,以备将来之用.它包括以下几类: (1)磁盘快照:磁盘的内容(可能是虚机的全部磁盘或者部分磁盘)在某个时间点上被保存,然 ...

  10. [原] KVM 虚拟化原理探究 —— 目录

    KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...

随机推荐

  1. 大麦基于HarmonyOS星盾安全架构,打造全链路安全抢票方案

    6月21日,在华为开发者大会2025 "安全与隐私分论坛"上,大麦作为鸿蒙生态应用开发优秀案例,受邀进行议题演讲,分享其基于鸿蒙系统星盾安全架构构建的票务安全创新实践.大麦娱乐无线 ...

  2. 一个工具管理你的所有 SDK 版本!

    众所周知,我们在面对同一个 SDK 的不同版本时,需要使用到不同的工具来管理,例如: Java:JEnv NodeJs:nvm ... 它们的原理都是基于系统的软连接,让环境变量指向一个软连接来实现切 ...

  3. left join 和 where 区别

    RT https://leetcode.cn/problems/replace-employee-id-with-the-unique-identifier/solution/ select b.un ...

  4. CGI 简单的python显示的页面

    简介 python 进行服务器的页面的显示 cgi common gateway interface 公用网关接口 简单操作 python3 -m http.server --cgi 8001 新建一 ...

  5. lingo 练习 二

    简介 练习测试 KeyPoints: 条件过滤的应用,循环乘法的应用 EX1.求sets中前几个数的和 model: data: N=6; enddata sets: number/1..N/:x; ...

  6. STM32 IAP(OTA)

    一.背景知识 STM32启动流程(从内部flash启动)[1] 正常情况下,程序从Flash启动时的流程如下:(转载自) https://blog.csdn.net/qq_42190402/artic ...

  7. ETL中如何自定义规则

    一.ETL中的规则 在使用规则之前我们先来了解一下什么是规则,ETL中规则在很多组件中都能看见,可以理解为按照事前约定好的逻辑去执行,规则可以使得数据更加的规范统一,同时也不需要去纵向的修改底层代码, ...

  8. ETL数据仓库的使用方式

    一.ETL的过程 在 ETL 过程中,数据从源系统中抽取(Extract),经过各种转换(Transform)操作,最后加载(Load)到目标数据仓库中.以下是 ETL 数仓流程的基本步骤: 抽取(E ...

  9. Rust中的匿名函数与闭包

    一.匿名函数 语法:"|参数名| 语句" 参考下面的这个示例: fn add(a: i32, b: i32) -> i32 { a + b } fn main() { let ...

  10. SpringBoot--如何创建自己的自动配置

    在实际开发中,仅靠SpringBoot的自动配置是远远不够的,比如要访问多个数据源,自动配置就完全无能为力了. 自动配置的本质 本质就是在容器中预配置要整合的框架所需的基础Bean. 以MyBatis ...