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/endian.h> 32 #include <sys/errno.h> 33 #include <stdint.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <unistd.h> 38 39 #include "image.h" 40 #include "format.h" 41 #include "mkimg.h" 42 43 #undef QCOW_SUPPORT_QCOW2 44 45 /* Default cluster sizes. */ 46 #define QCOW1_CLSTR_LOG2SZ 12 /* 4KB */ 47 #define QCOW2_CLSTR_LOG2SZ 16 /* 64KB */ 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_entries; 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 clstrsz, 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 return (EDOOFUS); 104 } 105 106 clstrsz = 1UL << clstr_log2sz; 107 imagesz = round_clstr(imgsz * secsz); 108 109 if (verbose) 110 fprintf(stderr, "QCOW: image size = %ju, cluster size = %ju\n", 111 (uintmax_t)imagesz, (uintmax_t)clstrsz); 112 113 return (image_set_size(imagesz / secsz)); 114 } 115 116 static int 117 qcow1_resize(lba_t imgsz) 118 { 119 120 return (qcow_resize(imgsz, QCOW_VERSION_1)); 121 } 122 123 #ifdef QCOW_SUPPORT_QCOW2 124 static int 125 qcow2_resize(lba_t imgsz) 126 { 127 128 return (qcow_resize(imgsz, QCOW_VERSION_2)); 129 } 130 #endif 131 132 static int 133 qcow_write(int fd, u_int version) 134 { 135 struct qcow_header *hdr; 136 uint64_t *l1tbl, *l2tbl; 137 uint16_t *rctbl; 138 uint64_t n, clstrsz, imagesz, nclstrs; 139 uint64_t l1ofs, l2ofs, ofs, rcofs; 140 lba_t blk, blkofs, blkcnt, imgsz; 141 u_int l1idx, l2idx, l2clstrs; 142 int error; 143 144 if (clstr_log2sz == 0) 145 return (EDOOFUS); 146 147 clstrsz = 1UL << clstr_log2sz; 148 blkcnt = clstrsz / secsz; 149 imgsz = image_get_size(); 150 imagesz = imgsz * secsz; 151 nclstrs = imagesz >> clstr_log2sz; 152 l2clstrs = (nclstrs * 8 + clstrsz - 1) > clstr_log2sz; 153 154 l1ofs = clstrsz; 155 rcofs = round_clstr(l1ofs + l2clstrs * 8); 156 157 hdr = calloc(1, clstrsz); 158 if (hdr == NULL) 159 return (errno); 160 161 be32enc(&hdr->magic, QCOW_MAGIC); 162 be32enc(&hdr->version, version); 163 be64enc(&hdr->disk_size, imagesz); 164 switch (version) { 165 case QCOW_VERSION_1: 166 l2ofs = rcofs; /* No reference counting. */ 167 hdr->u.v1.clstr_log2sz = clstr_log2sz; 168 hdr->u.v1.l2_log2sz = clstr_log2sz - 3; 169 be64enc(&hdr->u.v1.l1_offset, l1ofs); 170 break; 171 case QCOW_VERSION_2: 172 l2ofs = round_clstr(rcofs + (nclstrs + l2clstrs) * 2); 173 be32enc(&hdr->clstr_log2sz, clstr_log2sz); 174 be32enc(&hdr->u.v2.l1_entries, l2clstrs); 175 be64enc(&hdr->u.v2.l1_offset, l1ofs); 176 be64enc(&hdr->u.v2.refcnt_offset, rcofs); 177 be32enc(&hdr->u.v2.refcnt_entries, l2clstrs); 178 break; 179 default: 180 return (EDOOFUS); 181 } 182 183 l2tbl = l1tbl = NULL; 184 rctbl = NULL; 185 186 l1tbl = calloc(1, (size_t)(rcofs - l1ofs)); 187 if (l1tbl == NULL) { 188 error = ENOMEM; 189 goto out; 190 } 191 if (l2ofs != rcofs) { 192 rctbl = calloc(1, (size_t)(l2ofs - rcofs)); 193 if (rctbl == NULL) { 194 error = ENOMEM; 195 goto out; 196 } 197 } 198 199 ofs = l2ofs; 200 for (n = 0; n < nclstrs; n++) { 201 l1idx = n >> (clstr_log2sz - 3); 202 if (l1tbl[l1idx] != 0UL) 203 continue; 204 blk = n * blkcnt; 205 if (image_data(blk, blkcnt)) { 206 be64enc(l1tbl + l1idx, ofs); 207 ofs += clstrsz; 208 } 209 } 210 211 error = 0; 212 if (!error && sparse_write(fd, hdr, clstrsz) < 0) 213 error = errno; 214 if (!error && sparse_write(fd, l1tbl, (size_t)(rcofs - l1ofs)) < 0) 215 error = errno; 216 /* XXX refcnt table. */ 217 if (error) 218 goto out; 219 220 free(hdr); 221 hdr = NULL; 222 if (rctbl != NULL) { 223 free(rctbl); 224 rctbl = NULL; 225 } 226 227 l2tbl = malloc(clstrsz); 228 if (l2tbl == NULL) { 229 error = ENOMEM; 230 goto out; 231 } 232 233 for (l1idx = 0; l1idx < l2clstrs; l1idx++) { 234 if (l1tbl[l1idx] == 0) 235 continue; 236 memset(l2tbl, 0, clstrsz); 237 blkofs = (lba_t)l1idx * (clstrsz * (clstrsz >> 3)); 238 for (l2idx = 0; l2idx < (clstrsz >> 3); l2idx++) { 239 blk = blkofs + (lba_t)l2idx * blkcnt; 240 if (blk >= imgsz) 241 break; 242 if (image_data(blk, blkcnt)) { 243 be64enc(l2tbl + l2idx, ofs); 244 ofs += clstrsz; 245 } 246 } 247 if (sparse_write(fd, l2tbl, clstrsz) < 0) { 248 error = errno; 249 goto out; 250 } 251 } 252 253 free(l2tbl); 254 l2tbl = NULL; 255 free(l1tbl); 256 l1tbl = NULL; 257 258 error = 0; 259 for (n = 0; n < nclstrs; n++) { 260 blk = n * blkcnt; 261 if (image_data(blk, blkcnt)) { 262 error = image_copyout_region(fd, blk, blkcnt); 263 if (error) 264 break; 265 } 266 } 267 if (!error) 268 error = image_copyout_done(fd); 269 270 out: 271 if (l2tbl != NULL) 272 free(l2tbl); 273 if (rctbl != NULL) 274 free(rctbl); 275 if (l1tbl != NULL) 276 free(l1tbl); 277 if (hdr != NULL) 278 free(hdr); 279 return (error); 280 } 281 282 static int 283 qcow1_write(int fd) 284 { 285 286 return (qcow_write(fd, QCOW_VERSION_1)); 287 } 288 289 #ifdef QCOW_SUPPORT_QCOW2 290 static int 291 qcow2_write(int fd) 292 { 293 294 return (qcow_write(fd, QCOW_VERSION_2)); 295 } 296 #endif 297 298 static struct mkimg_format qcow1_format = { 299 .name = "qcow", 300 .description = "QEMU Copy-On-Write, version 1", 301 .resize = qcow1_resize, 302 .write = qcow1_write, 303 }; 304 FORMAT_DEFINE(qcow1_format); 305 306 #ifdef QCOW_SUPPORT_QCOW2 307 static struct mkimg_format qcow2_format = { 308 .name = "qcow2", 309 .description = "QEMU Copy-On-Write, version 2", 310 .resize = qcow2_resize, 311 .write = qcow2_write, 312 }; 313 FORMAT_DEFINE(qcow2_format); 314 #endif 315