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/errno.h> 31 #include <assert.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 #include "endian.h" 37 #include "image.h" 38 #include "format.h" 39 #include "mkimg.h" 40 41 /* Default cluster sizes. */ 42 #define QCOW1_CLSTR_LOG2SZ 12 /* 4KB */ 43 #define QCOW2_CLSTR_LOG2SZ 16 /* 64KB */ 44 45 /* Flag bits in cluster offsets */ 46 #define QCOW_CLSTR_COMPRESSED (1ULL << 62) 47 #define QCOW_CLSTR_COPIED (1ULL << 63) 48 49 struct qcow_header { 50 uint32_t magic; 51 #define QCOW_MAGIC 0x514649fb 52 uint32_t version; 53 #define QCOW_VERSION_1 1 54 #define QCOW_VERSION_2 2 55 uint64_t path_offset; 56 uint32_t path_length; 57 uint32_t clstr_log2sz; /* v2 only */ 58 uint64_t disk_size; 59 union { 60 struct { 61 uint8_t clstr_log2sz; 62 uint8_t l2_log2sz; 63 uint16_t _pad; 64 uint32_t encryption; 65 uint64_t l1_offset; 66 } v1; 67 struct { 68 uint32_t encryption; 69 uint32_t l1_entries; 70 uint64_t l1_offset; 71 uint64_t refcnt_offset; 72 uint32_t refcnt_clstrs; 73 uint32_t snapshot_count; 74 uint64_t snapshot_offset; 75 } v2; 76 } u; 77 }; 78 79 static u_int clstr_log2sz; 80 81 static uint64_t 82 round_clstr(uint64_t ofs) 83 { 84 uint64_t clstrsz; 85 86 clstrsz = 1UL << clstr_log2sz; 87 return ((ofs + clstrsz - 1) & ~(clstrsz - 1)); 88 } 89 90 static int 91 qcow_resize(lba_t imgsz, u_int version) 92 { 93 uint64_t imagesz; 94 95 switch (version) { 96 case QCOW_VERSION_1: 97 clstr_log2sz = QCOW1_CLSTR_LOG2SZ; 98 break; 99 case QCOW_VERSION_2: 100 clstr_log2sz = QCOW2_CLSTR_LOG2SZ; 101 break; 102 default: 103 assert(0); 104 } 105 106 imagesz = round_clstr(imgsz * secsz); 107 108 if (verbose) 109 fprintf(stderr, "QCOW: image size = %ju, cluster size = %u\n", 110 (uintmax_t)imagesz, (u_int)(1U << clstr_log2sz)); 111 112 return (image_set_size(imagesz / secsz)); 113 } 114 115 static int 116 qcow1_resize(lba_t imgsz) 117 { 118 119 return (qcow_resize(imgsz, QCOW_VERSION_1)); 120 } 121 122 static int 123 qcow2_resize(lba_t imgsz) 124 { 125 126 return (qcow_resize(imgsz, QCOW_VERSION_2)); 127 } 128 129 static int 130 qcow_write(int fd, u_int version) 131 { 132 struct qcow_header *hdr; 133 uint64_t *l1tbl, *l2tbl, *rctbl; 134 uint16_t *rcblk; 135 uint64_t clstr_imgsz, clstr_l2tbls, clstr_l1tblsz; 136 uint64_t clstr_rcblks, clstr_rctblsz; 137 uint64_t n, imagesz, nclstrs, ofs, ofsflags; 138 lba_t blk, blkofs, blk_imgsz; 139 u_int l1clno, l2clno, rcclno; 140 u_int blk_clstrsz, refcnt_clstrs; 141 u_int clstrsz, l1idx, l2idx; 142 int error; 143 144 assert(clstr_log2sz != 0); 145 146 clstrsz = 1U << clstr_log2sz; 147 blk_clstrsz = clstrsz / secsz; 148 blk_imgsz = image_get_size(); 149 imagesz = blk_imgsz * secsz; 150 clstr_imgsz = imagesz >> clstr_log2sz; 151 clstr_l2tbls = round_clstr(clstr_imgsz * 8) >> clstr_log2sz; 152 clstr_l1tblsz = round_clstr(clstr_l2tbls * 8) >> clstr_log2sz; 153 nclstrs = clstr_imgsz + clstr_l2tbls + clstr_l1tblsz + 1; 154 clstr_rcblks = clstr_rctblsz = 0; 155 do { 156 n = clstr_rcblks + clstr_rctblsz; 157 clstr_rcblks = round_clstr((nclstrs + n) * 2) >> clstr_log2sz; 158 clstr_rctblsz = round_clstr(clstr_rcblks * 8) >> clstr_log2sz; 159 } while (n < (clstr_rcblks + clstr_rctblsz)); 160 161 /* 162 * We got all the sizes in clusters. Start the layout. 163 * 0 - header 164 * 1 - L1 table 165 * 2 - RC table (v2 only) 166 * 3 - L2 tables 167 * 4 - RC block (v2 only) 168 * 5 - data 169 */ 170 171 l1clno = 1; 172 rcclno = 0; 173 rctbl = l2tbl = l1tbl = NULL; 174 rcblk = NULL; 175 176 hdr = calloc(1, clstrsz); 177 if (hdr == NULL) 178 return (errno); 179 180 be32enc(&hdr->magic, QCOW_MAGIC); 181 be32enc(&hdr->version, version); 182 be64enc(&hdr->disk_size, imagesz); 183 switch (version) { 184 case QCOW_VERSION_1: 185 ofsflags = 0; 186 l2clno = l1clno + clstr_l1tblsz; 187 hdr->u.v1.clstr_log2sz = clstr_log2sz; 188 hdr->u.v1.l2_log2sz = clstr_log2sz - 3; 189 be64enc(&hdr->u.v1.l1_offset, clstrsz * l1clno); 190 break; 191 case QCOW_VERSION_2: 192 ofsflags = QCOW_CLSTR_COPIED; 193 rcclno = l1clno + clstr_l1tblsz; 194 l2clno = rcclno + clstr_rctblsz; 195 be32enc(&hdr->clstr_log2sz, clstr_log2sz); 196 be32enc(&hdr->u.v2.l1_entries, clstr_l2tbls); 197 be64enc(&hdr->u.v2.l1_offset, clstrsz * l1clno); 198 be64enc(&hdr->u.v2.refcnt_offset, clstrsz * rcclno); 199 refcnt_clstrs = round_clstr(clstr_rcblks * 8) >> clstr_log2sz; 200 be32enc(&hdr->u.v2.refcnt_clstrs, refcnt_clstrs); 201 break; 202 default: 203 assert(0); 204 } 205 206 if (sparse_write(fd, hdr, clstrsz) < 0) { 207 error = errno; 208 goto out; 209 } 210 211 free(hdr); 212 hdr = NULL; 213 214 ofs = clstrsz * l2clno; 215 nclstrs = 1 + clstr_l1tblsz + clstr_rctblsz; 216 217 l1tbl = calloc(clstr_l1tblsz, clstrsz); 218 if (l1tbl == NULL) { 219 error = ENOMEM; 220 goto out; 221 } 222 223 for (n = 0; n < clstr_imgsz; n++) { 224 blk = n * blk_clstrsz; 225 if (image_data(blk, blk_clstrsz)) { 226 nclstrs++; 227 l1idx = n >> (clstr_log2sz - 3); 228 if (l1tbl[l1idx] == 0) { 229 be64enc(l1tbl + l1idx, ofs + ofsflags); 230 ofs += clstrsz; 231 nclstrs++; 232 } 233 } 234 } 235 236 if (sparse_write(fd, l1tbl, clstrsz * clstr_l1tblsz) < 0) { 237 error = errno; 238 goto out; 239 } 240 241 clstr_rcblks = 0; 242 do { 243 n = clstr_rcblks; 244 clstr_rcblks = round_clstr((nclstrs + n) * 2) >> clstr_log2sz; 245 } while (n < clstr_rcblks); 246 247 if (rcclno > 0) { 248 rctbl = calloc(clstr_rctblsz, clstrsz); 249 if (rctbl == NULL) { 250 error = ENOMEM; 251 goto out; 252 } 253 for (n = 0; n < clstr_rcblks; n++) { 254 be64enc(rctbl + n, ofs); 255 ofs += clstrsz; 256 nclstrs++; 257 } 258 if (sparse_write(fd, rctbl, clstrsz * clstr_rctblsz) < 0) { 259 error = errno; 260 goto out; 261 } 262 free(rctbl); 263 rctbl = NULL; 264 } 265 266 l2tbl = malloc(clstrsz); 267 if (l2tbl == NULL) { 268 error = ENOMEM; 269 goto out; 270 } 271 272 for (l1idx = 0; l1idx < clstr_l2tbls; l1idx++) { 273 if (l1tbl[l1idx] == 0) 274 continue; 275 memset(l2tbl, 0, clstrsz); 276 blkofs = (lba_t)l1idx * blk_clstrsz * (clstrsz >> 3); 277 for (l2idx = 0; l2idx < (clstrsz >> 3); l2idx++) { 278 blk = blkofs + (lba_t)l2idx * blk_clstrsz; 279 if (blk >= blk_imgsz) 280 break; 281 if (image_data(blk, blk_clstrsz)) { 282 be64enc(l2tbl + l2idx, ofs + ofsflags); 283 ofs += clstrsz; 284 } 285 } 286 if (sparse_write(fd, l2tbl, clstrsz) < 0) { 287 error = errno; 288 goto out; 289 } 290 } 291 292 free(l2tbl); 293 l2tbl = NULL; 294 free(l1tbl); 295 l1tbl = NULL; 296 297 if (rcclno > 0) { 298 rcblk = calloc(clstr_rcblks, clstrsz); 299 if (rcblk == NULL) { 300 error = ENOMEM; 301 goto out; 302 } 303 for (n = 0; n < nclstrs; n++) 304 be16enc(rcblk + n, 1); 305 if (sparse_write(fd, rcblk, clstrsz * clstr_rcblks) < 0) { 306 error = errno; 307 goto out; 308 } 309 free(rcblk); 310 rcblk = NULL; 311 } 312 313 error = 0; 314 for (n = 0; n < clstr_imgsz; n++) { 315 blk = n * blk_clstrsz; 316 if (image_data(blk, blk_clstrsz)) { 317 error = image_copyout_region(fd, blk, blk_clstrsz); 318 if (error) 319 break; 320 } 321 } 322 if (!error) 323 error = image_copyout_done(fd); 324 325 out: 326 if (rcblk != NULL) 327 free(rcblk); 328 if (l2tbl != NULL) 329 free(l2tbl); 330 if (rctbl != NULL) 331 free(rctbl); 332 if (l1tbl != NULL) 333 free(l1tbl); 334 if (hdr != NULL) 335 free(hdr); 336 return (error); 337 } 338 339 static int 340 qcow1_write(int fd) 341 { 342 343 return (qcow_write(fd, QCOW_VERSION_1)); 344 } 345 346 static int 347 qcow2_write(int fd) 348 { 349 350 return (qcow_write(fd, QCOW_VERSION_2)); 351 } 352 353 static struct mkimg_format qcow1_format = { 354 .name = "qcow", 355 .description = "QEMU Copy-On-Write, version 1", 356 .resize = qcow1_resize, 357 .write = qcow1_write, 358 }; 359 FORMAT_DEFINE(qcow1_format); 360 361 static struct mkimg_format qcow2_format = { 362 .name = "qcow2", 363 .description = "QEMU Copy-On-Write, version 2", 364 .resize = qcow2_resize, 365 .write = qcow2_write, 366 }; 367 FORMAT_DEFINE(qcow2_format); 368