-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathqcow-image-format-version-1.html
233 lines (177 loc) · 6.42 KB
/
qcow-image-format-version-1.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<title>The QCOW Image Format</title>
<body bgcolor="#ffffff">
<center><h1>The QCOW Image Format</h1></center>
<p>
The QCOW image format is one of the disk image formats supported by
the QEMU processor emulator. It is a representation of a fixed size
block device in a file. Benefits it offers over using raw dump
representation include:
</p>
<ol>
<li>Smaller file size, even on filesystems which don't support
<i>holes</i> (i.e. sparse files)</li>
<li>Snapshot support, where the image only represents changes made
to an underlying disk image</li>
<li>Optional zlib based compression</li>
<li>Optional AES encryption</li>
</ol>
<p>
The qemu-img command is the most common way of manipulating these
images e.g.
<pre>
$> qemu-img create -f qcow test.qcow 4G
Formating 'test.qcow', fmt=qcow, size=4194304 kB
$> qemu-img convert test.qcow -O raw test.img
</pre>
</p>
<h2>The Header</h2>
<p>
Each QCOW file begins with a header, in big endian format, as follows:
<pre>
typedef struct QCowHeader {
uint32_t magic;
uint32_t version;
uint64_t backing_file_offset;
uint32_t backing_file_size;
uint32_t mtime;
uint64_t size; /* in bytes */
uint8_t cluster_bits;
uint8_t l2_bits;
uint32_t crypt_method;
uint64_t l1_table_offset;
} QCowHeader;
</pre>
</p>
<ul>
<li>The first 4 bytes contain the characters 'Q', 'F', 'I' followed
by <tt>0xfb</tt>.</li>
<li>The next 4 bytes contain the format version used by the
file. Currently, there has only been a single version of the format,
version 1.</li>
<li>The <tt>backing_file_offset</tt> field gives the offset from the
beginning of the file to a string containing the path to a file;
<tt>backing_file_size</tt> gives the length of this string, which
isn't a nul-terminated. If this image is a snapshot image, then this
will be the path to the original file. More on snapshots below.</li>
<li>The mtime field can be ignored.</li>
<li>The next 8 bytes contain the size, in bytes, of the block device
represented by the image.</li>
<li>The <tt>cluster_bits</tt> and <tt>l2_bits</tt> fields, between
them, describe how to map an image offset address to a location
within the file. The <tt>cluster_bits</tt> field determines the
number of lower bits of the offset address are used as an index
within a cluster; the <tt>l2_bits</tt> field gives the number of
bits used as an index withing the L2 table. More on the format's
2-level lookup system below.</li>
<li>The <tt>crypt_method</tt> field is 0 if no encryption has been
used, and 1 if AES encryption has been used.</li>
<li>The l1_table_offset gives the offset within the file of the L1
table.</li>
</ul>
<h2>2-Level Lookups</h2>
<p>
With QCOW, the contents of the device are stored in
<i>clusters</i>. Each cluster contains a number of 512 byte sectors.
</p>
<p>In order to find the cluster for a given address within the device,
you must traverse two levels of tables. The L1 table is an array of
file offsets to L2 tables, and each L2 table is an array of file
offsets to clusters.</p>
<p>So, an address is split into three separate offsets according to
the <tt>cluster_bits</tt> and <tt>l2_bits</tt> fields. For example, if
<tt>cluster_bits</tt> is 12 and <tt>l2_bits</tt> is 9, then the
address is split up as follows:
</p>
<ul>
<li>the lower 12 is an offset within a 4Kb cluster</li>
<li>the next 9 bits is offset within a 512 entry array of 64 bit
file offsets, the L2 table</li>
<li>the remaining 43 bits is an offset within another array of 64
bit file offsets, the L1 table</li>
</ul>
<p>
Note, the size of the L1 table is a function of the size of the
represented disk image:
<pre>
l1_size = ceiling (disk_size / (cluster_size * l2_size))
</pre>
</p>
<p>In other words, in order to map a given disk address to an offset
within the image:
<ol>
<li>Obtain the L1 table address using the <tt>l1_table_offset</tt>
header field</li>
<li>Use the top (64 - <tt>l2_bits</tt> - <tt>cluster_bits</tt>) bits
of the address to index the L1 table as an array of 64 bit
entries
</li>
<li>Obtain the L2 table address using the offset in the L1
table</li>
<li>Use the next <tt>l2_bits</tt> of the address to index the L2
table as an array of 64 bit entries</li>
<li>Obtain the cluster address using the offset in the L2 table.
(Assuming the most significant bit of the cluster address is
zero. See the details on compression below.)
</li>
<li>Use the remaining cluster_bits of the address as an offset
within the cluster itself</li>
</ol>
<p>
If the offset found in either the L1 or L2 table is zero, that area of
the disk is not allocated within the image.
</p>
<h2>Snapshots</h2>
<p>
The QCOW format can represent the notion of a snapshot. That is, a
QCOW image can be used to store the changes to another disk image,
without actually affecting the contents of the original image.
</p>
<p>
The representation is very simple. The snapshot image contains the
path to the original disk image, and the snapshot image header
gives the location of the path string within the file.
</p>
<p>
When you want to read an area from the snapshot, you first check to
see if that area is allocated within the snapshot image. If not, you
read the area from the original disk image.
</p>
<h2>Compression</h2>
<p>
The QCOW format supports compression by allowing each cluster to be
independently compressed with zlib.
</p>
<p>
This is represented in the cluster offset obtained from the L2 table
as follows:
</p>
<ul>
<li>If the most significant bit of the cluster offset is 1, this is
a compressed cluster</li>
<li>The next cluster_bits of the cluster offset is the size of the
compressed cluster</li>
<li>The remaining bits of the cluster offset is the actual address
of the compressed cluster within the image</li>
</ul>
<h2>Encryption</h2>
<p>
The QCOW format also supports the encryption of clusters.
</p>
<p>
If the crypt_method header field is 1, then a 16 character password
is used as the 128 bit AES key.
</p>
<p>
Each sector within each cluster is independently encrypted using AES
Cipher Block Chaining mode, using the sector's offset (relative to the
start of the device) in little-endian format as the first 64 bits of
the 128 bit initialisation vector.
</p>
<p>
<small><a href="http://blogs.gnome.org/markmc">Mark McLoughlin</a>.
June 21, 2006.</small>
</p>
</body>
</html>