1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2015 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
24 #include "alloc-util.h"
25 #include "btrfs-util.h"
26 #include "qcow2-util.h"
27 #include "sparse-endian.h"
30 #define QCOW2_MAGIC 0x514649fb
32 #define QCOW2_COPIED (1ULL << 63)
33 #define QCOW2_COMPRESSED (1ULL << 62)
34 #define QCOW2_ZERO (1ULL << 0)
36 typedef struct _packed_ Header
{
40 be64_t backing_file_offset
;
41 be32_t backing_file_size
;
48 be64_t l1_table_offset
;
50 be64_t refcount_table_offset
;
51 be32_t refcount_table_clusters
;
54 be64_t snapshots_offset
;
56 /* The remainder is only present on QCOW3 */
57 be64_t incompatible_features
;
58 be64_t compatible_features
;
59 be64_t autoclear_features
;
61 be32_t refcount_order
;
65 #define HEADER_MAGIC(header) be32toh((header)->magic)
66 #define HEADER_VERSION(header) be32toh((header)->version)
67 #define HEADER_CLUSTER_BITS(header) be32toh((header)->cluster_bits)
68 #define HEADER_CLUSTER_SIZE(header) (1ULL << HEADER_CLUSTER_BITS(header))
69 #define HEADER_L2_BITS(header) (HEADER_CLUSTER_BITS(header) - 3)
70 #define HEADER_SIZE(header) be64toh((header)->size)
71 #define HEADER_CRYPT_METHOD(header) be32toh((header)->crypt_method)
72 #define HEADER_L1_SIZE(header) be32toh((header)->l1_size)
73 #define HEADER_L2_SIZE(header) (HEADER_CLUSTER_SIZE(header)/sizeof(uint64_t))
74 #define HEADER_L1_TABLE_OFFSET(header) be64toh((header)->l1_table_offset)
76 static uint32_t HEADER_HEADER_LENGTH(const Header
*h
) {
77 if (HEADER_VERSION(h
) < 3)
78 return offsetof(Header
, incompatible_features
);
80 return be32toh(h
->header_length
);
83 static int copy_cluster(
84 int sfd
, uint64_t soffset
,
85 int dfd
, uint64_t doffset
,
86 uint64_t cluster_size
,
92 r
= btrfs_clone_range(sfd
, soffset
, dfd
, doffset
, cluster_size
);
96 l
= pread(sfd
, buffer
, cluster_size
, soffset
);
99 if ((uint64_t) l
!= cluster_size
)
102 l
= pwrite(dfd
, buffer
, cluster_size
, doffset
);
105 if ((uint64_t) l
!= cluster_size
)
111 static int decompress_cluster(
112 int sfd
, uint64_t soffset
,
113 int dfd
, uint64_t doffset
,
114 uint64_t compressed_size
,
115 uint64_t cluster_size
,
119 _cleanup_free_
void *large_buffer
= NULL
;
125 if (compressed_size
> cluster_size
) {
126 /* The usual cluster buffer doesn't suffice, let's
127 * allocate a larger one, temporarily */
129 large_buffer
= malloc(compressed_size
);
133 buffer1
= large_buffer
;
136 l
= pread(sfd
, buffer1
, compressed_size
, soffset
);
139 if ((uint64_t) l
!= compressed_size
)
143 s
.avail_in
= compressed_size
;
144 s
.next_out
= buffer2
;
145 s
.avail_out
= cluster_size
;
147 r
= inflateInit2(&s
, -12);
151 r
= inflate(&s
, Z_FINISH
);
152 sz
= (uint8_t*) s
.next_out
- (uint8_t*) buffer2
;
154 if (r
!= Z_STREAM_END
|| sz
!= cluster_size
)
157 l
= pwrite(dfd
, buffer2
, cluster_size
, doffset
);
160 if ((uint64_t) l
!= cluster_size
)
166 static int normalize_offset(
167 const Header
*header
,
171 uint64_t *compressed_size
) {
177 if (q
& QCOW2_COMPRESSED
) {
178 uint64_t sz
, csize_shift
, csize_mask
;
183 csize_shift
= 64 - 2 - (HEADER_CLUSTER_BITS(header
) - 8);
184 csize_mask
= (1ULL << (HEADER_CLUSTER_BITS(header
) - 8)) - 1;
185 sz
= (((q
>> csize_shift
) & csize_mask
) + 1) * 512 - (q
& 511);
186 q
&= ((1ULL << csize_shift
) - 1);
189 *compressed_size
= sz
;
196 *compressed_size
= 0;
199 if (q
& QCOW2_ZERO
) {
200 /* We make no distinction between zero blocks and holes */
209 return q
> 0; /* returns positive if not a hole */
212 static int verify_header(const Header
*header
) {
215 if (HEADER_MAGIC(header
) != QCOW2_MAGIC
)
218 if (HEADER_VERSION(header
) != 2 &&
219 HEADER_VERSION(header
) != 3)
222 if (HEADER_CRYPT_METHOD(header
) != 0)
225 if (HEADER_CLUSTER_BITS(header
) < 9) /* 512K */
228 if (HEADER_CLUSTER_BITS(header
) > 21) /* 2MB */
231 if (HEADER_SIZE(header
) % HEADER_CLUSTER_SIZE(header
) != 0)
234 if (HEADER_L1_SIZE(header
) > 32*1024*1024) /* 32MB */
237 if (HEADER_VERSION(header
) == 3) {
239 if (header
->incompatible_features
!= 0)
242 if (HEADER_HEADER_LENGTH(header
) < sizeof(Header
))
249 int qcow2_convert(int qcow2_fd
, int raw_fd
) {
250 _cleanup_free_
void *buffer1
= NULL
, *buffer2
= NULL
;
251 _cleanup_free_ be64_t
*l1_table
= NULL
, *l2_table
= NULL
;
257 l
= pread(qcow2_fd
, &header
, sizeof(header
), 0);
260 if (l
!= sizeof(header
))
263 r
= verify_header(&header
);
267 l1_table
= new(be64_t
, HEADER_L1_SIZE(&header
));
271 l2_table
= malloc(HEADER_CLUSTER_SIZE(&header
));
275 buffer1
= malloc(HEADER_CLUSTER_SIZE(&header
));
279 buffer2
= malloc(HEADER_CLUSTER_SIZE(&header
));
283 /* Empty the file if it exists, we rely on zero bits */
284 if (ftruncate(raw_fd
, 0) < 0)
287 if (ftruncate(raw_fd
, HEADER_SIZE(&header
)) < 0)
290 sz
= sizeof(uint64_t) * HEADER_L1_SIZE(&header
);
291 l
= pread(qcow2_fd
, l1_table
, sz
, HEADER_L1_TABLE_OFFSET(&header
));
294 if ((uint64_t) l
!= sz
)
297 for (i
= 0; i
< HEADER_L1_SIZE(&header
); i
++) {
298 uint64_t l2_begin
, j
;
300 r
= normalize_offset(&header
, l1_table
[i
], &l2_begin
, NULL
, NULL
);
306 l
= pread(qcow2_fd
, l2_table
, HEADER_CLUSTER_SIZE(&header
), l2_begin
);
309 if ((uint64_t) l
!= HEADER_CLUSTER_SIZE(&header
))
312 for (j
= 0; j
< HEADER_L2_SIZE(&header
); j
++) {
313 uint64_t data_begin
, p
, compressed_size
;
316 p
= ((i
<< HEADER_L2_BITS(&header
)) + j
) << HEADER_CLUSTER_BITS(&header
);
318 r
= normalize_offset(&header
, l2_table
[j
], &data_begin
, &compressed
, &compressed_size
);
325 r
= decompress_cluster(
326 qcow2_fd
, data_begin
,
328 compressed_size
, HEADER_CLUSTER_SIZE(&header
),
332 qcow2_fd
, data_begin
,
334 HEADER_CLUSTER_SIZE(&header
), buffer1
);
343 int qcow2_detect(int fd
) {
347 l
= pread(fd
, &id
, sizeof(id
), 0);
353 return htobe32(QCOW2_MAGIC
) == id
;