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_sync(bs->file, offset, &h, sizeof(h)) < 0) 162 goto fail; 163 offset += sizeof(h); 164 if (bdrv_pwrite_sync(bs->file, offset, sn->id_str, id_str_size) < 0) 165 goto fail; 166 offset += id_str_size; 167 if (bdrv_pwrite_sync(bs->file, offset, sn->name, name_size) < 0) 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_sync(bs->file, offsetof(QCowHeader, snapshots_offset), 175 &data64, sizeof(data64)) < 0) 176 goto fail; 177 data32 = cpu_to_be32(s->nb_snapshots); 178 if (bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots), 179 &data32, sizeof(data32)) < 0) 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_sync(bs->file, sn->l1_table_offset, 288 l1_table, s->l1_size * sizeof(uint64_t)) < 0) 289 goto fail; 290 qemu_free(l1_table); 291 l1_table = NULL; 292 293 snapshots1 = qemu_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot)); 294 if (s->snapshots) { 295 memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot)); 296 qemu_free(s->snapshots); 297 } 298 s->snapshots = snapshots1; 299 s->snapshots[s->nb_snapshots++] = *sn; 300 301 if (qcow_write_snapshots(bs) < 0) 302 goto fail; 303 #ifdef DEBUG_ALLOC 304 qcow2_check_refcounts(bs); 305 #endif 306 return 0; 307 fail: 308 qemu_free(sn->name); 309 qemu_free(l1_table); 310 return -1; 311 } 312 313 /* copy the snapshot 'snapshot_name' into the current disk image */ 314 int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) 315 { 316 BDRVQcowState *s = bs->opaque; 317 QCowSnapshot *sn; 318 int i, snapshot_index, l1_size2; 319 320 snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); 321 if (snapshot_index < 0) 322 return -ENOENT; 323 sn = &s->snapshots[snapshot_index]; 324 325 if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1) < 0) 326 goto fail; 327 328 if (qcow2_grow_l1_table(bs, sn->l1_size) < 0) 329 goto fail; 330 331 s->l1_size = sn->l1_size; 332 l1_size2 = s->l1_size * sizeof(uint64_t); 333 /* copy the snapshot l1 table to the current l1 table */ 334 if (bdrv_pread(bs->file, sn->l1_table_offset, 335 s->l1_table, l1_size2) != l1_size2) 336 goto fail; 337 if (bdrv_pwrite_sync(bs->file, s->l1_table_offset, 338 s->l1_table, l1_size2) < 0) 339 goto fail; 340 for(i = 0;i < s->l1_size; i++) { 341 be64_to_cpus(&s->l1_table[i]); 342 } 343 344 if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1) < 0) 345 goto fail; 346 347 #ifdef DEBUG_ALLOC 348 qcow2_check_refcounts(bs); 349 #endif 350 return 0; 351 fail: 352 return -EIO; 353 } 354 355 int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) 356 { 357 BDRVQcowState *s = bs->opaque; 358 QCowSnapshot *sn; 359 int snapshot_index, ret; 360 361 snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id); 362 if (snapshot_index < 0) 363 return -ENOENT; 364 sn = &s->snapshots[snapshot_index]; 365 366 ret = qcow2_update_snapshot_refcount(bs, sn->l1_table_offset, sn->l1_size, -1); 367 if (ret < 0) 368 return ret; 369 /* must update the copied flag on the current cluster offsets */ 370 ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0); 371 if (ret < 0) 372 return ret; 373 qcow2_free_clusters(bs, sn->l1_table_offset, sn->l1_size * sizeof(uint64_t)); 374 375 qemu_free(sn->id_str); 376 qemu_free(sn->name); 377 memmove(sn, sn + 1, (s->nb_snapshots - snapshot_index - 1) * sizeof(*sn)); 378 s->nb_snapshots--; 379 ret = qcow_write_snapshots(bs); 380 if (ret < 0) { 381 /* XXX: restore snapshot if error ? */ 382 return ret; 383 } 384 #ifdef DEBUG_ALLOC 385 qcow2_check_refcounts(bs); 386 #endif 387 return 0; 388 } 389 390 int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab) 391 { 392 BDRVQcowState *s = bs->opaque; 393 QEMUSnapshotInfo *sn_tab, *sn_info; 394 QCowSnapshot *sn; 395 int i; 396 397 if (!s->nb_snapshots) { 398 *psn_tab = NULL; 399 return s->nb_snapshots; 400 } 401 402 sn_tab = qemu_mallocz(s->nb_snapshots * sizeof(QEMUSnapshotInfo)); 403 for(i = 0; i < s->nb_snapshots; i++) { 404 sn_info = sn_tab + i; 405 sn = s->snapshots + i; 406 pstrcpy(sn_info->id_str, sizeof(sn_info->id_str), 407 sn->id_str); 408 pstrcpy(sn_info->name, sizeof(sn_info->name), 409 sn->name); 410 sn_info->vm_state_size = sn->vm_state_size; 411 sn_info->date_sec = sn->date_sec; 412 sn_info->date_nsec = sn->date_nsec; 413 sn_info->vm_clock_nsec = sn->vm_clock_nsec; 414 } 415 *psn_tab = sn_tab; 416 return s->nb_snapshots; 417 } 418 419