Statistics
| Branch: | Revision:

root / block / qcow2-snapshot.c @ 2a2af967

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