xref: /kvmtool/disk/qcow.c (revision 43835ac90fb7c14c3946772d778da4b62a0bfd7c)
186835cedSPrasad Joshi #include "kvm/qcow.h"
286835cedSPrasad Joshi 
386835cedSPrasad Joshi #include "kvm/disk-image.h"
486835cedSPrasad Joshi #include "kvm/read-write.h"
586835cedSPrasad Joshi #include "kvm/util.h"
686835cedSPrasad Joshi 
786835cedSPrasad Joshi #include <sys/types.h>
886835cedSPrasad Joshi #include <sys/stat.h>
986835cedSPrasad Joshi #include <stdbool.h>
1086835cedSPrasad Joshi #include <stdlib.h>
1186835cedSPrasad Joshi #include <string.h>
1286835cedSPrasad Joshi #include <unistd.h>
1386835cedSPrasad Joshi #include <fcntl.h>
1486835cedSPrasad Joshi 
1586835cedSPrasad Joshi #include <linux/byteorder.h>
1686835cedSPrasad Joshi #include <linux/types.h>
1786835cedSPrasad Joshi 
18742fce76SPrasad Joshi static inline u64 get_l1_index(struct qcow *q, u64 offset)
1986835cedSPrasad Joshi {
20ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
2186835cedSPrasad Joshi 
2286835cedSPrasad Joshi 	return offset >> (header->l2_bits + header->cluster_bits);
2386835cedSPrasad Joshi }
2486835cedSPrasad Joshi 
25742fce76SPrasad Joshi static inline u64 get_l2_index(struct qcow *q, u64 offset)
2686835cedSPrasad Joshi {
27ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
2886835cedSPrasad Joshi 
2986835cedSPrasad Joshi 	return (offset >> (header->cluster_bits)) & ((1 << header->l2_bits)-1);
3086835cedSPrasad Joshi }
3186835cedSPrasad Joshi 
32742fce76SPrasad Joshi static inline u64 get_cluster_offset(struct qcow *q, u64 offset)
3386835cedSPrasad Joshi {
34ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
3586835cedSPrasad Joshi 
3686835cedSPrasad Joshi 	return offset & ((1 << header->cluster_bits)-1);
3786835cedSPrasad Joshi }
3886835cedSPrasad Joshi 
39a51948ceSPekka Enberg static ssize_t qcow1_read_cluster(struct qcow *q, u64 offset, void *dst, u32 dst_len)
4086835cedSPrasad Joshi {
41ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
423dac48d4SPrasad Joshi 	struct qcow_table *table  = &q->table;
43179b71f0SPekka Enberg 	u64 *l2_table = NULL;
44742fce76SPrasad Joshi 	u64 l2_table_offset;
45742fce76SPrasad Joshi 	u64 l2_table_size;
463dac48d4SPrasad Joshi 	u64 cluster_size;
47742fce76SPrasad Joshi 	u64 clust_offset;
48742fce76SPrasad Joshi 	u64 clust_start;
49a51948ceSPekka Enberg 	size_t length;
50742fce76SPrasad Joshi 	u64 l1_idx;
51742fce76SPrasad Joshi 	u64 l2_idx;
5286835cedSPrasad Joshi 
53dae803fbSPekka Enberg 	cluster_size = 1 << header->cluster_bits;
5486835cedSPrasad Joshi 
55c5e0624bSPrasad Joshi 	l1_idx = get_l1_index(q, offset);
563dac48d4SPrasad Joshi 	if (l1_idx >= table->table_size)
5786835cedSPrasad Joshi 		goto out_error;
5886835cedSPrasad Joshi 
593dac48d4SPrasad Joshi 	clust_offset = get_cluster_offset(q, offset);
603dac48d4SPrasad Joshi 	if (clust_offset >= cluster_size)
613dac48d4SPrasad Joshi 		goto out_error;
623dac48d4SPrasad Joshi 
633dac48d4SPrasad Joshi 	length = cluster_size - clust_offset;
643dac48d4SPrasad Joshi 	if (length > dst_len)
653dac48d4SPrasad Joshi 		length = dst_len;
663dac48d4SPrasad Joshi 
67ad627d62SPekka Enberg 	l2_table_offset = table->l1_table[l1_idx] & ~header->oflag_mask;
6886835cedSPrasad Joshi 	if (!l2_table_offset)
693dac48d4SPrasad Joshi 		goto zero_cluster;
7086835cedSPrasad Joshi 
7186835cedSPrasad Joshi 	l2_table_size = 1 << header->l2_bits;
72742fce76SPrasad Joshi 	l2_table = calloc(l2_table_size, sizeof(u64));
7386835cedSPrasad Joshi 	if (!l2_table)
7486835cedSPrasad Joshi 		goto out_error;
7586835cedSPrasad Joshi 
763dac48d4SPrasad Joshi 	if (pread_in_full(q->fd, l2_table, l2_table_size * sizeof(u64),
773dac48d4SPrasad Joshi 				l2_table_offset) < 0)
78b6edb0ecSSasha Levin 		goto out_error;
7986835cedSPrasad Joshi 
80c5e0624bSPrasad Joshi 	l2_idx = get_l2_index(q, offset);
8186835cedSPrasad Joshi 	if (l2_idx >= l2_table_size)
82b6edb0ecSSasha Levin 		goto out_error;
8386835cedSPrasad Joshi 
84ad627d62SPekka Enberg 	clust_start = be64_to_cpu(l2_table[l2_idx]) & ~header->oflag_mask;
8586835cedSPrasad Joshi 	if (!clust_start)
863dac48d4SPrasad Joshi 		goto zero_cluster;
8786835cedSPrasad Joshi 
883dac48d4SPrasad Joshi 	if (pread_in_full(q->fd, dst, length, clust_start + clust_offset) < 0)
89b6edb0ecSSasha Levin 		goto out_error;
9086835cedSPrasad Joshi 
91179b71f0SPekka Enberg out:
92179b71f0SPekka Enberg 	free(l2_table);
933dac48d4SPrasad Joshi 	return length;
9486835cedSPrasad Joshi 
95179b71f0SPekka Enberg zero_cluster:
96179b71f0SPekka Enberg 	memset(dst, 0, length);
97179b71f0SPekka Enberg 	goto out;
98179b71f0SPekka Enberg 
9986835cedSPrasad Joshi out_error:
100179b71f0SPekka Enberg 	length = -1;
101179b71f0SPekka Enberg 	goto out;
1023dac48d4SPrasad Joshi }
103b6edb0ecSSasha Levin 
104*43835ac9SSasha Levin static int qcow1_read_sector(struct disk_image *disk, u64 sector,
1053fdf659dSSasha Levin 		void *dst, u32 dst_len)
1063dac48d4SPrasad Joshi {
107*43835ac9SSasha Levin 	struct qcow *q = disk->priv;
108ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
1093dac48d4SPrasad Joshi 	char *buf = dst;
1103dac48d4SPrasad Joshi 	u64 offset;
111d8eea993SPekka Enberg 	u32 nr_read;
1123dac48d4SPrasad Joshi 	u32 nr;
1133dac48d4SPrasad Joshi 
114d8eea993SPekka Enberg 	nr_read = 0;
115d8eea993SPekka Enberg 	while (nr_read < dst_len) {
1163dac48d4SPrasad Joshi 		offset = sector << SECTOR_SHIFT;
1173dac48d4SPrasad Joshi 		if (offset >= header->size)
1183dac48d4SPrasad Joshi 			goto out_error;
1193dac48d4SPrasad Joshi 
120d8eea993SPekka Enberg 		nr = qcow1_read_cluster(q, offset, buf, dst_len - nr_read);
121a51948ceSPekka Enberg 		if (nr <= 0)
1223dac48d4SPrasad Joshi 			goto out_error;
1233dac48d4SPrasad Joshi 
124d8eea993SPekka Enberg 		nr_read		+= nr;
1253dac48d4SPrasad Joshi 		buf		+= nr;
1263dac48d4SPrasad Joshi 		sector		+= (nr >> SECTOR_SHIFT);
1273dac48d4SPrasad Joshi 	}
1283dac48d4SPrasad Joshi 	return 0;
1293dac48d4SPrasad Joshi out_error:
13086835cedSPrasad Joshi 	return -1;
13186835cedSPrasad Joshi }
13286835cedSPrasad Joshi 
133*43835ac9SSasha Levin static int qcow1_write_sector(struct disk_image *disk, u64 sector, void *src, u32 src_len)
13486835cedSPrasad Joshi {
13586835cedSPrasad Joshi 	return -1;
13686835cedSPrasad Joshi }
13786835cedSPrasad Joshi 
138*43835ac9SSasha Levin static void qcow1_disk_close(struct disk_image *disk)
13986835cedSPrasad Joshi {
14086835cedSPrasad Joshi 	struct qcow *q;
14186835cedSPrasad Joshi 
142*43835ac9SSasha Levin 	if (!disk)
14386835cedSPrasad Joshi 		return;
14486835cedSPrasad Joshi 
145*43835ac9SSasha Levin 	q = disk->priv;
14686835cedSPrasad Joshi 
1476c6f79b6SPrasad Joshi 	free(q->table.l1_table);
14886835cedSPrasad Joshi 	free(q->header);
14986835cedSPrasad Joshi 	free(q);
15086835cedSPrasad Joshi }
15186835cedSPrasad Joshi 
15286835cedSPrasad Joshi struct disk_image_operations qcow1_disk_ops = {
15386835cedSPrasad Joshi 	.read_sector		= qcow1_read_sector,
15486835cedSPrasad Joshi 	.write_sector		= qcow1_write_sector,
15586835cedSPrasad Joshi 	.close			= qcow1_disk_close
15686835cedSPrasad Joshi };
15786835cedSPrasad Joshi 
15886835cedSPrasad Joshi static int qcow_read_l1_table(struct qcow *q)
15986835cedSPrasad Joshi {
160ad627d62SPekka Enberg 	struct qcow_header *header = q->header;
16100adcc1bSPrasad Joshi 	struct qcow_table *table = &q->table;
16200adcc1bSPrasad Joshi 	u64 i;
16386835cedSPrasad Joshi 
164ad627d62SPekka Enberg 	table->table_size	= header->l1_size;
16586835cedSPrasad Joshi 
16600adcc1bSPrasad Joshi 	table->l1_table	= calloc(table->table_size, sizeof(u64));
16700adcc1bSPrasad Joshi 	if (!table->l1_table)
16886835cedSPrasad Joshi 		return -1;
16986835cedSPrasad Joshi 
17000adcc1bSPrasad Joshi 	if (pread_in_full(q->fd, table->l1_table, sizeof(u64) *
17100adcc1bSPrasad Joshi 				table->table_size, header->l1_table_offset) < 0)
17286835cedSPrasad Joshi 		return -1;
17386835cedSPrasad Joshi 
17400adcc1bSPrasad Joshi 	for (i = 0; i < table->table_size; i++)
17500adcc1bSPrasad Joshi 		be64_to_cpus(&table->l1_table[i]);
17600adcc1bSPrasad Joshi 
17786835cedSPrasad Joshi 	return 0;
17886835cedSPrasad Joshi }
17986835cedSPrasad Joshi 
180ad627d62SPekka Enberg static void *qcow2_read_header(int fd)
18186835cedSPrasad Joshi {
182ad627d62SPekka Enberg 	struct qcow2_header_disk f_header;
183ad627d62SPekka Enberg 	struct qcow_header *header;
18486835cedSPrasad Joshi 
185ad627d62SPekka Enberg 	header = malloc(sizeof(struct qcow_header));
18686835cedSPrasad Joshi 	if (!header)
18786835cedSPrasad Joshi 		return NULL;
18886835cedSPrasad Joshi 
1890657f33dSPrasad Joshi 	if (pread_in_full(fd, &f_header, sizeof(struct qcow2_header_disk), 0) < 0) {
1900657f33dSPrasad Joshi 		free(header);
19186835cedSPrasad Joshi 		return NULL;
1920657f33dSPrasad Joshi 	}
19386835cedSPrasad Joshi 
194ad627d62SPekka Enberg 	be32_to_cpus(&f_header.magic);
195ad627d62SPekka Enberg 	be32_to_cpus(&f_header.version);
196ad627d62SPekka Enberg 	be64_to_cpus(&f_header.backing_file_offset);
197ad627d62SPekka Enberg 	be32_to_cpus(&f_header.backing_file_size);
198ad627d62SPekka Enberg 	be32_to_cpus(&f_header.cluster_bits);
199ad627d62SPekka Enberg 	be64_to_cpus(&f_header.size);
200ad627d62SPekka Enberg 	be32_to_cpus(&f_header.crypt_method);
201ad627d62SPekka Enberg 	be32_to_cpus(&f_header.l1_size);
202ad627d62SPekka Enberg 	be64_to_cpus(&f_header.l1_table_offset);
203ad627d62SPekka Enberg 	be64_to_cpus(&f_header.refcount_table_offset);
204ad627d62SPekka Enberg 	be32_to_cpus(&f_header.refcount_table_clusters);
205ad627d62SPekka Enberg 	be32_to_cpus(&f_header.nb_snapshots);
206ad627d62SPekka Enberg 	be64_to_cpus(&f_header.snapshots_offset);
207ad627d62SPekka Enberg 
208ad627d62SPekka Enberg 	*header		= (struct qcow_header) {
209ad627d62SPekka Enberg 		.size			= f_header.size,
210ad627d62SPekka Enberg 		.l1_table_offset	= f_header.l1_table_offset,
211ad627d62SPekka Enberg 		.l1_size		= f_header.l1_size,
212ad627d62SPekka Enberg 		.cluster_bits		= f_header.cluster_bits,
213ad627d62SPekka Enberg 		.l2_bits		= f_header.cluster_bits - 3,
214ad627d62SPekka Enberg 		.oflag_mask		= QCOW2_OFLAG_MASK,
215ad627d62SPekka Enberg 	};
216ad627d62SPekka Enberg 
217ad627d62SPekka Enberg 	return header;
218ad627d62SPekka Enberg }
219ad627d62SPekka Enberg 
220ad627d62SPekka Enberg static struct disk_image *qcow2_probe(int fd)
221ad627d62SPekka Enberg {
222ad627d62SPekka Enberg 	struct qcow *q;
223ad627d62SPekka Enberg 	struct qcow_header *h;
224ad627d62SPekka Enberg 	struct disk_image *disk_image;
225ad627d62SPekka Enberg 
226ad627d62SPekka Enberg 	q = calloc(1, sizeof(struct qcow));
227ad627d62SPekka Enberg 	if (!q)
228ad627d62SPekka Enberg 		goto error;
229ad627d62SPekka Enberg 
230ad627d62SPekka Enberg 	q->fd = fd;
231ad627d62SPekka Enberg 
232ad627d62SPekka Enberg 	h = q->header = qcow2_read_header(fd);
233ad627d62SPekka Enberg 	if (!h)
234ad627d62SPekka Enberg 		goto error;
235ad627d62SPekka Enberg 
236ad627d62SPekka Enberg 	if (qcow_read_l1_table(q) < 0)
237ad627d62SPekka Enberg 		goto error;
238ad627d62SPekka Enberg 
239ad627d62SPekka Enberg 	disk_image = disk_image__new(fd, h->size, &qcow1_disk_ops);
240ad627d62SPekka Enberg 	if (!disk_image)
241ad627d62SPekka Enberg 		goto error;
242ad627d62SPekka Enberg 	disk_image->priv = q;
243ad627d62SPekka Enberg 
244ad627d62SPekka Enberg 	return disk_image;
245ad627d62SPekka Enberg error:
246ad627d62SPekka Enberg 	if (!q)
247ad627d62SPekka Enberg 		return NULL;
248ad627d62SPekka Enberg 
249ad627d62SPekka Enberg 	free(q->table.l1_table);
250ad627d62SPekka Enberg 	free(q->header);
251ad627d62SPekka Enberg 	free(q);
252ad627d62SPekka Enberg 
253ad627d62SPekka Enberg 	return NULL;
254ad627d62SPekka Enberg }
255ad627d62SPekka Enberg 
256ad627d62SPekka Enberg static bool qcow2_check_image(int fd)
257ad627d62SPekka Enberg {
258ad627d62SPekka Enberg 	struct qcow2_header_disk f_header;
259ad627d62SPekka Enberg 
260ad627d62SPekka Enberg 	if (pread_in_full(fd, &f_header, sizeof(struct qcow2_header_disk), 0) < 0)
261ad627d62SPekka Enberg 		return false;
262ad627d62SPekka Enberg 
263ad627d62SPekka Enberg 	be32_to_cpus(&f_header.magic);
264ad627d62SPekka Enberg 	be32_to_cpus(&f_header.version);
265ad627d62SPekka Enberg 
266ad627d62SPekka Enberg 	if (f_header.magic != QCOW_MAGIC)
267ad627d62SPekka Enberg 		return false;
268ad627d62SPekka Enberg 
269ad627d62SPekka Enberg 	if (f_header.version != QCOW2_VERSION)
270ad627d62SPekka Enberg 		return false;
271ad627d62SPekka Enberg 
272ad627d62SPekka Enberg 	return true;
273ad627d62SPekka Enberg }
274ad627d62SPekka Enberg 
275ad627d62SPekka Enberg static void *qcow1_read_header(int fd)
276ad627d62SPekka Enberg {
277ad627d62SPekka Enberg 	struct qcow1_header_disk f_header;
278ad627d62SPekka Enberg 	struct qcow_header *header;
279ad627d62SPekka Enberg 
280ad627d62SPekka Enberg 	header = malloc(sizeof(struct qcow_header));
281ad627d62SPekka Enberg 	if (!header)
282ad627d62SPekka Enberg 		return NULL;
283ad627d62SPekka Enberg 
284d39cefd2SSasha Levin 	if (pread_in_full(fd, &f_header, sizeof(struct qcow1_header_disk), 0) < 0) {
285d39cefd2SSasha Levin 		free(header);
286ad627d62SPekka Enberg 		return NULL;
287d39cefd2SSasha Levin 	}
288ad627d62SPekka Enberg 
289ad627d62SPekka Enberg 	be32_to_cpus(&f_header.magic);
290ad627d62SPekka Enberg 	be32_to_cpus(&f_header.version);
291ad627d62SPekka Enberg 	be64_to_cpus(&f_header.backing_file_offset);
292ad627d62SPekka Enberg 	be32_to_cpus(&f_header.backing_file_size);
293ad627d62SPekka Enberg 	be32_to_cpus(&f_header.mtime);
294ad627d62SPekka Enberg 	be64_to_cpus(&f_header.size);
295ad627d62SPekka Enberg 	be32_to_cpus(&f_header.crypt_method);
296ad627d62SPekka Enberg 	be64_to_cpus(&f_header.l1_table_offset);
297ad627d62SPekka Enberg 
298ad627d62SPekka Enberg 	*header		= (struct qcow_header) {
299ad627d62SPekka Enberg 		.size			= f_header.size,
300ad627d62SPekka Enberg 		.l1_table_offset	= f_header.l1_table_offset,
301ad627d62SPekka Enberg 		.l1_size		= f_header.size / ((1 << f_header.l2_bits) * (1 << f_header.cluster_bits)),
302ad627d62SPekka Enberg 		.cluster_bits		= f_header.cluster_bits,
303ad627d62SPekka Enberg 		.l2_bits		= f_header.l2_bits,
304ad627d62SPekka Enberg 		.oflag_mask		= QCOW1_OFLAG_MASK,
305ad627d62SPekka Enberg 	};
30686835cedSPrasad Joshi 
30786835cedSPrasad Joshi 	return header;
30886835cedSPrasad Joshi }
30986835cedSPrasad Joshi 
31086835cedSPrasad Joshi static struct disk_image *qcow1_probe(int fd)
31186835cedSPrasad Joshi {
31286835cedSPrasad Joshi 	struct qcow *q;
313ad627d62SPekka Enberg 	struct qcow_header *h;
31486835cedSPrasad Joshi 	struct disk_image *disk_image;
31586835cedSPrasad Joshi 
31686835cedSPrasad Joshi 	q = calloc(1, sizeof(struct qcow));
31786835cedSPrasad Joshi 	if (!q)
31886835cedSPrasad Joshi 		goto error;
31986835cedSPrasad Joshi 
32086835cedSPrasad Joshi 	q->fd = fd;
32186835cedSPrasad Joshi 
32286835cedSPrasad Joshi 	h = q->header = qcow1_read_header(fd);
32386835cedSPrasad Joshi 	if (!h)
32486835cedSPrasad Joshi 		goto error;
32586835cedSPrasad Joshi 
32686835cedSPrasad Joshi 	if (qcow_read_l1_table(q) < 0)
32786835cedSPrasad Joshi 		goto error;
32886835cedSPrasad Joshi 
32986835cedSPrasad Joshi 	disk_image = disk_image__new(fd, h->size, &qcow1_disk_ops);
33086835cedSPrasad Joshi 	if (!disk_image)
33186835cedSPrasad Joshi 		goto error;
33286835cedSPrasad Joshi 	disk_image->priv = q;
33386835cedSPrasad Joshi 
33486835cedSPrasad Joshi 	return disk_image;
33586835cedSPrasad Joshi error:
33686835cedSPrasad Joshi 	if (!q)
33786835cedSPrasad Joshi 		return NULL;
33886835cedSPrasad Joshi 
3396c6f79b6SPrasad Joshi 	free(q->table.l1_table);
34086835cedSPrasad Joshi 	free(q->header);
34186835cedSPrasad Joshi 	free(q);
34286835cedSPrasad Joshi 
34386835cedSPrasad Joshi 	return NULL;
34486835cedSPrasad Joshi }
34586835cedSPrasad Joshi 
346ad627d62SPekka Enberg static bool qcow1_check_image(int fd)
34786835cedSPrasad Joshi {
348ad627d62SPekka Enberg 	struct qcow1_header_disk f_header;
34986835cedSPrasad Joshi 
350ad627d62SPekka Enberg 	if (pread_in_full(fd, &f_header, sizeof(struct qcow1_header_disk), 0) < 0)
351ad627d62SPekka Enberg 		return false;
35286835cedSPrasad Joshi 
353ad627d62SPekka Enberg 	be32_to_cpus(&f_header.magic);
354ad627d62SPekka Enberg 	be32_to_cpus(&f_header.version);
35586835cedSPrasad Joshi 
356ad627d62SPekka Enberg 	if (f_header.magic != QCOW_MAGIC)
357ad627d62SPekka Enberg 		return false;
35886835cedSPrasad Joshi 
359ad627d62SPekka Enberg 	if (f_header.version != QCOW1_VERSION)
360ad627d62SPekka Enberg 		return false;
36186835cedSPrasad Joshi 
362ad627d62SPekka Enberg 	return true;
36386835cedSPrasad Joshi }
36486835cedSPrasad Joshi 
36586835cedSPrasad Joshi struct disk_image *qcow_probe(int fd)
36686835cedSPrasad Joshi {
367ad627d62SPekka Enberg 	if (qcow1_check_image(fd))
36886835cedSPrasad Joshi 		return qcow1_probe(fd);
369ad627d62SPekka Enberg 
370ad627d62SPekka Enberg 	if (qcow2_check_image(fd))
371ad627d62SPekka Enberg 		return qcow2_probe(fd);
372ad627d62SPekka Enberg 
373ad627d62SPekka Enberg 	return NULL;
37486835cedSPrasad Joshi }
375