1 /* 2 * Block driver for the QCOW version 2 format 3 * 4 * Copyright (c) 2004-2006 Fabrice Bellard 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 * THE SOFTWARE. 23 */ 24 25 #include "qemu-common.h" 26 #include "block_int.h" 27 #include "block/qcow2.h" 28 29 typedef struct QEMU_PACKED QCowSnapshotHeader { 30 /* header is 8 byte aligned */ 31 uint64_t l1_table_offset; 32 33 uint32_t l1_size; 34 uint16_t id_str_size; 35 uint16_t name_size; 36 37 uint32_t date_sec; 38 uint32_t date_nsec; 39 40 uint64_t vm_clock_nsec; 41 42 uint32_t vm_state_size; 43 uint32_t extra_data_size; /* for extension */ 44 /* extra data follows */ 45 /* id_str follows */ 46 /* name follows */ 47 } QCowSnapshotHeader; 48 49 void qcow2_free_snapshots(BlockDriverState *bs) 50 { 51 BDRVQcowState *s = bs->opaque; 52 int i; 53 54 for(i = 0; i < s->nb_snapshots; i++) { 55 g_free(s->snapshots[i].name); 56 g_free(s->snapshots[i].id_str); 57 } 58 g_free(s->snapshots); 59 s->snapshots = NULL; 60 s->nb_snapshots = 0; 61 } 62 63 int qcow2_read_snapshots(BlockDriverState *bs) 64 { 65 BDRVQcowState *s = bs->opaque; 66 QCowSnapshotHeader h; 67 QCowSnapshot *sn; 68 int i, id_str_size, name_size; 69 int64_t offset; 70 uint32_t extra_data_size; 71 72 if (!s->nb_snapshots) { 73 s->snapshots = NULL; 74 s->snapshots_size = 0; 75 return 0; 76 } 77 78 offset = s->snapshots_offset; 79 s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot)); 80 for(i = 0; i < s->nb_snapshots; i++) { 81 offset = align_offset(offset, 8); 82 if (bdrv_pread(bs->file, offset, &h, sizeof(h)) != sizeof(h)) 83 goto fail; 84 offset += sizeof(h); 85 sn = s->snapshots + i; 86 sn->l1_table_offset = be64_to_cpu(h.l1_table_offset); 87 sn->l1_size = be32_to_cpu(h.l1_size); 88 sn->vm_state_size = be32_to_cpu(h.vm_state_size); 89 sn->date_sec = be32_to_cpu(h.date_sec); 90 sn->date_nsec = be32_to_cpu(h.date_nsec); 91 sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec); 92 extra_data_size = be32_to_cpu(h.extra_data_size); 93 94 id_str_size = be16_to_cpu(h.id_str_size); 95 name_size = be16_to_cpu(h.name_size); 96 97 offset += extra_data_size; 98 99 sn->id_str = g_malloc(id_str_size + 1); 100 if (bdrv_pread(bs->file, offset, sn->id_str, id_str_size) != id_str_size) 101 goto fail; 102 offset += id_str_size; 103 sn->id_str[id_str_size] = '\0'; 104 105 sn->name = g_malloc(name_size + 1); 106 if (bdrv_pread(bs->file, offset, sn->name, name_size) != name_size) 107 goto fail; 108 offset += name_size; 109 sn->name[name_size] = '\0'; 110 } 111 s->snapshots_size = offset - s->snapshots_offset; 112 return 0; 113 fail: 114 qcow2_free_snapshots(bs); 115 return -1; 116 } 117 118 /* add at the end of the file a new list of snapshots */ 119 static int qcow2_write_snapshots(BlockDriverState *bs) 120 { 121 BDRVQcowState *s = bs->opaque; 122 QCowSnapshot *sn; 123 QCowSnapshotHeader h; 124 int i, name_size, id_str_size, snapshots_size; 125 uint64_t data64; 126 uint32_t data32; 127 int64_t offset, snapshots_offset; 128 129 /* compute the size of the snapshots */ 130 offset = 0; 131 for(i = 0; i < s->nb_snapshots; i++) { 132 sn = s->snapshots + i; 133 offset = align_offset(offset, 8); 134 offset += sizeof(h); 135 offset += strlen(sn->id_str); 136 offset += strlen(sn->name); 137 } 138 snapshots_size = offset; 139 140 snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size); 141 bdrv_flush(bs->file); 142 offset = snapshots_offset; 143 if (offset < 0) { 144 return offset; 145 } 146 147 for(i = 0; i < s->nb_snapshots; i++) { 148 sn = s->snapshots + i; 149 memset(&h, 0, sizeof(h)); 150 h.l1_table_offset = cpu_to_be64(sn->l1_table_offset); 151 h.l1_size = cpu_to_be32(sn->l1_size); 152 h.vm_state_size = cpu_to_be32(sn->vm_state_size); 153 h.date_sec = cpu_to_be32(sn->date_sec); 154 h.date_nsec = cpu_to_be32(sn->date_nsec); 155 h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec); 156 157 id_str_size = strlen(sn->id_str); 158 name_size = strlen(sn->name); 159 h.id_str_size = cpu_to_be16(id_str_size); 160 h.name_size = cpu_to_be16(name_size); 161 offset = align_offset(offset, 8); 162 if (bdrv_pwrite_sync(bs->file, offset, &h, sizeof(h)) < 0) 163 goto fail; 164 offset += sizeof(h); 165 if (bdrv_pwrite_sync(bs->file, offset, sn->id_str, id_str_size) < 0) 166 goto fail; 167 offset += id_str_size; 168 if (bdrv_pwrite_sync(bs->file, offset, sn->name, name_size) < 0) 169 goto fail; 170 offset += name_size; 171 } 172 173 /* update the various header fields */ 174 data64 = cpu_to_be64(snapshots_offset); 175 if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, snapshots_offset), 176 &data64, sizeof(data64)) < 0) 177 goto fail; 178 data32 = cpu_to_be32(s->nb_snapshots); 179 if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots), 180 &data32, sizeof(data32)) < 0) 181 goto fail; 182 183 /* free the old snapshot table */ 184 qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size); 185 s->snapshots_offset = snapshots_offset; 186 s->snapshots_size = snapshots_size; 187 return 0; 188 fail: 189 return -1; 190 } 191 192 static void find_new_snapshot_id(BlockDriverState *bs, 193 char *id_str, int id_str_size) 194 { 195 BDRVQcowState *s = bs->opaque; 196 QCowSnapshot *sn; 197 int i, id, id_max = 0; 198 199 for(i = 0; i < s->nb_snapshots; i++) { 200 sn = s->snapshots + i; 201 id = strtoul(sn->id_str, NULL, 10); 202 if (id > id_max) 203 id_max = id; 204 } 205 snprintf(id_str, id_str_size, "%d", id_max + 1); 206 } 207 208 static int find_snapshot_by_id(BlockDriverState *bs, const char *id_str) 209 { 210 BDRVQcowState *s = bs->opaque; 211 int i; 212 213 for(i = 0; i < s->nb_snapshots; i++) { 214 if (!strcmp(s->snapshots[i].id_str, id_str)) 215 return i; 216 } 217 return -1; 218 } 219 220 static int find_snapshot_by_id_or_name(BlockDriverState *bs, const char *name) 221 { 222 BDRVQcowState *s = bs->opaque; 223 int i, ret; 224 225 ret = find_snapshot_by_id(bs, name); 226 if (ret >= 0) 227 return ret; 228 for(i = 0; i < s->nb_snapshots; i++) { 229 if (!strcmp(s->snapshots[i].name, name)) 230 return i; 231 } 232 return -1; 233 } 234 235 /* if no id is provided, a new one is constructed */ 236 int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) 237 { 238 BDRVQcowState *s = bs->opaque; 239 QCowSnapshot *snapshots1, sn1, *sn = &sn1; 240 int i, ret; 241 uint64_t *l1_table = NULL; 242 int64_t l1_table_offset; 243 244 memset(sn, 0, sizeof(*sn)); 245 246 if (sn_info->id_str[0] == '\0') { 247 /* compute a new id */ 248 find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str)); 249 } 250 251 /* check that the ID is unique */ 252 if (find_snapshot_by_id(bs, sn_info->id_str) >= 0) 253 return -ENOENT; 254 255 sn->id_str = g_strdup(sn_info->id_str); 256 if (!sn->id_str) 257 goto fail; 258 sn->name = g_strdup(sn_info->name); 259 if (!sn->name) 260 goto fail; 261 sn->vm_state_size = sn_info->vm_state_size; 262 sn->date_sec = sn_info->date_sec; 263 sn->date_nsec = sn_info->date_nsec; 264 sn->vm_clock_nsec = sn_info->vm_clock_nsec; 265 266 ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1); 267 if (ret < 0) 268 goto fail; 269 270 /* create the L1 table of the snapshot */ 271 l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t)); 272 if (l1_table_offset < 0) { 273 goto fail; 274 } 275 bdrv_flush(bs->file); 276 277 sn->l1_table_offset = l1_table_offset; 278 sn->l1_size = s->l1_size; 279 280 if (s->l1_size != 0) { 281 l1_table = g_malloc(s->l1_size * sizeof(uint64_t)); 282 } else { 283 l1_table = NULL; 284 } 285 286 for(i = 0; i < s->l1_size; i++) { 287 l1_table[i] = cpu_to_be64(s->l1_table[i]); 288 } 289 if (bdrv_pwrite_sync(bs->file, sn->l1_table_offset, 290 l1_table, s->l1_size * sizeof(uint64_t)) < 0) 291 goto fail; 292 g_free(l1_table); 293 l1_table = NULL; 294 295 snapshots1 = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot)); 296 if (s->snapshots) { 297 memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot)); 298 g_free(s->snapshots); 299 } 300 s->snapshots = snapshots1; 301 s->snapshots[s->nb_snapshots++] = *sn; 302 303 if (qcow2_write_snapshots(bs) < 0) 304 goto fail; 305 #ifdef DEBUG_ALLOC 306 { 307 BdrvCheckResult result = {0}; 308 qcow2_check_refcounts(bs, &result); 309 } 310 #endif 311 return 0; 312 fail: 313 g_free(sn->name); 314 g_free(l1_table); 315 return -1; 316 } 317 318 /* copy the snapshot 'snapshot_name' into the current disk image */ 319 int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) 320 { 321 BDRVQcowState *s = bs->opaque; 322 QCowSnapshot *sn; 323 int i, snapshot_index; 324 int cur_l1_bytes, sn_l1_bytes; 325 326 snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); 327 if (snapshot_index < 0) 328 return -ENOENT; 329 sn = &s->snapshots[snapshot_index]; 330 331 if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1) < 0) 332 goto fail; 333 334 if (qcow2_grow_l1_table(bs, sn->l1_size, true) < 0) 335 goto fail; 336 337 cur_l1_bytes = s->l1_size * sizeof(uint64_t); 338 sn_l1_bytes = sn->l1_size * sizeof(uint64_t); 339 340 if (cur_l1_bytes > sn_l1_bytes) { 341 memset(s->l1_table + sn->l1_size, 0, cur_l1_bytes - sn_l1_bytes); 342 } 343 344 /* copy the snapshot l1 table to the current l1 table */ 345 if (bdrv_pread(bs->file, sn->l1_table_offset, 346 s->l1_table, sn_l1_bytes) < 0) 347 goto fail; 348 if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, 349 s->l1_table, cur_l1_bytes) < 0) 350 goto fail; 351 for(i = 0;i < s->l1_size; i++) { 352 be64_to_cpus(&s->l1_table[i]); 353 } 354 355 if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1) < 0) 356 goto fail; 357 358 #ifdef DEBUG_ALLOC 359 { 360 BdrvCheckResult result = {0}; 361 qcow2_check_refcounts(bs, &result); 362 } 363 #endif 364 return 0; 365 fail: 366 return -EIO; 367 } 368 369 int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 370 { 371 BDRVQcowState *s = bs->opaque; 372 QCowSnapshot *sn; 373 int snapshot_index, ret; 374 375 snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); 376 if (snapshot_index < 0) 377 return -ENOENT; 378 sn = &s->snapshots[snapshot_index]; 379 380 ret = qcow2_update_snapshot_refcount(bs, sn->l1_table_offset, sn->l1_size, -1); 381 if (ret < 0) 382 return ret; 383 /* must update the copied flag on the current cluster offsets */ 384 ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0); 385 if (ret < 0) 386 return ret; 387 qcow2_free_clusters(bs, sn->l1_table_offset, sn->l1_size * sizeof(uint64_t)); 388 389 g_free(sn->id_str); 390 g_free(sn->name); 391 memmove(sn, sn + 1, (s->nb_snapshots - snapshot_index - 1) * sizeof(*sn)); 392 s->nb_snapshots--; 393 ret = qcow2_write_snapshots(bs); 394 if (ret < 0) { 395 /* XXX: restore snapshot if error ? */ 396 return ret; 397 } 398 #ifdef DEBUG_ALLOC 399 { 400 BdrvCheckResult result = {0}; 401 qcow2_check_refcounts(bs, &result); 402 } 403 #endif 404 return 0; 405 } 406 407 int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) 408 { 409 BDRVQcowState *s = bs->opaque; 410 QEMUSnapshotInfo *sn_tab, *sn_info; 411 QCowSnapshot *sn; 412 int i; 413 414 if (!s->nb_snapshots) { 415 *psn_tab = NULL; 416 return s->nb_snapshots; 417 } 418 419 sn_tab = g_malloc0(s->nb_snapshots * sizeof(QEMUSnapshotInfo)); 420 for(i = 0; i < s->nb_snapshots; i++) { 421 sn_info = sn_tab + i; 422 sn = s->snapshots + i; 423 pstrcpy(sn_info->id_str, sizeof(sn_info->id_str), 424 sn->id_str); 425 pstrcpy(sn_info->name, sizeof(sn_info->name), 426 sn->name); 427 sn_info->vm_state_size = sn->vm_state_size; 428 sn_info->date_sec = sn->date_sec; 429 sn_info->date_nsec = sn->date_nsec; 430 sn_info->vm_clock_nsec = sn->vm_clock_nsec; 431 } 432 *psn_tab = sn_tab; 433 return s->nb_snapshots; 434 } 435 436 int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name) 437 { 438 int i, snapshot_index, l1_size2; 439 BDRVQcowState *s = bs->opaque; 440 QCowSnapshot *sn; 441 442 snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_name); 443 if (snapshot_index < 0) { 444 return -ENOENT; 445 } 446 447 sn = &s->snapshots[snapshot_index]; 448 s->l1_size = sn->l1_size; 449 l1_size2 = s->l1_size * sizeof(uint64_t); 450 if (s->l1_table != NULL) { 451 g_free(s->l1_table); 452 } 453 454 s->l1_table_offset = sn->l1_table_offset; 455 s->l1_table = g_malloc0(align_offset(l1_size2, 512)); 456 457 if (bdrv_pread(bs->file, sn->l1_table_offset, 458 s->l1_table, l1_size2) != l1_size2) { 459 return -1; 460 } 461 462 for(i = 0;i < s->l1_size; i++) { 463 be64_to_cpus(&s->l1_table[i]); 464 } 465 return 0; 466 } 467