mysql qcow2_qcow2文件格式分析

本文详细分析了qcow2文件格式,包括其魔数、版本号、backing_file信息、cluster大小、虚拟磁盘大小、加密方法、L1和L2表、refcount_table、快照管理和特性标志等关键字段。通过对文件头部的解析,揭示了qcow2如何实现高效、灵活的磁盘映像管理,尤其在虚拟化环境中用于MySQL等数据库系统的应用。
摘要由CSDN通过智能技术生成

qcow文件格式描述

官网说明文档:

vim [某虚拟机的qcow2文件]

%!xxd

0 - 3 : magic QCOW magic string ("QFI\xfb") 4个字节固定的标识符

4 - 7 : version Version number (valid values are 2 and 3) 版本号,2或者3

8 - 15 : backing_file_offset 文件路径字符串相对于文件起始位置的偏移地址,这个字符串不是以0结束的。该值为0时,表示该镜像没有 backing file

0000 0000 0000 0118 -> 0000 0001 0001 1000 256+24=280 看左边的地址定位

16 - 19 : backing_file_size 文件路径字符串长度,单位是字节数。必须小于1023字节。镜像没有backing file时,该值无意义

0000 0079 0111 1001 = 121

400 280

0x00000190-0x00000118 =ox78 + 1 = 121

20 - 23 : cluster_bits cluster 位数,代表了 cluster 大小(1 << cluster_bits 就是 cluster 的大小)。不能小于9,也就是每个 cluster 大小不能小于 512个字节。 Note:新版本的qemu启用了最大 2MB 的 cluster 大小。

0000 0010 -> 00010000 16 bit :2^16:64k cluster大小

24 - 31 : size 虚拟磁盘的大小,单位字节,这个是呈现给用户的大小(virt-df查看),不是文件实际大小

0000 0002 8000 0000 2 * 2^32 + 8 * 2^28=2^33 + 2^31 = 10G

32 - 35 : crypt_method 0 - 未加密;1 - AES加密

0000 0000

36 - 39 : l1_size L1 table项数

0000 0014= 20

40 - 47 : l1_table_offset L1 table 相对于镜像文件起始位置的偏移, 必须与 cluster 对齐

0000 0000 0004 0000= 4 * 2^12 看左边的地址即可

48 - 55 : refcount_table_offset refcount table 相对于镜像文件起始位置的偏移。必须与 cluster 对齐

0000 0000 0001 0000

56 - 59 : refcount_table_clusters refcount table 占用了多少个 cluster

0000 0001

60 - 63 : nb_snapshots 镜像文件中包含了多少个快照。

0000 0000

64 - 71 : snapshots_offset 快照table相对于镜像文件起始位置的偏移,必须与cluster对齐

0000 0000 0000 0000

版本号如果为3,头部还会有以下附加的信息,在版本2中,这些值都是0,除非特别说明:

72 - 79 : incompatible_features 未实现的特征的位掩码,在解析文件的时候,如果发现某个未知的位被设置为1,就是需要报错的时候了。

0000 0000 0000 0000

Bit 0 脏位。如果该位为1,refcounts可能和实际情况是不一致的,在解析的时候需要扫描一遍 L1/L2 table 来修复 refcounts。

Bit 1 损坏位。如果该位为1,任何数据结构可能损坏,且镜像不应该被写。

Bits 2-63 Reserved (set to 0) 保留,应该为0。

Bitmask of incompatible features. An implementation must

fail to open an image if an unknown bit is set.

Bit 0: Dirty bit. If this bit is set then refcounts

may be inconsistent, make sure to scan L1/L2

tables to repair refcounts before accessing the

image.

Bit 1: Corrupt bit. If this bit is set then any data

structure may be corrupt and the image must not

be written to (unless for regaining

consistency).

Bits 2-63: Reserved (set to 0)

80 - 87 : compatible_features 兼容特征的位掩码。解析的时候完全可以忽略这些位。

0000 0000 0000 0000

Bit 0: 该位为1,则 lazy refcount 更新可以被使用。 意味着 dirty bit 为1,并且推迟refcount 元数据的更新。

Bits 1-63: Reserved (set to 0)

88 - 95 : autoclear_features 我的理解是…… 对于这些autoclear feature,在处理镜像时,如果某一位含义未知,则应该先将其设置为0,再进行写镜像操作。

Bitmask of auto-clear features. An implementation may only write to an image with unknown auto-clear features if it clears the respective bits from this field first.

0000 0000 0000 0000

Bit 0:这一位表示 bitmap extension 数据一致性。 如果这一位为1,但不存在 bitmaps extension,则应该报错;如果存在 bitmap extension 但这一位为0,则应认为 bitmap extension data 不一致(存在问题?)。

Bits 1-63: Reserved (set to 0)

96 - 99 : refcount_order refcount block项的宽度(bit宽度),版本2时,固定为4,也就是说 refcount_bits = 16.该值不超过6,也就是 refcount_bits 不超过 64。refcount_bits = 1 << refcount_order

0000 0004

100 - 103: header_length 文件头结构体的长度,版本2时,长度固定为72字节。

0000 0068104字节 也就是刚好到该位置

关于header extensions,头部扩展性选项

紧接着镜像的文件头,存储的是可选的多个 header extensions,header extensions定义

typedef struct Qcow2UnknownHeaderExtension {

uint32_t magic;

uint32_t len;

QLIST_ENTRY(Qcow2UnknownHeaderExtension) next;

uint8_t data[];

} Qcow2UnknownHeaderExtension;

字段说明

Byte 0 - 3: Header extension 的类型:

0x00000000 - End of the header extension area 我理解该值应该是表示没有header extension选项

0xE2792ACA - Backing file format namee279 2aca示例中刚好是这个值

0x6803f857 - Feature name table

0x23852875 - Bitmaps extension

other - Unknown header extension, can be safely

ignored

4 - 7: header extension 的数据长度0000 00055byte

8 - n: Header extension数据部分7163 6f77 32

n - m: 为对齐到8字节的填充部分00 0000

后面接着

6803 f857 00000090和后面紧接着的Feature name table有关 长度为00000090144byte

除非特别说明,每个extension类型在一个镜像里应该只会出现一次。如果有Backing file ,则在the backing file name should be stored in the remaining space between the end of the header extension area and the end of the first cluster. It is not allowed to store other data here, so that an implementation can safely modify the header and add extensions without harming data of compatible features that it doesn't support. Compatible features that need space for additional data can use a header extension.

关于 Feature name table 和 Bitmaps extension 两种 extension 类型结构的说明

Feature name table

eature name table 是可选项:记录镜像的某种特性。应用程序使用该字段记录某种未知的特性错误信息(稍后才知道的特性),eature name table的条目数取决于header extension data的长度,每一项的结构如下:

00000080: 00006469 7274 7920 6269 7400 0000 0000 ..dirty bit.....

00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000000b0: 0001 636f 7272 7570 7420 6269 7400 0000 ..corrupt bit...

000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000000e0: 0100 6c61 7a79 2072 6566 636f 756e 7473 ..lazy refcounts

000000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000100: 0000 0000 0000 0000 0000 0000 0000 0000 …………….

三种future name table刚好144byte

Byte 0: 特性的类型 (select feature bitmap)

0: Incompatible feature参看前面 应该是dirty bit 和 corrupt bit

1: Compatible feature

2: Autoclear feature

1: Bit number within the selected feature bitmap (valid

values: 0-63)

2 - 47: Feature name (padded with zeros, but not necessarily null

terminated if it has full length)

Bitmaps extension

bitmaps extension为可选项.可用于存储虚拟disk相关的bitmap . 当前只有一种 dirty tracking bitmap,跟踪 虚disk从某个时间点的变化。在auto-clear feature设置的情况下,需要考虑extension的数据。

Byte 0 - 3: nb_bitmaps image中bitmap的数量,大于等于1

The number of bitmaps contained in the image. Must be

greater than or equal to 1.

注意: 当前Qemu 一个image支持65535个bitmaps

4 - 7: 保留为0.

8 - 15: bitmap_directory_size

Size of the bitmap directory in bytes. It is the cumulative

size of all (nb_bitmaps) bitmap headers.

16 - 23: bitmap_directory_offset

Offset into the image file at which the bitmap directory

starts. Must be aligned to a cluster boundary.

Host cluster management

有 host cluster 和 guest cluster 的区别.这里解释了前面一直提到的refcount。对于每一个host cluster,qcow2维护了一个refcount表,应该是引用计数的概念,当refcount为0时,表示该cluster是未分配的,1表示是在使用的,>=2时表示在被使用,并且所有的写操作都要进行COW(copy on write)操作。

采用了两层表来维护管理 refcounts,第一层叫 refcount table,是可变大小的(refcount table 的 size 存储在header里),refcount table 的每一项覆盖多个 cluster,当然,在镜像文件中refcount table是连续存储的。refcount table 包含了多个指针,指向了第二层结构体,第二层结构被称为 refcount block,一个refcount block在大小上就是一个cluster。(意思就是,block也是存在一个个cluster里的),以下是根据镜像偏移量 offset,获得某个cluster对应引用计数的方法.

refcount_block_entries = (cluster_size * 8 / refcount_bits)

refcount_block_index = (offset / cluster_size) % refcount_block_entries

refcount_table_index = (offset / cluster_size) / refcount_block_entries

refcount_block = load_cluster(refcount_table[refcount_table_index]);

return refcount_block[refcount_block_index];

注:各种变量前文有述,这里回顾一下

cluster_size = 1 << cluster_bits //最小 512 bytes

refcount_bits = 16 //in version 2

以版本2为例:

cluster_size是一个cluster的字节数,对于一个qcow2文件来说,每个cluster都是固定大小的,比如512字节。

refcount_bits固定是16,也就是2bytes,因为refcount block也要按照cluster的大小来存储,所以每个cluster能够存储的block个数: refcount_block_entries = cluster_size / 2 = 256 。

refcount_table 的一个单元对应 256 个 refcount_block,存在一个cluster里。

每个block里有2个字节(16位),记录了某个cluster的引用计数。

所以计算某个 offset 所在的 cluster 引用计数的办法,先 offset / cluster_size 得到这个offset对应的是第几个cluster,然后在refcount table里找,存在table的第几个单元里,最后在这个单元里找是第几个block存着引用计数。

下面是 refcount table 和 refcount block 的结构体定义,理解了上面这段的话,这里挺简单的了。

Refcount table entry:

Bit 0 - 8: Reserved (set to 0)

9 - 63: Bits 9-63 of the offset into the image file at which the

refcount block starts. Must be aligned to a cluster

boundary.

If this is 0, the corresponding refcount block has not yet

been allocated. All refcounts managed by this refcount block

are 0.

Refcount block entry (x = refcount_bits - 1): 这里为16-1=15

Bit 0 - x: Reference count of the cluster. If refcount_bits implies a

sub-byte width, note that bit 0 means the least significant

bit in this context.

00000000: 5146 49fb 0000 0003 0000 0000 0000 0118 QFI.............

00000010:0000 00790000 0010 0000 0002 8000 0000 ...y............

00000020: 0000 0000 0000 0014 0000 0000 0004 0000 ................

00000030: 0000 0000 0001 0000 0000 0001 0000 0000 ................

00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000050: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000060: 0000 0004 0000 0068 e279 2aca 0000 0005 .......h.y*.....

00000070: 7163 6f77 3200 0000 6803 f857 00000090 qcow2...h..W....

00000080: 00006469 7274 7920 6269 7400 0000 0000 ..dirty bit.....

00000090: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000000a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000000b0: 0001 636f 7272 7570 7420 6269 7400 0000 ..corrupt bit...

000000c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000000d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000000e0: 0100 6c61 7a79 2072 6566 636f 756e 7473 ..lazy refcounts

000000f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000100: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000110: 0000 0000 0000 0000 2f64 6174 6130 2f7a ......../data0/z

00000120: 7374 6163 6b2d 7072 696d 6172 792d 7374 stack-primary-st

00000130: 6f72 6167 652f 696d 6167 6563 6163 6865 orage/imagecache

00000140: 2f74 656d 706c 6174 652f 3365 3839 6131 /template/3e89a1

00000150: 3965 6566 3231 3433 3738 6166 3437 3262 9eef214378af472b

00000160: 3136 3162 3165 6662 3562 2f33 6538 3961 161b1efb5b/3e89a

00000170: 3139 6565 6632 3134 3337 3861 6634 3732 19eef214378af472

00000180: 6231 3631 6231 6566 6235 622e 7163 6f77 b161b1efb5b.qcow

00000190: 3200 0000 0000 0000 0000 0000 0000 0000 2...............

000001a0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000001b0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000001c0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000001d0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000001e0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

000001f0: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000200: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000210: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000220: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000230: 0000 0000 0000 0000 0000 0000 0000 0000 ................

00000240: 0000 0000 0000 0000 0000 0000 0000 0000 ................

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值