1 /*- 2 * Copyright (c) 2014 Marcel Moolenaar 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/types.h> 31 #include <sys/errno.h> 32 #include <assert.h> 33 #include <stdint.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <unistd.h> 38 39 #include "endian.h" 40 #include "image.h" 41 #include "format.h" 42 #include "mkimg.h" 43 44 /* Default cluster sizes. */ 45 #define QCOW1_CLSTR_LOG2SZ 12 /* 4KB */ 46 #define QCOW2_CLSTR_LOG2SZ 16 /* 64KB */ 47 48 /* Flag bits in cluster offsets */ 49 #define QCOW_CLSTR_COMPRESSED (1ULL << 62) 50 #define QCOW_CLSTR_COPIED (1ULL << 63) 51 52 struct qcow_header { 53 uint32_t magic; 54 #define QCOW_MAGIC 0x514649fb 55 uint32_t version; 56 #define QCOW_VERSION_1 1 57 #define QCOW_VERSION_2 2 58 uint64_t path_offset; 59 uint32_t path_length; 60 uint32_t clstr_log2sz; /* v2 only */ 61 uint64_t disk_size; 62 union { 63 struct { 64 uint8_t clstr_log2sz; 65 uint8_t l2_log2sz; 66 uint16_t _pad; 67 uint32_t encryption; 68 uint64_t l1_offset; 69 } v1; 70 struct { 71 uint32_t encryption; 72 uint32_t l1_entries; 73 uint64_t l1_offset; 74 uint64_t refcnt_offset; 75 uint32_t refcnt_clstrs; 76 uint32_t snapshot_count; 77 uint64_t snapshot_offset; 78 } v2; 79 } u; 80 }; 81 82 static u_int clstr_log2sz; 83 84 static uint64_t 85 round_clstr(uint64_t ofs) 86 { 87 uint64_t clstrsz; 88 89 clstrsz = 1UL << clstr_log2sz; 90 return ((ofs + clstrsz - 1) & ~(clstrsz - 1)); 91 } 92 93 static int 94 qcow_resize(lba_t imgsz, u_int version) 95 { 96 uint64_t imagesz; 97 98 switch (version) { 99 case QCOW_VERSION_1: 100 clstr_log2sz = QCOW1_CLSTR_LOG2SZ; 101 break; 102 case QCOW_VERSION_2: 103 clstr_log2sz = QCOW2_CLSTR_LOG2SZ; 104 break; 105 default: 106 assert(0); 107 } 108 109 imagesz = round_clstr(imgsz * secsz); 110 111 if (verbose) 112 fprintf(stderr, "QCOW: image size = %ju, cluster size = %u\n", 113 (uintmax_t)imagesz, (u_int)(1U << clstr_log2sz)); 114 115 return (image_set_size(imagesz / secsz)); 116 } 117 118 static int 119 qcow1_resize(lba_t imgsz) 120 { 121 122 return (qcow_resize(imgsz, QCOW_VERSION_1)); 123 } 124 125 static int 126 qcow2_resize(lba_t imgsz) 127 { 128 129 return (qcow_resize(imgsz, QCOW_VERSION_2)); 130 } 131 132 static int 133 qcow_write(int fd, u_int version) 134 { 135 struct qcow_header *hdr; 136 uint64_t *l1tbl, *l2tbl, *rctbl; 137 uint16_t *rcblk; 138 uint64_t clstr_imgsz, clstr_l2tbls, clstr_l1tblsz; 139 uint64_t clstr_rcblks, clstr_rctblsz; 140 uint64_t n, imagesz, nclstrs, ofs, ofsflags; 141 lba_t blk, blkofs, blk_imgsz; 142 u_int l1clno, l2clno, rcclno; 143 u_int blk_clstrsz, refcnt_clstrs; 144 u_int clstrsz, l1idx, l2idx; 145 int error; 146 147 assert(clstr_log2sz != 0); 148 149 clstrsz = 1U << clstr_log2sz; 150 blk_clstrsz = clstrsz / secsz; 151 blk_imgsz = image_get_size(); 152 imagesz = blk_imgsz * secsz; 153 clstr_imgsz = imagesz >> clstr_log2sz; 154 clstr_l2tbls = round_clstr(clstr_imgsz * 8) >> clstr_log2sz; 155 clstr_l1tblsz = round_clstr(clstr_l2tbls * 8) >> clstr_log2sz; 156 nclstrs = clstr_imgsz + clstr_l2tbls + clstr_l1tblsz + 1; 157 clstr_rcblks = clstr_rctblsz = 0; 158 do { 159 n = clstr_rcblks + clstr_rctblsz; 160 clstr_rcblks = round_clstr((nclstrs + n) * 2) >> clstr_log2sz; 161 clstr_rctblsz = round_clstr(clstr_rcblks * 8) >> clstr_log2sz; 162 } while (n < (clstr_rcblks + clstr_rctblsz)); 163 164 /* 165 * We got all the sizes in clusters. Start the layout. 166 * 0 - header 167 * 1 - L1 table 168 * 2 - RC table (v2 only) 169 * 3 - L2 tables 170 * 4 - RC block (v2 only) 171 * 5 - data 172 */ 173 174 l1clno = 1; 175 rcclno = 0; 176 rctbl = l2tbl = l1tbl = NULL; 177 rcblk = NULL; 178 179 hdr = calloc(1, clstrsz); 180 if (hdr == NULL) 181 return (errno); 182 183 be32enc(&hdr->magic, QCOW_MAGIC); 184 be32enc(&hdr->version, version); 185 be64enc(&hdr->disk_size, imagesz); 186 switch (version) { 187 case QCOW_VERSION_1: 188 ofsflags = 0; 189 l2clno = l1clno + clstr_l1tblsz; 190 hdr->u.v1.clstr_log2sz = clstr_log2sz; 191 hdr->u.v1.l2_log2sz = clstr_log2sz - 3; 192 be64enc(&hdr->u.v1.l1_offset, clstrsz * l1clno); 193 break; 194 case QCOW_VERSION_2: 195 ofsflags = QCOW_CLSTR_COPIED; 196 rcclno = l1clno + clstr_l1tblsz; 197 l2clno = rcclno + clstr_rctblsz; 198 be32enc(&hdr->clstr_log2sz, clstr_log2sz); 199 be32enc(&hdr->u.v2.l1_entries, clstr_l2tbls); 200 be64enc(&hdr->u.v2.l1_offset, clstrsz * l1clno); 201 be64enc(&hdr->u.v2.refcnt_offset, clstrsz * rcclno); 202 refcnt_clstrs = round_clstr(clstr_rcblks * 8) >> clstr_log2sz; 203 be32enc(&hdr->u.v2.refcnt_clstrs, refcnt_clstrs); 204 break; 205 default: 206 assert(0); 207 } 208 209 if (sparse_write(fd, hdr, clstrsz) < 0) { 210 error = errno; 211 goto out; 212 } 213 214 free(hdr); 215 hdr = NULL; 216 217 ofs = clstrsz * l2clno; 218 nclstrs = 1 + clstr_l1tblsz + clstr_rctblsz; 219 220 l1tbl = calloc(1, clstrsz * clstr_l1tblsz); 221 if (l1tbl == NULL) { 222 error = ENOMEM; 223 goto out; 224 } 225 226 for (n = 0; n < clstr_imgsz; n++) { 227 blk = n * blk_clstrsz; 228 if (image_data(blk, blk_clstrsz)) { 229 nclstrs++; 230 l1idx = n >> (clstr_log2sz - 3); 231 if (l1tbl[l1idx] == 0) { 232 be64enc(l1tbl + l1idx, ofs + ofsflags); 233 ofs += clstrsz; 234 nclstrs++; 235 } 236 } 237 } 238 239 if (sparse_write(fd, l1tbl, clstrsz * clstr_l1tblsz) < 0) { 240 error = errno; 241 goto out; 242 } 243 244 clstr_rcblks = 0; 245 do { 246 n = clstr_rcblks; 247 clstr_rcblks = round_clstr((nclstrs + n) * 2) >> clstr_log2sz; 248 } while (n < clstr_rcblks); 249 250 if (rcclno > 0) { 251 rctbl = calloc(1, clstrsz * clstr_rctblsz); 252 if (rctbl == NULL) { 253 error = ENOMEM; 254 goto out; 255 } 256 for (n = 0; n < clstr_rcblks; n++) { 257 be64enc(rctbl + n, ofs); 258 ofs += clstrsz; 259 nclstrs++; 260 } 261 if (sparse_write(fd, rctbl, clstrsz * clstr_rctblsz) < 0) { 262 error = errno; 263 goto out; 264 } 265 free(rctbl); 266 rctbl = NULL; 267 } 268 269 l2tbl = malloc(clstrsz); 270 if (l2tbl == NULL) { 271 error = ENOMEM; 272 goto out; 273 } 274 275 for (l1idx = 0; l1idx < clstr_l2tbls; l1idx++) { 276 if (l1tbl[l1idx] == 0) 277 continue; 278 memset(l2tbl, 0, clstrsz); 279 blkofs = (lba_t)l1idx * blk_clstrsz * (clstrsz >> 3); 280 for (l2idx = 0; l2idx < (clstrsz >> 3); l2idx++) { 281 blk = blkofs + (lba_t)l2idx * blk_clstrsz; 282 if (blk >= blk_imgsz) 283 break; 284 if (image_data(blk, blk_clstrsz)) { 285 be64enc(l2tbl + l2idx, ofs + ofsflags); 286 ofs += clstrsz; 287 } 288 } 289 if (sparse_write(fd, l2tbl, clstrsz) < 0) { 290 error = errno; 291 goto out; 292 } 293 } 294 295 free(l2tbl); 296 l2tbl = NULL; 297 free(l1tbl); 298 l1tbl = NULL; 299 300 if (rcclno > 0) { 301 rcblk = calloc(1, clstrsz * clstr_rcblks); 302 if (rcblk == NULL) { 303 error = ENOMEM; 304 goto out; 305 } 306 for (n = 0; n < nclstrs; n++) 307 be16enc(rcblk + n, 1); 308 if (sparse_write(fd, rcblk, clstrsz * clstr_rcblks) < 0) { 309 error = errno; 310 goto out; 311 } 312 free(rcblk); 313 rcblk = NULL; 314 } 315 316 error = 0; 317 for (n = 0; n < clstr_imgsz; n++) { 318 blk = n * blk_clstrsz; 319 if (image_data(blk, blk_clstrsz)) { 320 error = image_copyout_region(fd, blk, blk_clstrsz); 321 if (error) 322 break; 323 } 324 } 325 if (!error) 326 error = image_copyout_done(fd); 327 328 out: 329 if (rcblk != NULL) 330 free(rcblk); 331 if (l2tbl != NULL) 332 free(l2tbl); 333 if (rctbl != NULL) 334 free(rctbl); 335 if (l1tbl != NULL) 336 free(l1tbl); 337 if (hdr != NULL) 338 free(hdr); 339 return (error); 340 } 341 342 static int 343 qcow1_write(int fd) 344 { 345 346 return (qcow_write(fd, QCOW_VERSION_1)); 347 } 348 349 static int 350 qcow2_write(int fd) 351 { 352 353 return (qcow_write(fd, QCOW_VERSION_2)); 354 } 355 356 static struct mkimg_format qcow1_format = { 357 .name = "qcow", 358 .description = "QEMU Copy-On-Write, version 1", 359 .resize = qcow1_resize, 360 .write = qcow1_write, 361 }; 362 FORMAT_DEFINE(qcow1_format); 363 364 static struct mkimg_format qcow2_format = { 365 .name = "qcow2", 366 .description = "QEMU Copy-On-Write, version 2", 367 .resize = qcow2_resize, 368 .write = qcow2_write, 369 }; 370 FORMAT_DEFINE(qcow2_format); 371