Statistics
| Branch: | Revision:

root / block / qcow2-snapshot.c @ 7371d56f

History | View | Annotate | Download (18.6 kB)

1 c142442b Kevin Wolf
/*
2 c142442b Kevin Wolf
 * Block driver for the QCOW version 2 format
3 c142442b Kevin Wolf
 *
4 c142442b Kevin Wolf
 * Copyright (c) 2004-2006 Fabrice Bellard
5 c142442b Kevin Wolf
 *
6 c142442b Kevin Wolf
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 c142442b Kevin Wolf
 * of this software and associated documentation files (the "Software"), to deal
8 c142442b Kevin Wolf
 * in the Software without restriction, including without limitation the rights
9 c142442b Kevin Wolf
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 c142442b Kevin Wolf
 * copies of the Software, and to permit persons to whom the Software is
11 c142442b Kevin Wolf
 * furnished to do so, subject to the following conditions:
12 c142442b Kevin Wolf
 *
13 c142442b Kevin Wolf
 * The above copyright notice and this permission notice shall be included in
14 c142442b Kevin Wolf
 * all copies or substantial portions of the Software.
15 c142442b Kevin Wolf
 *
16 c142442b Kevin Wolf
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 c142442b Kevin Wolf
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 c142442b Kevin Wolf
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 c142442b Kevin Wolf
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 c142442b Kevin Wolf
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 c142442b Kevin Wolf
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 c142442b Kevin Wolf
 * THE SOFTWARE.
23 c142442b Kevin Wolf
 */
24 c142442b Kevin Wolf
25 c142442b Kevin Wolf
#include "qemu-common.h"
26 737e150e Paolo Bonzini
#include "block/block_int.h"
27 c142442b Kevin Wolf
#include "block/qcow2.h"
28 c142442b Kevin Wolf
29 541dc0d4 Stefan Weil
typedef struct QEMU_PACKED QCowSnapshotHeader {
30 c142442b Kevin Wolf
    /* header is 8 byte aligned */
31 c142442b Kevin Wolf
    uint64_t l1_table_offset;
32 c142442b Kevin Wolf
33 c142442b Kevin Wolf
    uint32_t l1_size;
34 c142442b Kevin Wolf
    uint16_t id_str_size;
35 c142442b Kevin Wolf
    uint16_t name_size;
36 c142442b Kevin Wolf
37 c142442b Kevin Wolf
    uint32_t date_sec;
38 c142442b Kevin Wolf
    uint32_t date_nsec;
39 c142442b Kevin Wolf
40 c142442b Kevin Wolf
    uint64_t vm_clock_nsec;
41 c142442b Kevin Wolf
42 c142442b Kevin Wolf
    uint32_t vm_state_size;
43 c142442b Kevin Wolf
    uint32_t extra_data_size; /* for extension */
44 c142442b Kevin Wolf
    /* extra data follows */
45 c142442b Kevin Wolf
    /* id_str follows */
46 c142442b Kevin Wolf
    /* name follows  */
47 c142442b Kevin Wolf
} QCowSnapshotHeader;
48 c142442b Kevin Wolf
49 c2c9a466 Kevin Wolf
typedef struct QEMU_PACKED QCowSnapshotExtraData {
50 c2c9a466 Kevin Wolf
    uint64_t vm_state_size_large;
51 90b27759 Kevin Wolf
    uint64_t disk_size;
52 c2c9a466 Kevin Wolf
} QCowSnapshotExtraData;
53 c2c9a466 Kevin Wolf
54 ed6ccf0f Kevin Wolf
void qcow2_free_snapshots(BlockDriverState *bs)
55 c142442b Kevin Wolf
{
56 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
57 c142442b Kevin Wolf
    int i;
58 c142442b Kevin Wolf
59 c142442b Kevin Wolf
    for(i = 0; i < s->nb_snapshots; i++) {
60 7267c094 Anthony Liguori
        g_free(s->snapshots[i].name);
61 7267c094 Anthony Liguori
        g_free(s->snapshots[i].id_str);
62 c142442b Kevin Wolf
    }
63 7267c094 Anthony Liguori
    g_free(s->snapshots);
64 c142442b Kevin Wolf
    s->snapshots = NULL;
65 c142442b Kevin Wolf
    s->nb_snapshots = 0;
66 c142442b Kevin Wolf
}
67 c142442b Kevin Wolf
68 ed6ccf0f Kevin Wolf
int qcow2_read_snapshots(BlockDriverState *bs)
69 c142442b Kevin Wolf
{
70 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
71 c142442b Kevin Wolf
    QCowSnapshotHeader h;
72 c2c9a466 Kevin Wolf
    QCowSnapshotExtraData extra;
73 c142442b Kevin Wolf
    QCowSnapshot *sn;
74 c142442b Kevin Wolf
    int i, id_str_size, name_size;
75 c142442b Kevin Wolf
    int64_t offset;
76 c142442b Kevin Wolf
    uint32_t extra_data_size;
77 42deb29f Kevin Wolf
    int ret;
78 c142442b Kevin Wolf
79 c142442b Kevin Wolf
    if (!s->nb_snapshots) {
80 c142442b Kevin Wolf
        s->snapshots = NULL;
81 c142442b Kevin Wolf
        s->snapshots_size = 0;
82 c142442b Kevin Wolf
        return 0;
83 c142442b Kevin Wolf
    }
84 c142442b Kevin Wolf
85 c142442b Kevin Wolf
    offset = s->snapshots_offset;
86 7267c094 Anthony Liguori
    s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot));
87 42deb29f Kevin Wolf
88 c142442b Kevin Wolf
    for(i = 0; i < s->nb_snapshots; i++) {
89 42deb29f Kevin Wolf
        /* Read statically sized part of the snapshot header */
90 c142442b Kevin Wolf
        offset = align_offset(offset, 8);
91 42deb29f Kevin Wolf
        ret = bdrv_pread(bs->file, offset, &h, sizeof(h));
92 42deb29f Kevin Wolf
        if (ret < 0) {
93 c142442b Kevin Wolf
            goto fail;
94 42deb29f Kevin Wolf
        }
95 42deb29f Kevin Wolf
96 c142442b Kevin Wolf
        offset += sizeof(h);
97 c142442b Kevin Wolf
        sn = s->snapshots + i;
98 c142442b Kevin Wolf
        sn->l1_table_offset = be64_to_cpu(h.l1_table_offset);
99 c142442b Kevin Wolf
        sn->l1_size = be32_to_cpu(h.l1_size);
100 c142442b Kevin Wolf
        sn->vm_state_size = be32_to_cpu(h.vm_state_size);
101 c142442b Kevin Wolf
        sn->date_sec = be32_to_cpu(h.date_sec);
102 c142442b Kevin Wolf
        sn->date_nsec = be32_to_cpu(h.date_nsec);
103 c142442b Kevin Wolf
        sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec);
104 c142442b Kevin Wolf
        extra_data_size = be32_to_cpu(h.extra_data_size);
105 c142442b Kevin Wolf
106 c142442b Kevin Wolf
        id_str_size = be16_to_cpu(h.id_str_size);
107 c142442b Kevin Wolf
        name_size = be16_to_cpu(h.name_size);
108 c142442b Kevin Wolf
109 c2c9a466 Kevin Wolf
        /* Read extra data */
110 c2c9a466 Kevin Wolf
        ret = bdrv_pread(bs->file, offset, &extra,
111 c2c9a466 Kevin Wolf
                         MIN(sizeof(extra), extra_data_size));
112 c2c9a466 Kevin Wolf
        if (ret < 0) {
113 c2c9a466 Kevin Wolf
            goto fail;
114 c2c9a466 Kevin Wolf
        }
115 c142442b Kevin Wolf
        offset += extra_data_size;
116 c142442b Kevin Wolf
117 c2c9a466 Kevin Wolf
        if (extra_data_size >= 8) {
118 c2c9a466 Kevin Wolf
            sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large);
119 c2c9a466 Kevin Wolf
        }
120 c2c9a466 Kevin Wolf
121 90b27759 Kevin Wolf
        if (extra_data_size >= 16) {
122 90b27759 Kevin Wolf
            sn->disk_size = be64_to_cpu(extra.disk_size);
123 90b27759 Kevin Wolf
        } else {
124 90b27759 Kevin Wolf
            sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
125 90b27759 Kevin Wolf
        }
126 90b27759 Kevin Wolf
127 42deb29f Kevin Wolf
        /* Read snapshot ID */
128 7267c094 Anthony Liguori
        sn->id_str = g_malloc(id_str_size + 1);
129 42deb29f Kevin Wolf
        ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size);
130 42deb29f Kevin Wolf
        if (ret < 0) {
131 c142442b Kevin Wolf
            goto fail;
132 42deb29f Kevin Wolf
        }
133 c142442b Kevin Wolf
        offset += id_str_size;
134 c142442b Kevin Wolf
        sn->id_str[id_str_size] = '\0';
135 c142442b Kevin Wolf
136 42deb29f Kevin Wolf
        /* Read snapshot name */
137 7267c094 Anthony Liguori
        sn->name = g_malloc(name_size + 1);
138 42deb29f Kevin Wolf
        ret = bdrv_pread(bs->file, offset, sn->name, name_size);
139 42deb29f Kevin Wolf
        if (ret < 0) {
140 c142442b Kevin Wolf
            goto fail;
141 42deb29f Kevin Wolf
        }
142 c142442b Kevin Wolf
        offset += name_size;
143 c142442b Kevin Wolf
        sn->name[name_size] = '\0';
144 c142442b Kevin Wolf
    }
145 42deb29f Kevin Wolf
146 c142442b Kevin Wolf
    s->snapshots_size = offset - s->snapshots_offset;
147 c142442b Kevin Wolf
    return 0;
148 42deb29f Kevin Wolf
149 42deb29f Kevin Wolf
fail:
150 ed6ccf0f Kevin Wolf
    qcow2_free_snapshots(bs);
151 42deb29f Kevin Wolf
    return ret;
152 c142442b Kevin Wolf
}
153 c142442b Kevin Wolf
154 c142442b Kevin Wolf
/* add at the end of the file a new list of snapshots */
155 7c80ab3f Jes Sorensen
static int qcow2_write_snapshots(BlockDriverState *bs)
156 c142442b Kevin Wolf
{
157 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
158 c142442b Kevin Wolf
    QCowSnapshot *sn;
159 c142442b Kevin Wolf
    QCowSnapshotHeader h;
160 c2c9a466 Kevin Wolf
    QCowSnapshotExtraData extra;
161 c142442b Kevin Wolf
    int i, name_size, id_str_size, snapshots_size;
162 d69969c4 Kevin Wolf
    struct {
163 d69969c4 Kevin Wolf
        uint32_t nb_snapshots;
164 d69969c4 Kevin Wolf
        uint64_t snapshots_offset;
165 d69969c4 Kevin Wolf
    } QEMU_PACKED header_data;
166 c142442b Kevin Wolf
    int64_t offset, snapshots_offset;
167 07fd8779 Kevin Wolf
    int ret;
168 c142442b Kevin Wolf
169 c142442b Kevin Wolf
    /* compute the size of the snapshots */
170 c142442b Kevin Wolf
    offset = 0;
171 c142442b Kevin Wolf
    for(i = 0; i < s->nb_snapshots; i++) {
172 c142442b Kevin Wolf
        sn = s->snapshots + i;
173 c142442b Kevin Wolf
        offset = align_offset(offset, 8);
174 c142442b Kevin Wolf
        offset += sizeof(h);
175 c2c9a466 Kevin Wolf
        offset += sizeof(extra);
176 c142442b Kevin Wolf
        offset += strlen(sn->id_str);
177 c142442b Kevin Wolf
        offset += strlen(sn->name);
178 c142442b Kevin Wolf
    }
179 c142442b Kevin Wolf
    snapshots_size = offset;
180 c142442b Kevin Wolf
181 07fd8779 Kevin Wolf
    /* Allocate space for the new snapshot list */
182 ed6ccf0f Kevin Wolf
    snapshots_offset = qcow2_alloc_clusters(bs, snapshots_size);
183 29216ed1 Kevin Wolf
    bdrv_flush(bs->file);
184 c142442b Kevin Wolf
    offset = snapshots_offset;
185 5d757b56 Kevin Wolf
    if (offset < 0) {
186 5d757b56 Kevin Wolf
        return offset;
187 5d757b56 Kevin Wolf
    }
188 c142442b Kevin Wolf
189 07fd8779 Kevin Wolf
    /* Write all snapshots to the new list */
190 c142442b Kevin Wolf
    for(i = 0; i < s->nb_snapshots; i++) {
191 c142442b Kevin Wolf
        sn = s->snapshots + i;
192 c142442b Kevin Wolf
        memset(&h, 0, sizeof(h));
193 c142442b Kevin Wolf
        h.l1_table_offset = cpu_to_be64(sn->l1_table_offset);
194 c142442b Kevin Wolf
        h.l1_size = cpu_to_be32(sn->l1_size);
195 c2c9a466 Kevin Wolf
        /* If it doesn't fit in 32 bit, older implementations should treat it
196 c2c9a466 Kevin Wolf
         * as a disk-only snapshot rather than truncate the VM state */
197 c2c9a466 Kevin Wolf
        if (sn->vm_state_size <= 0xffffffff) {
198 c2c9a466 Kevin Wolf
            h.vm_state_size = cpu_to_be32(sn->vm_state_size);
199 c2c9a466 Kevin Wolf
        }
200 c142442b Kevin Wolf
        h.date_sec = cpu_to_be32(sn->date_sec);
201 c142442b Kevin Wolf
        h.date_nsec = cpu_to_be32(sn->date_nsec);
202 c142442b Kevin Wolf
        h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec);
203 c2c9a466 Kevin Wolf
        h.extra_data_size = cpu_to_be32(sizeof(extra));
204 c2c9a466 Kevin Wolf
205 c2c9a466 Kevin Wolf
        memset(&extra, 0, sizeof(extra));
206 c2c9a466 Kevin Wolf
        extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size);
207 90b27759 Kevin Wolf
        extra.disk_size = cpu_to_be64(sn->disk_size);
208 c142442b Kevin Wolf
209 c142442b Kevin Wolf
        id_str_size = strlen(sn->id_str);
210 c142442b Kevin Wolf
        name_size = strlen(sn->name);
211 c142442b Kevin Wolf
        h.id_str_size = cpu_to_be16(id_str_size);
212 c142442b Kevin Wolf
        h.name_size = cpu_to_be16(name_size);
213 c142442b Kevin Wolf
        offset = align_offset(offset, 8);
214 07fd8779 Kevin Wolf
215 07fd8779 Kevin Wolf
        ret = bdrv_pwrite(bs->file, offset, &h, sizeof(h));
216 07fd8779 Kevin Wolf
        if (ret < 0) {
217 c142442b Kevin Wolf
            goto fail;
218 07fd8779 Kevin Wolf
        }
219 c142442b Kevin Wolf
        offset += sizeof(h);
220 07fd8779 Kevin Wolf
221 c2c9a466 Kevin Wolf
        ret = bdrv_pwrite(bs->file, offset, &extra, sizeof(extra));
222 c2c9a466 Kevin Wolf
        if (ret < 0) {
223 c2c9a466 Kevin Wolf
            goto fail;
224 c2c9a466 Kevin Wolf
        }
225 c2c9a466 Kevin Wolf
        offset += sizeof(extra);
226 c2c9a466 Kevin Wolf
227 07fd8779 Kevin Wolf
        ret = bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size);
228 07fd8779 Kevin Wolf
        if (ret < 0) {
229 c142442b Kevin Wolf
            goto fail;
230 07fd8779 Kevin Wolf
        }
231 c142442b Kevin Wolf
        offset += id_str_size;
232 07fd8779 Kevin Wolf
233 07fd8779 Kevin Wolf
        ret = bdrv_pwrite(bs->file, offset, sn->name, name_size);
234 07fd8779 Kevin Wolf
        if (ret < 0) {
235 c142442b Kevin Wolf
            goto fail;
236 07fd8779 Kevin Wolf
        }
237 c142442b Kevin Wolf
        offset += name_size;
238 c142442b Kevin Wolf
    }
239 c142442b Kevin Wolf
240 07fd8779 Kevin Wolf
    /*
241 07fd8779 Kevin Wolf
     * Update the header to point to the new snapshot table. This requires the
242 07fd8779 Kevin Wolf
     * new table and its refcounts to be stable on disk.
243 07fd8779 Kevin Wolf
     */
244 07fd8779 Kevin Wolf
    ret = bdrv_flush(bs);
245 07fd8779 Kevin Wolf
    if (ret < 0) {
246 07fd8779 Kevin Wolf
        goto fail;
247 07fd8779 Kevin Wolf
    }
248 07fd8779 Kevin Wolf
249 d69969c4 Kevin Wolf
    QEMU_BUILD_BUG_ON(offsetof(QCowHeader, snapshots_offset) !=
250 d69969c4 Kevin Wolf
        offsetof(QCowHeader, nb_snapshots) + sizeof(header_data.nb_snapshots));
251 d69969c4 Kevin Wolf
252 d69969c4 Kevin Wolf
    header_data.nb_snapshots        = cpu_to_be32(s->nb_snapshots);
253 d69969c4 Kevin Wolf
    header_data.snapshots_offset    = cpu_to_be64(snapshots_offset);
254 07fd8779 Kevin Wolf
255 07fd8779 Kevin Wolf
    ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapshots),
256 d69969c4 Kevin Wolf
                           &header_data, sizeof(header_data));
257 07fd8779 Kevin Wolf
    if (ret < 0) {
258 c142442b Kevin Wolf
        goto fail;
259 07fd8779 Kevin Wolf
    }
260 c142442b Kevin Wolf
261 c142442b Kevin Wolf
    /* free the old snapshot table */
262 ed6ccf0f Kevin Wolf
    qcow2_free_clusters(bs, s->snapshots_offset, s->snapshots_size);
263 c142442b Kevin Wolf
    s->snapshots_offset = snapshots_offset;
264 c142442b Kevin Wolf
    s->snapshots_size = snapshots_size;
265 c142442b Kevin Wolf
    return 0;
266 07fd8779 Kevin Wolf
267 07fd8779 Kevin Wolf
fail:
268 07fd8779 Kevin Wolf
    return ret;
269 c142442b Kevin Wolf
}
270 c142442b Kevin Wolf
271 c142442b Kevin Wolf
static void find_new_snapshot_id(BlockDriverState *bs,
272 c142442b Kevin Wolf
                                 char *id_str, int id_str_size)
273 c142442b Kevin Wolf
{
274 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
275 c142442b Kevin Wolf
    QCowSnapshot *sn;
276 c142442b Kevin Wolf
    int i, id, id_max = 0;
277 c142442b Kevin Wolf
278 c142442b Kevin Wolf
    for(i = 0; i < s->nb_snapshots; i++) {
279 c142442b Kevin Wolf
        sn = s->snapshots + i;
280 c142442b Kevin Wolf
        id = strtoul(sn->id_str, NULL, 10);
281 c142442b Kevin Wolf
        if (id > id_max)
282 c142442b Kevin Wolf
            id_max = id;
283 c142442b Kevin Wolf
    }
284 c142442b Kevin Wolf
    snprintf(id_str, id_str_size, "%d", id_max + 1);
285 c142442b Kevin Wolf
}
286 c142442b Kevin Wolf
287 c142442b Kevin Wolf
static int find_snapshot_by_id(BlockDriverState *bs, const char *id_str)
288 c142442b Kevin Wolf
{
289 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
290 c142442b Kevin Wolf
    int i;
291 c142442b Kevin Wolf
292 c142442b Kevin Wolf
    for(i = 0; i < s->nb_snapshots; i++) {
293 c142442b Kevin Wolf
        if (!strcmp(s->snapshots[i].id_str, id_str))
294 c142442b Kevin Wolf
            return i;
295 c142442b Kevin Wolf
    }
296 c142442b Kevin Wolf
    return -1;
297 c142442b Kevin Wolf
}
298 c142442b Kevin Wolf
299 c142442b Kevin Wolf
static int find_snapshot_by_id_or_name(BlockDriverState *bs, const char *name)
300 c142442b Kevin Wolf
{
301 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
302 c142442b Kevin Wolf
    int i, ret;
303 c142442b Kevin Wolf
304 c142442b Kevin Wolf
    ret = find_snapshot_by_id(bs, name);
305 c142442b Kevin Wolf
    if (ret >= 0)
306 c142442b Kevin Wolf
        return ret;
307 c142442b Kevin Wolf
    for(i = 0; i < s->nb_snapshots; i++) {
308 c142442b Kevin Wolf
        if (!strcmp(s->snapshots[i].name, name))
309 c142442b Kevin Wolf
            return i;
310 c142442b Kevin Wolf
    }
311 c142442b Kevin Wolf
    return -1;
312 c142442b Kevin Wolf
}
313 c142442b Kevin Wolf
314 c142442b Kevin Wolf
/* if no id is provided, a new one is constructed */
315 ed6ccf0f Kevin Wolf
int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
316 c142442b Kevin Wolf
{
317 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
318 d1ea98d5 Kevin Wolf
    QCowSnapshot *new_snapshot_list = NULL;
319 d1ea98d5 Kevin Wolf
    QCowSnapshot *old_snapshot_list = NULL;
320 d1ea98d5 Kevin Wolf
    QCowSnapshot sn1, *sn = &sn1;
321 c142442b Kevin Wolf
    int i, ret;
322 c142442b Kevin Wolf
    uint64_t *l1_table = NULL;
323 5d757b56 Kevin Wolf
    int64_t l1_table_offset;
324 c142442b Kevin Wolf
325 c142442b Kevin Wolf
    memset(sn, 0, sizeof(*sn));
326 c142442b Kevin Wolf
327 03343166 Kevin Wolf
    /* Generate an ID if it wasn't passed */
328 c142442b Kevin Wolf
    if (sn_info->id_str[0] == '\0') {
329 c142442b Kevin Wolf
        find_new_snapshot_id(bs, sn_info->id_str, sizeof(sn_info->id_str));
330 c142442b Kevin Wolf
    }
331 c142442b Kevin Wolf
332 03343166 Kevin Wolf
    /* Check that the ID is unique */
333 03343166 Kevin Wolf
    if (find_snapshot_by_id(bs, sn_info->id_str) >= 0) {
334 647cc472 Zhi Yong Wu
        return -EEXIST;
335 03343166 Kevin Wolf
    }
336 c142442b Kevin Wolf
337 03343166 Kevin Wolf
    /* Populate sn with passed data */
338 7267c094 Anthony Liguori
    sn->id_str = g_strdup(sn_info->id_str);
339 7267c094 Anthony Liguori
    sn->name = g_strdup(sn_info->name);
340 03343166 Kevin Wolf
341 90b27759 Kevin Wolf
    sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
342 c142442b Kevin Wolf
    sn->vm_state_size = sn_info->vm_state_size;
343 c142442b Kevin Wolf
    sn->date_sec = sn_info->date_sec;
344 c142442b Kevin Wolf
    sn->date_nsec = sn_info->date_nsec;
345 c142442b Kevin Wolf
    sn->vm_clock_nsec = sn_info->vm_clock_nsec;
346 c142442b Kevin Wolf
347 03343166 Kevin Wolf
    /* Allocate the L1 table of the snapshot and copy the current one there. */
348 5d757b56 Kevin Wolf
    l1_table_offset = qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint64_t));
349 5d757b56 Kevin Wolf
    if (l1_table_offset < 0) {
350 d1ea98d5 Kevin Wolf
        ret = l1_table_offset;
351 5d757b56 Kevin Wolf
        goto fail;
352 5d757b56 Kevin Wolf
    }
353 5d757b56 Kevin Wolf
354 5d757b56 Kevin Wolf
    sn->l1_table_offset = l1_table_offset;
355 c142442b Kevin Wolf
    sn->l1_size = s->l1_size;
356 c142442b Kevin Wolf
357 03343166 Kevin Wolf
    l1_table = g_malloc(s->l1_size * sizeof(uint64_t));
358 c142442b Kevin Wolf
    for(i = 0; i < s->l1_size; i++) {
359 c142442b Kevin Wolf
        l1_table[i] = cpu_to_be64(s->l1_table[i]);
360 c142442b Kevin Wolf
    }
361 d1ea98d5 Kevin Wolf
362 d1ea98d5 Kevin Wolf
    ret = bdrv_pwrite(bs->file, sn->l1_table_offset, l1_table,
363 d1ea98d5 Kevin Wolf
                      s->l1_size * sizeof(uint64_t));
364 d1ea98d5 Kevin Wolf
    if (ret < 0) {
365 c142442b Kevin Wolf
        goto fail;
366 d1ea98d5 Kevin Wolf
    }
367 d1ea98d5 Kevin Wolf
368 7267c094 Anthony Liguori
    g_free(l1_table);
369 c142442b Kevin Wolf
    l1_table = NULL;
370 c142442b Kevin Wolf
371 d1ea98d5 Kevin Wolf
    /*
372 d1ea98d5 Kevin Wolf
     * Increase the refcounts of all clusters and make sure everything is
373 d1ea98d5 Kevin Wolf
     * stable on disk before updating the snapshot table to contain a pointer
374 d1ea98d5 Kevin Wolf
     * to the new L1 table.
375 d1ea98d5 Kevin Wolf
     */
376 d1ea98d5 Kevin Wolf
    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 1);
377 d1ea98d5 Kevin Wolf
    if (ret < 0) {
378 d1ea98d5 Kevin Wolf
        goto fail;
379 d1ea98d5 Kevin Wolf
    }
380 d1ea98d5 Kevin Wolf
381 d1ea98d5 Kevin Wolf
    ret = bdrv_flush(bs);
382 d1ea98d5 Kevin Wolf
    if (ret < 0) {
383 d1ea98d5 Kevin Wolf
        goto fail;
384 d1ea98d5 Kevin Wolf
    }
385 d1ea98d5 Kevin Wolf
386 d1ea98d5 Kevin Wolf
    /* Append the new snapshot to the snapshot list */
387 d1ea98d5 Kevin Wolf
    new_snapshot_list = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
388 c142442b Kevin Wolf
    if (s->snapshots) {
389 d1ea98d5 Kevin Wolf
        memcpy(new_snapshot_list, s->snapshots,
390 d1ea98d5 Kevin Wolf
               s->nb_snapshots * sizeof(QCowSnapshot));
391 d1ea98d5 Kevin Wolf
        old_snapshot_list = s->snapshots;
392 c142442b Kevin Wolf
    }
393 d1ea98d5 Kevin Wolf
    s->snapshots = new_snapshot_list;
394 c142442b Kevin Wolf
    s->snapshots[s->nb_snapshots++] = *sn;
395 c142442b Kevin Wolf
396 d1ea98d5 Kevin Wolf
    ret = qcow2_write_snapshots(bs);
397 d1ea98d5 Kevin Wolf
    if (ret < 0) {
398 d1ea98d5 Kevin Wolf
        g_free(s->snapshots);
399 d1ea98d5 Kevin Wolf
        s->snapshots = old_snapshot_list;
400 c142442b Kevin Wolf
        goto fail;
401 d1ea98d5 Kevin Wolf
    }
402 d1ea98d5 Kevin Wolf
403 d1ea98d5 Kevin Wolf
    g_free(old_snapshot_list);
404 d1ea98d5 Kevin Wolf
405 c142442b Kevin Wolf
#ifdef DEBUG_ALLOC
406 6cbc3031 Philipp Hahn
    {
407 6cbc3031 Philipp Hahn
      BdrvCheckResult result = {0};
408 b35278f7 Stefan Hajnoczi
      qcow2_check_refcounts(bs, &result, 0);
409 6cbc3031 Philipp Hahn
    }
410 c142442b Kevin Wolf
#endif
411 c142442b Kevin Wolf
    return 0;
412 03343166 Kevin Wolf
413 03343166 Kevin Wolf
fail:
414 03343166 Kevin Wolf
    g_free(sn->id_str);
415 7267c094 Anthony Liguori
    g_free(sn->name);
416 7267c094 Anthony Liguori
    g_free(l1_table);
417 d1ea98d5 Kevin Wolf
418 d1ea98d5 Kevin Wolf
    return ret;
419 c142442b Kevin Wolf
}
420 c142442b Kevin Wolf
421 c142442b Kevin Wolf
/* copy the snapshot 'snapshot_name' into the current disk image */
422 ed6ccf0f Kevin Wolf
int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
423 c142442b Kevin Wolf
{
424 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
425 c142442b Kevin Wolf
    QCowSnapshot *sn;
426 35d7ace7 Kevin Wolf
    int i, snapshot_index;
427 35d7ace7 Kevin Wolf
    int cur_l1_bytes, sn_l1_bytes;
428 589f284b Kevin Wolf
    int ret;
429 43a0cac4 Kevin Wolf
    uint64_t *sn_l1_table = NULL;
430 c142442b Kevin Wolf
431 589f284b Kevin Wolf
    /* Search the snapshot */
432 c142442b Kevin Wolf
    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
433 589f284b Kevin Wolf
    if (snapshot_index < 0) {
434 c142442b Kevin Wolf
        return -ENOENT;
435 589f284b Kevin Wolf
    }
436 c142442b Kevin Wolf
    sn = &s->snapshots[snapshot_index];
437 c142442b Kevin Wolf
438 90b27759 Kevin Wolf
    if (sn->disk_size != bs->total_sectors * BDRV_SECTOR_SIZE) {
439 90b27759 Kevin Wolf
        error_report("qcow2: Loading snapshots with different disk "
440 90b27759 Kevin Wolf
            "size is not implemented");
441 90b27759 Kevin Wolf
        ret = -ENOTSUP;
442 90b27759 Kevin Wolf
        goto fail;
443 90b27759 Kevin Wolf
    }
444 90b27759 Kevin Wolf
445 589f284b Kevin Wolf
    /*
446 589f284b Kevin Wolf
     * Make sure that the current L1 table is big enough to contain the whole
447 589f284b Kevin Wolf
     * L1 table of the snapshot. If the snapshot L1 table is smaller, the
448 589f284b Kevin Wolf
     * current one must be padded with zeros.
449 589f284b Kevin Wolf
     */
450 589f284b Kevin Wolf
    ret = qcow2_grow_l1_table(bs, sn->l1_size, true);
451 589f284b Kevin Wolf
    if (ret < 0) {
452 c142442b Kevin Wolf
        goto fail;
453 589f284b Kevin Wolf
    }
454 c142442b Kevin Wolf
455 35d7ace7 Kevin Wolf
    cur_l1_bytes = s->l1_size * sizeof(uint64_t);
456 35d7ace7 Kevin Wolf
    sn_l1_bytes = sn->l1_size * sizeof(uint64_t);
457 35d7ace7 Kevin Wolf
458 589f284b Kevin Wolf
    /*
459 589f284b Kevin Wolf
     * Copy the snapshot L1 table to the current L1 table.
460 589f284b Kevin Wolf
     *
461 589f284b Kevin Wolf
     * Before overwriting the old current L1 table on disk, make sure to
462 589f284b Kevin Wolf
     * increase all refcounts for the clusters referenced by the new one.
463 43a0cac4 Kevin Wolf
     * Decrease the refcount referenced by the old one only when the L1
464 43a0cac4 Kevin Wolf
     * table is overwritten.
465 589f284b Kevin Wolf
     */
466 43a0cac4 Kevin Wolf
    sn_l1_table = g_malloc0(cur_l1_bytes);
467 43a0cac4 Kevin Wolf
468 43a0cac4 Kevin Wolf
    ret = bdrv_pread(bs->file, sn->l1_table_offset, sn_l1_table, sn_l1_bytes);
469 43a0cac4 Kevin Wolf
    if (ret < 0) {
470 43a0cac4 Kevin Wolf
        goto fail;
471 43a0cac4 Kevin Wolf
    }
472 43a0cac4 Kevin Wolf
473 43a0cac4 Kevin Wolf
    ret = qcow2_update_snapshot_refcount(bs, sn->l1_table_offset,
474 43a0cac4 Kevin Wolf
                                         sn->l1_size, 1);
475 589f284b Kevin Wolf
    if (ret < 0) {
476 c142442b Kevin Wolf
        goto fail;
477 589f284b Kevin Wolf
    }
478 589f284b Kevin Wolf
479 43a0cac4 Kevin Wolf
    ret = bdrv_pwrite_sync(bs->file, s->l1_table_offset, sn_l1_table,
480 589f284b Kevin Wolf
                           cur_l1_bytes);
481 589f284b Kevin Wolf
    if (ret < 0) {
482 c142442b Kevin Wolf
        goto fail;
483 589f284b Kevin Wolf
    }
484 589f284b Kevin Wolf
485 43a0cac4 Kevin Wolf
    /*
486 43a0cac4 Kevin Wolf
     * Decrease refcount of clusters of current L1 table.
487 43a0cac4 Kevin Wolf
     *
488 43a0cac4 Kevin Wolf
     * At this point, the in-memory s->l1_table points to the old L1 table,
489 43a0cac4 Kevin Wolf
     * whereas on disk we already have the new one.
490 43a0cac4 Kevin Wolf
     *
491 43a0cac4 Kevin Wolf
     * qcow2_update_snapshot_refcount special cases the current L1 table to use
492 43a0cac4 Kevin Wolf
     * the in-memory data instead of really using the offset to load a new one,
493 43a0cac4 Kevin Wolf
     * which is why this works.
494 43a0cac4 Kevin Wolf
     */
495 43a0cac4 Kevin Wolf
    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset,
496 43a0cac4 Kevin Wolf
                                         s->l1_size, -1);
497 43a0cac4 Kevin Wolf
498 43a0cac4 Kevin Wolf
    /*
499 43a0cac4 Kevin Wolf
     * Now update the in-memory L1 table to be in sync with the on-disk one. We
500 43a0cac4 Kevin Wolf
     * need to do this even if updating refcounts failed.
501 43a0cac4 Kevin Wolf
     */
502 c142442b Kevin Wolf
    for(i = 0;i < s->l1_size; i++) {
503 43a0cac4 Kevin Wolf
        s->l1_table[i] = be64_to_cpu(sn_l1_table[i]);
504 c142442b Kevin Wolf
    }
505 c142442b Kevin Wolf
506 43a0cac4 Kevin Wolf
    if (ret < 0) {
507 43a0cac4 Kevin Wolf
        goto fail;
508 43a0cac4 Kevin Wolf
    }
509 43a0cac4 Kevin Wolf
510 43a0cac4 Kevin Wolf
    g_free(sn_l1_table);
511 43a0cac4 Kevin Wolf
    sn_l1_table = NULL;
512 43a0cac4 Kevin Wolf
513 43a0cac4 Kevin Wolf
    /*
514 43a0cac4 Kevin Wolf
     * Update QCOW_OFLAG_COPIED in the active L1 table (it may have changed
515 43a0cac4 Kevin Wolf
     * when we decreased the refcount of the old snapshot.
516 43a0cac4 Kevin Wolf
     */
517 43a0cac4 Kevin Wolf
    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);
518 589f284b Kevin Wolf
    if (ret < 0) {
519 c142442b Kevin Wolf
        goto fail;
520 589f284b Kevin Wolf
    }
521 c142442b Kevin Wolf
522 c142442b Kevin Wolf
#ifdef DEBUG_ALLOC
523 6cbc3031 Philipp Hahn
    {
524 6cbc3031 Philipp Hahn
        BdrvCheckResult result = {0};
525 b35278f7 Stefan Hajnoczi
        qcow2_check_refcounts(bs, &result, 0);
526 6cbc3031 Philipp Hahn
    }
527 c142442b Kevin Wolf
#endif
528 c142442b Kevin Wolf
    return 0;
529 589f284b Kevin Wolf
530 589f284b Kevin Wolf
fail:
531 43a0cac4 Kevin Wolf
    g_free(sn_l1_table);
532 589f284b Kevin Wolf
    return ret;
533 c142442b Kevin Wolf
}
534 c142442b Kevin Wolf
535 ed6ccf0f Kevin Wolf
int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
536 c142442b Kevin Wolf
{
537 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
538 9a476780 Kevin Wolf
    QCowSnapshot sn;
539 c142442b Kevin Wolf
    int snapshot_index, ret;
540 c142442b Kevin Wolf
541 9a476780 Kevin Wolf
    /* Search the snapshot */
542 c142442b Kevin Wolf
    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
543 9a476780 Kevin Wolf
    if (snapshot_index < 0) {
544 c142442b Kevin Wolf
        return -ENOENT;
545 9a476780 Kevin Wolf
    }
546 9a476780 Kevin Wolf
    sn = s->snapshots[snapshot_index];
547 c142442b Kevin Wolf
548 9a476780 Kevin Wolf
    /* Remove it from the snapshot list */
549 9a476780 Kevin Wolf
    memmove(s->snapshots + snapshot_index,
550 9a476780 Kevin Wolf
            s->snapshots + snapshot_index + 1,
551 9a476780 Kevin Wolf
            (s->nb_snapshots - snapshot_index - 1) * sizeof(sn));
552 9a476780 Kevin Wolf
    s->nb_snapshots--;
553 9a476780 Kevin Wolf
    ret = qcow2_write_snapshots(bs);
554 9a476780 Kevin Wolf
    if (ret < 0) {
555 c142442b Kevin Wolf
        return ret;
556 9a476780 Kevin Wolf
    }
557 9a476780 Kevin Wolf
558 9a476780 Kevin Wolf
    /*
559 9a476780 Kevin Wolf
     * The snapshot is now unused, clean up. If we fail after this point, we
560 9a476780 Kevin Wolf
     * won't recover but just leak clusters.
561 9a476780 Kevin Wolf
     */
562 9a476780 Kevin Wolf
    g_free(sn.id_str);
563 9a476780 Kevin Wolf
    g_free(sn.name);
564 9a476780 Kevin Wolf
565 9a476780 Kevin Wolf
    /*
566 9a476780 Kevin Wolf
     * Now decrease the refcounts of clusters referenced by the snapshot and
567 9a476780 Kevin Wolf
     * free the L1 table.
568 9a476780 Kevin Wolf
     */
569 9a476780 Kevin Wolf
    ret = qcow2_update_snapshot_refcount(bs, sn.l1_table_offset,
570 9a476780 Kevin Wolf
                                         sn.l1_size, -1);
571 9a476780 Kevin Wolf
    if (ret < 0) {
572 c142442b Kevin Wolf
        return ret;
573 9a476780 Kevin Wolf
    }
574 9a476780 Kevin Wolf
    qcow2_free_clusters(bs, sn.l1_table_offset, sn.l1_size * sizeof(uint64_t));
575 c142442b Kevin Wolf
576 9a476780 Kevin Wolf
    /* must update the copied flag on the current cluster offsets */
577 9a476780 Kevin Wolf
    ret = qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, 0);
578 c142442b Kevin Wolf
    if (ret < 0) {
579 c142442b Kevin Wolf
        return ret;
580 c142442b Kevin Wolf
    }
581 9a476780 Kevin Wolf
582 c142442b Kevin Wolf
#ifdef DEBUG_ALLOC
583 6cbc3031 Philipp Hahn
    {
584 6cbc3031 Philipp Hahn
        BdrvCheckResult result = {0};
585 b35278f7 Stefan Hajnoczi
        qcow2_check_refcounts(bs, &result, 0);
586 6cbc3031 Philipp Hahn
    }
587 c142442b Kevin Wolf
#endif
588 c142442b Kevin Wolf
    return 0;
589 c142442b Kevin Wolf
}
590 c142442b Kevin Wolf
591 ed6ccf0f Kevin Wolf
int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
592 c142442b Kevin Wolf
{
593 c142442b Kevin Wolf
    BDRVQcowState *s = bs->opaque;
594 c142442b Kevin Wolf
    QEMUSnapshotInfo *sn_tab, *sn_info;
595 c142442b Kevin Wolf
    QCowSnapshot *sn;
596 c142442b Kevin Wolf
    int i;
597 c142442b Kevin Wolf
598 c142442b Kevin Wolf
    if (!s->nb_snapshots) {
599 c142442b Kevin Wolf
        *psn_tab = NULL;
600 c142442b Kevin Wolf
        return s->nb_snapshots;
601 c142442b Kevin Wolf
    }
602 c142442b Kevin Wolf
603 7267c094 Anthony Liguori
    sn_tab = g_malloc0(s->nb_snapshots * sizeof(QEMUSnapshotInfo));
604 c142442b Kevin Wolf
    for(i = 0; i < s->nb_snapshots; i++) {
605 c142442b Kevin Wolf
        sn_info = sn_tab + i;
606 c142442b Kevin Wolf
        sn = s->snapshots + i;
607 c142442b Kevin Wolf
        pstrcpy(sn_info->id_str, sizeof(sn_info->id_str),
608 c142442b Kevin Wolf
                sn->id_str);
609 c142442b Kevin Wolf
        pstrcpy(sn_info->name, sizeof(sn_info->name),
610 c142442b Kevin Wolf
                sn->name);
611 c142442b Kevin Wolf
        sn_info->vm_state_size = sn->vm_state_size;
612 c142442b Kevin Wolf
        sn_info->date_sec = sn->date_sec;
613 c142442b Kevin Wolf
        sn_info->date_nsec = sn->date_nsec;
614 c142442b Kevin Wolf
        sn_info->vm_clock_nsec = sn->vm_clock_nsec;
615 c142442b Kevin Wolf
    }
616 c142442b Kevin Wolf
    *psn_tab = sn_tab;
617 c142442b Kevin Wolf
    return s->nb_snapshots;
618 c142442b Kevin Wolf
}
619 c142442b Kevin Wolf
620 51ef6727 edison
int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
621 51ef6727 edison
{
622 e3f652b3 Kevin Wolf
    int i, snapshot_index;
623 51ef6727 edison
    BDRVQcowState *s = bs->opaque;
624 51ef6727 edison
    QCowSnapshot *sn;
625 e3f652b3 Kevin Wolf
    uint64_t *new_l1_table;
626 e3f652b3 Kevin Wolf
    int new_l1_bytes;
627 e3f652b3 Kevin Wolf
    int ret;
628 51ef6727 edison
629 e3f652b3 Kevin Wolf
    assert(bs->read_only);
630 e3f652b3 Kevin Wolf
631 e3f652b3 Kevin Wolf
    /* Search the snapshot */
632 51ef6727 edison
    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_name);
633 51ef6727 edison
    if (snapshot_index < 0) {
634 51ef6727 edison
        return -ENOENT;
635 51ef6727 edison
    }
636 51ef6727 edison
    sn = &s->snapshots[snapshot_index];
637 51ef6727 edison
638 e3f652b3 Kevin Wolf
    /* Allocate and read in the snapshot's L1 table */
639 e3f652b3 Kevin Wolf
    new_l1_bytes = s->l1_size * sizeof(uint64_t);
640 e3f652b3 Kevin Wolf
    new_l1_table = g_malloc0(align_offset(new_l1_bytes, 512));
641 51ef6727 edison
642 e3f652b3 Kevin Wolf
    ret = bdrv_pread(bs->file, sn->l1_table_offset, new_l1_table, new_l1_bytes);
643 e3f652b3 Kevin Wolf
    if (ret < 0) {
644 e3f652b3 Kevin Wolf
        g_free(new_l1_table);
645 e3f652b3 Kevin Wolf
        return ret;
646 51ef6727 edison
    }
647 51ef6727 edison
648 e3f652b3 Kevin Wolf
    /* Switch the L1 table */
649 e3f652b3 Kevin Wolf
    g_free(s->l1_table);
650 e3f652b3 Kevin Wolf
651 e3f652b3 Kevin Wolf
    s->l1_size = sn->l1_size;
652 e3f652b3 Kevin Wolf
    s->l1_table_offset = sn->l1_table_offset;
653 e3f652b3 Kevin Wolf
    s->l1_table = new_l1_table;
654 e3f652b3 Kevin Wolf
655 51ef6727 edison
    for(i = 0;i < s->l1_size; i++) {
656 51ef6727 edison
        be64_to_cpus(&s->l1_table[i]);
657 51ef6727 edison
    }
658 e3f652b3 Kevin Wolf
659 51ef6727 edison
    return 0;
660 51ef6727 edison
}