1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2015 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include "alloc-util.h"
24 #include "btrfs-util.h"
25 #include "qcow2-util.h"
26 #include "sparse-endian.h"
29 #define QCOW2_MAGIC 0x514649fb
31 #define QCOW2_COPIED (1ULL << 63)
32 #define QCOW2_COMPRESSED (1ULL << 62)
33 #define QCOW2_ZERO (1ULL << 0)
35 typedef struct _packed_ Header
{
39 be64_t backing_file_offset
;
40 be32_t backing_file_size
;
47 be64_t l1_table_offset
;
49 be64_t refcount_table_offset
;
50 be32_t refcount_table_clusters
;
53 be64_t snapshots_offset
;
55 /* The remainder is only present on QCOW3 */
56 be64_t incompatible_features
;
57 be64_t compatible_features
;
58 be64_t autoclear_features
;
60 be32_t refcount_order
;
64 #define HEADER_MAGIC(header) be32toh((header)->magic)
65 #define HEADER_VERSION(header) be32toh((header)->version)
66 #define HEADER_CLUSTER_BITS(header) be32toh((header)->cluster_bits)
67 #define HEADER_CLUSTER_SIZE(header) (1ULL << HEADER_CLUSTER_BITS(header))
68 #define HEADER_L2_BITS(header) (HEADER_CLUSTER_BITS(header) - 3)
69 #define HEADER_SIZE(header) be64toh((header)->size)
70 #define HEADER_CRYPT_METHOD(header) be32toh((header)->crypt_method)
71 #define HEADER_L1_SIZE(header) be32toh((header)->l1_size)
72 #define HEADER_L2_SIZE(header) (HEADER_CLUSTER_SIZE(header)/sizeof(uint64_t))
73 #define HEADER_L1_TABLE_OFFSET(header) be64toh((header)->l1_table_offset)
75 static uint32_t HEADER_HEADER_LENGTH(const Header
*h
) {
76 if (HEADER_VERSION(h
) < 3)
77 return offsetof(Header
, incompatible_features
);
79 return be32toh(h
->header_length
);
82 static int copy_cluster(
83 int sfd
, uint64_t soffset
,
84 int dfd
, uint64_t doffset
,
85 uint64_t cluster_size
,
91 r
= btrfs_clone_range(sfd
, soffset
, dfd
, doffset
, cluster_size
);
95 l
= pread(sfd
, buffer
, cluster_size
, soffset
);
98 if ((uint64_t) l
!= cluster_size
)
101 l
= pwrite(dfd
, buffer
, cluster_size
, doffset
);
104 if ((uint64_t) l
!= cluster_size
)
110 static int decompress_cluster(
111 int sfd
, uint64_t soffset
,
112 int dfd
, uint64_t doffset
,
113 uint64_t compressed_size
,
114 uint64_t cluster_size
,
118 _cleanup_free_
void *large_buffer
= NULL
;
124 if (compressed_size
> cluster_size
) {
125 /* The usual cluster buffer doesn't suffice, let's
126 * allocate a larger one, temporarily */
128 large_buffer
= malloc(compressed_size
);
132 buffer1
= large_buffer
;
135 l
= pread(sfd
, buffer1
, compressed_size
, soffset
);
138 if ((uint64_t) l
!= compressed_size
)
142 s
.avail_in
= compressed_size
;
143 s
.next_out
= buffer2
;
144 s
.avail_out
= cluster_size
;
146 r
= inflateInit2(&s
, -12);
150 r
= inflate(&s
, Z_FINISH
);
151 sz
= (uint8_t*) s
.next_out
- (uint8_t*) buffer2
;
153 if (r
!= Z_STREAM_END
|| sz
!= cluster_size
)
156 l
= pwrite(dfd
, buffer2
, cluster_size
, doffset
);
159 if ((uint64_t) l
!= cluster_size
)
165 static int normalize_offset(
166 const Header
*header
,
170 uint64_t *compressed_size
) {
176 if (q
& QCOW2_COMPRESSED
) {
177 uint64_t sz
, csize_shift
, csize_mask
;
182 csize_shift
= 64 - 2 - (HEADER_CLUSTER_BITS(header
) - 8);
183 csize_mask
= (1ULL << (HEADER_CLUSTER_BITS(header
) - 8)) - 1;
184 sz
= (((q
>> csize_shift
) & csize_mask
) + 1) * 512 - (q
& 511);
185 q
&= ((1ULL << csize_shift
) - 1);
188 *compressed_size
= sz
;
195 *compressed_size
= 0;
198 if (q
& QCOW2_ZERO
) {
199 /* We make no distinction between zero blocks and holes */
208 return q
> 0; /* returns positive if not a hole */
211 static int verify_header(const Header
*header
) {
214 if (HEADER_MAGIC(header
) != QCOW2_MAGIC
)
217 if (!IN_SET(HEADER_VERSION(header
), 2, 3))
220 if (HEADER_CRYPT_METHOD(header
) != 0)
223 if (HEADER_CLUSTER_BITS(header
) < 9) /* 512K */
226 if (HEADER_CLUSTER_BITS(header
) > 21) /* 2MB */
229 if (HEADER_SIZE(header
) % HEADER_CLUSTER_SIZE(header
) != 0)
232 if (HEADER_L1_SIZE(header
) > 32*1024*1024) /* 32MB */
235 if (HEADER_VERSION(header
) == 3) {
237 if (header
->incompatible_features
!= 0)
240 if (HEADER_HEADER_LENGTH(header
) < sizeof(Header
))
247 int qcow2_convert(int qcow2_fd
, int raw_fd
) {
248 _cleanup_free_
void *buffer1
= NULL
, *buffer2
= NULL
;
249 _cleanup_free_ be64_t
*l1_table
= NULL
, *l2_table
= NULL
;
255 l
= pread(qcow2_fd
, &header
, sizeof(header
), 0);
258 if (l
!= sizeof(header
))
261 r
= verify_header(&header
);
265 l1_table
= new(be64_t
, HEADER_L1_SIZE(&header
));
269 l2_table
= malloc(HEADER_CLUSTER_SIZE(&header
));
273 buffer1
= malloc(HEADER_CLUSTER_SIZE(&header
));
277 buffer2
= malloc(HEADER_CLUSTER_SIZE(&header
));
281 /* Empty the file if it exists, we rely on zero bits */
282 if (ftruncate(raw_fd
, 0) < 0)
285 if (ftruncate(raw_fd
, HEADER_SIZE(&header
)) < 0)
288 sz
= sizeof(uint64_t) * HEADER_L1_SIZE(&header
);
289 l
= pread(qcow2_fd
, l1_table
, sz
, HEADER_L1_TABLE_OFFSET(&header
));
292 if ((uint64_t) l
!= sz
)
295 for (i
= 0; i
< HEADER_L1_SIZE(&header
); i
++) {
296 uint64_t l2_begin
, j
;
298 r
= normalize_offset(&header
, l1_table
[i
], &l2_begin
, NULL
, NULL
);
304 l
= pread(qcow2_fd
, l2_table
, HEADER_CLUSTER_SIZE(&header
), l2_begin
);
307 if ((uint64_t) l
!= HEADER_CLUSTER_SIZE(&header
))
310 for (j
= 0; j
< HEADER_L2_SIZE(&header
); j
++) {
311 uint64_t data_begin
, p
, compressed_size
;
314 p
= ((i
<< HEADER_L2_BITS(&header
)) + j
) << HEADER_CLUSTER_BITS(&header
);
316 r
= normalize_offset(&header
, l2_table
[j
], &data_begin
, &compressed
, &compressed_size
);
323 r
= decompress_cluster(
324 qcow2_fd
, data_begin
,
326 compressed_size
, HEADER_CLUSTER_SIZE(&header
),
330 qcow2_fd
, data_begin
,
332 HEADER_CLUSTER_SIZE(&header
), buffer1
);
341 int qcow2_detect(int fd
) {
345 l
= pread(fd
, &id
, sizeof(id
), 0);
351 return htobe32(QCOW2_MAGIC
) == id
;