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/block_int.h"
27#include "block/qcow2.h"
28
29typedef 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
49void qcow2_free_snapshots(BlockDriverState *bs)
50{
51    BDRVQcowState *s = bs->opaque;
52    int i;
53
54    for(i = 0; i < s->nb_snapshots; i++) {
55        g_free(s->snapshots[i].name);
56        g_free(s->snapshots[i].id_str);
57    }
58    g_free(s->snapshots);
59    s->snapshots = NULL;
60    s->nb_snapshots = 0;
61}
62
63int qcow2_read_snapshots(BlockDriverState *bs)
64{
65    BDRVQcowState *s = bs->opaque;
66    QCowSnapshotHeader h;
67    QCowSnapshot *sn;
68    int i, id_str_size, name_size;
69    int64_t offset;
70    uint32_t extra_data_size;
71
72    if (!s->nb_snapshots) {
73        s->snapshots = NULL;
74        s->snapshots_size = 0;
75        return 0;
76    }
77
78    offset = s->snapshots_offset;
79    s->snapshots = g_malloc0(s->nb_snapshots * sizeof(QCowSnapshot));
80    for(i = 0; i < s->nb_snapshots; i++) {
81        offset = align_offset(offset, 8);
82        if (bdrv_pread(bs->file, offset, &h, sizeof(h)) != sizeof(h))
83            goto fail;
84        offset += sizeof(h);
85        sn = s->snapshots + i;
86        sn->l1_table_offset = be64_to_cpu(h.l1_table_offset);
87        sn->l1_size = be32_to_cpu(h.l1_size);
88        sn->vm_state_size = be32_to_cpu(h.vm_state_size);
89        sn->date_sec = be32_to_cpu(h.date_sec);
90        sn->date_nsec = be32_to_cpu(h.date_nsec);
91        sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec);
92        extra_data_size = be32_to_cpu(h.extra_data_size);
93
94        id_str_size = be16_to_cpu(h.id_str_size);
95        name_size = be16_to_cpu(h.name_size);
96
97        offset += extra_data_size;
98
99        sn->id_str = g_malloc(id_str_size + 1);
100        if (bdrv_pread(bs->file, offset, sn->id_str, id_str_size) != id_str_size)
101            goto fail;
102        offset += id_str_size;
103        sn->id_str[id_str_size] = '\0';
104
105        sn->name = g_malloc(name_size + 1);
106        if (bdrv_pread(bs->file, offset, sn->name, name_size) != name_size)
107            goto fail;
108        offset += name_size;
109        sn->name[name_size] = '\0';
110    }
111    s->snapshots_size = offset - s->snapshots_offset;
112    return 0;
113 fail:
114    qcow2_free_snapshots(bs);
115    return -1;
116}
117
118/* add at the end of the file a new list of snapshots */
119static 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
191static 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
207static 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
219static 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 */
235int 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 = g_strdup(sn_info->id_str);
255    if (!sn->id_str)
256        goto fail;
257    sn->name = g_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 = g_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    g_free(l1_table);
291    l1_table = NULL;
292
293    snapshots1 = g_malloc((s->nb_snapshots + 1) * sizeof(QCowSnapshot));
294    if (s->snapshots) {
295        memcpy(snapshots1, s->snapshots, s->nb_snapshots * sizeof(QCowSnapshot));
296        g_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    g_free(sn->name);
309    g_free(l1_table);
310    return -1;
311}
312
313/* copy the snapshot 'snapshot_name' into the current disk image */
314int 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
355int 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    g_free(sn->id_str);
376    g_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
390int 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 = g_malloc0(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