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 __attribute__((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 qemu_free(s->snapshots[i].name); 56 qemu_free(s->snapshots[i].id_str); 57 } 58 qemu_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 = qemu_mallocz(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 = qemu_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 = qemu_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 qcow_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 offset = snapshots_offset; 142 if (offset < 0) { 143 return offset; 144 } 145 146 for(i = 0; i < s->nb_snapshots; i++) { 147 sn = s->snapshots + i; 148 memset(&h, 0, sizeof(h)); 149 h.l1_table_offset = cpu_to_be64(sn->l1_table_offset); 150 h.l1_size = cpu_to_be32(sn->l1_size); 151 h.vm_state_size = cpu_to_be32(sn->vm_state_size); 152 h.date_sec = cpu_to_be32(sn->date_sec); 153 h.date_nsec = cpu_to_be32(sn->date_nsec); 154 h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec); 155 156 id_str_size = strlen(sn->id_str); 157 name_size = strlen(sn->name); 158 h.id_str_size = cpu_to_be16(id_str_size); 159 h.name_size = cpu_to_be16(name_size); 160 offset = align_offset(offset, 8); 161 if (bdrv_pwrite(bs->file, offset, &h, sizeof(h)) != sizeof(h)) 162 goto fail; 163 offset += sizeof(h); 164 if (bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size) != id_str_size) 165 goto fail; 166 offset += id_str_size; 167 if (bdrv_pwrite(bs->file, offset, sn->name, name_size) != name_size) 168 goto fail; 169 offset += name_size; 170 } 171 172 /* update the various header fields */ 173 data64 = cpu_to_be64(snapshots_offset); 174 if (bdrv_pwrite(bs->file, offsetof(QCowHeader, snapshots_offset), 175 &data64, sizeof(data64)) != sizeof(data64)) 176 goto fail; 177 data32 = cpu_to_be32(s->nb_snapshots); 178 if (bdrv_pwrite(bs->file, offsetof(QCowHeader, nb_snapshots), 179 &data32, sizeof(data32)) != sizeof(data32)) 180 goto fail; 181 182 /* free the old snapshot table */ 183 qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size); 184 s->snapshots_offset = snapshots_offset; 185 s->snapshots_size = snapshots_size; 186 return 0; 187 fail: 188 return -1; 189 } 190 191 static void find_new_snapshot_id(BlockDriverState *bs, 192 char *id_str, int id_str_size) 193 { 194 BDRVQcowState *s = bs->opaque; 195 QCowSnapshot *sn; 196 int i, id, id_max = 0; 197 198 for(i = 0; i < s->nb_snapshots; i++) { 199 sn = s->snapshots + i; 200 id = strtoul(sn->id_str, NULL, 10); 201 if (id > id_max) 202 id_max = id; 203 } 204 snprintf(id_str, id_str_size, "%d", id_max + 1); 205 } 206 207 static int find_snapshot_by_id(BlockDriverState *bs, const char *id_str) 208 { 209 BDRVQcowState *s = bs->opaque; 210 int i; 211 212 for(i = 0; i < s->nb_snapshots; i++) { 213 if (!strcmp(s->snapshots[i].id_str, id_str)) 214 return i; 215 } 216 return -1; 217 } 218 219 static int find_snapshot_by_id_or_name(BlockDriverState *bs, const char *name) 220 { 221 BDRVQcowState *s = bs->opaque; 222 int i, ret; 223 224 ret = find_snapshot_by_id(bs, name); 225 if (ret >= 0) 226 return ret; 227 for(i = 0; i < s->nb_snapshots; i++) { 228 if (!strcmp(s->snapshots[i].name, name)) 229 return i; 230 } 231 return -1; 232 } 233 234 /* if no id is provided, a new one is constructed */ 235 int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) 236 { 237 BDRVQcowState *s = bs->opaque; 238 QCowSnapshot *snapshots1, sn1, *sn = &sn1; 239 int i, ret; 240 uint64_t *l1_table = NULL; 241 int64_t l1_table_offset; 242 243 memset(sn, 0, sizeof(*sn)); 244 245 if (sn_info->id_str[0] == '\0') { 246 /* compute a new id */ 247 find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str)); 248 } 249 250 /* check that the ID is unique */ 251 if (find_snapshot_by_id(bs, sn_info->id_str) >= 0) 252 return -ENOENT; 253 254 sn->id_str = qemu_strdup(sn_info->id_str); 255 if (!sn->id_str) 256 goto fail; 257 sn->name = qemu_strdup(sn_info->name); 258 if (!sn->name) 259 goto fail; 260 sn->vm_state_size = sn_info->vm_state_size; 261 sn->date_sec = sn_info->date_sec; 262 sn->date_nsec = sn_info->date_nsec; 263 sn->vm_clock_nsec = sn_info->vm_clock_nsec; 264 265 ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1); 266 if (ret < 0) 267 goto fail; 268 269 /* create the L1 table of the snapshot */ 270 l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t)); 271 if (l1_table_offset < 0) { 272 goto fail; 273 } 274 275 sn->l1_table_offset = l1_table_offset; 276 sn->l1_size = s->l1_size; 277 278 if (s->l1_size != 0) { 279 l1_table = qemu_malloc(s->l1_size * sizeof(uint64_t)); 280 } else { 281 l1_table = NULL; 282 } 283 284 for(i = 0; i < s->l1_size; i++) { 285 l1_table[i] = cpu_to_be64(s->l1_table[i]); 286 } 287 if (bdrv_pwrite(bs->file, sn->l1_table_offset, 288 l1_table, s->l1_size * sizeof(uint64_t)) != 289 (s->l1_size * sizeof(uint64_t))) 290 goto fail; 291 qemu_free(l1_table); 292 l1_table = NULL; 293 294 snapshots1 = qemu_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot)); 295 if (s->snapshots) { 296 memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot)); 297 qemu_free(s->snapshots); 298 } 299 s->snapshots = snapshots1; 300 s->snapshots[s->nb_snapshots++] = *sn; 301 302 if (qcow_write_snapshots(bs) < 0) 303 goto fail; 304 #ifdef DEBUG_ALLOC 305 qcow2_check_refcounts(bs); 306 #endif 307 return 0; 308 fail: 309 qemu_free(sn->name); 310 qemu_free(l1_table); 311 return -1; 312 } 313 314 /* copy the snapshot 'snapshot_name' into the current disk image */ 315 int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) 316 { 317 BDRVQcowState *s = bs->opaque; 318 QCowSnapshot *sn; 319 int i, snapshot_index, l1_size2; 320 321 snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); 322 if (snapshot_index < 0) 323 return -ENOENT; 324 sn = &s->snapshots[snapshot_index]; 325 326 if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1) < 0) 327 goto fail; 328 329 if (qcow2_grow_l1_table(bs, sn->l1_size) < 0) 330 goto fail; 331 332 s->l1_size = sn->l1_size; 333 l1_size2 = s->l1_size * sizeof(uint64_t); 334 /* copy the snapshot l1 table to the current l1 table */ 335 if (bdrv_pread(bs->file, sn->l1_table_offset, 336 s->l1_table, l1_size2) != l1_size2) 337 goto fail; 338 if (bdrv_pwrite(bs->file, s->l1_table_offset, 339 s->l1_table, l1_size2) != l1_size2) 340 goto fail; 341 for(i = 0;i < s->l1_size; i++) { 342 be64_to_cpus(&s->l1_table[i]); 343 } 344 345 if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1) < 0) 346 goto fail; 347 348 #ifdef DEBUG_ALLOC 349 qcow2_check_refcounts(bs); 350 #endif 351 return 0; 352 fail: 353 return -EIO; 354 } 355 356 int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 357 { 358 BDRVQcowState *s = bs->opaque; 359 QCowSnapshot *sn; 360 int snapshot_index, ret; 361 362 snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); 363 if (snapshot_index < 0) 364 return -ENOENT; 365 sn = &s->snapshots[snapshot_index]; 366 367 ret = qcow2_update_snapshot_refcount(bs, sn->l1_table_offset, sn->l1_size, -1); 368 if (ret < 0) 369 return ret; 370 /* must update the copied flag on the current cluster offsets */ 371 ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0); 372 if (ret < 0) 373 return ret; 374 qcow2_free_clusters(bs, sn->l1_table_offset, sn->l1_size * sizeof(uint64_t)); 375 376 qemu_free(sn->id_str); 377 qemu_free(sn->name); 378 memmove(sn, sn + 1, (s->nb_snapshots - snapshot_index - 1) * sizeof(*sn)); 379 s->nb_snapshots--; 380 ret = qcow_write_snapshots(bs); 381 if (ret < 0) { 382 /* XXX: restore snapshot if error ? */ 383 return ret; 384 } 385 #ifdef DEBUG_ALLOC 386 qcow2_check_refcounts(bs); 387 #endif 388 return 0; 389 } 390 391 int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) 392 { 393 BDRVQcowState *s = bs->opaque; 394 QEMUSnapshotInfo *sn_tab, *sn_info; 395 QCowSnapshot *sn; 396 int i; 397 398 if (!s->nb_snapshots) { 399 *psn_tab = NULL; 400 return s->nb_snapshots; 401 } 402 403 sn_tab = qemu_mallocz(s->nb_snapshots * sizeof(QEMUSnapshotInfo)); 404 for(i = 0; i < s->nb_snapshots; i++) { 405 sn_info = sn_tab + i; 406 sn = s->snapshots + i; 407 pstrcpy(sn_info->id_str, sizeof(sn_info->id_str), 408 sn->id_str); 409 pstrcpy(sn_info->name, sizeof(sn_info->name), 410 sn->name); 411 sn_info->vm_state_size = sn->vm_state_size; 412 sn_info->date_sec = sn->date_sec; 413 sn_info->date_nsec = sn->date_nsec; 414 sn_info->vm_clock_nsec = sn->vm_clock_nsec; 415 } 416 *psn_tab = sn_tab; 417 return s->nb_snapshots; 418 } 419 420