This patch adds an extra 'annot' field to qcow2 snapshots, and updates serialization functions. Signed-off-by: Jorge Lucángeli Obes --- diff --git a/qemu/block-qcow2.c b/qemu/block-qcow2.c index 0f7a069..361d300 100644 --- a/qemu/block-qcow2.c +++ b/qemu/block-qcow2.c @@ -106,6 +106,8 @@ typedef struct QCowSnapshot { uint32_t l1_size; char *id_str; char *name; + char *annot; + uint32_t vm_state_size; uint32_t date_sec; uint32_t date_nsec; @@ -1370,6 +1372,7 @@ static void qcow_free_snapshots(BlockDriverState *bs) for(i = 0; i < s->nb_snapshots; i++) { qemu_free(s->snapshots[i].name); qemu_free(s->snapshots[i].id_str); + qemu_free(s->snapshots[i].annot); } qemu_free(s->snapshots); s->snapshots = NULL; @@ -1401,12 +1404,18 @@ static int qcow_read_snapshots(BlockDriverState *bs) sn->date_sec = be32_to_cpu(h.date_sec); sn->date_nsec = be32_to_cpu(h.date_nsec); sn->vm_clock_nsec = be64_to_cpu(h.vm_clock_nsec); - extra_data_size = be32_to_cpu(h.extra_data_size); + extra_data_size = be32_to_cpu(h.extra_data_size); id_str_size = be16_to_cpu(h.id_str_size); name_size = be16_to_cpu(h.name_size); + sn->annot = qemu_malloc(extra_data_size + 1); + if (!sn->annot) + goto fail; + if (bdrv_pread(s->hd, offset, sn->annot, extra_data_size) != extra_data_size) + goto fail; offset += extra_data_size; + sn->annot[extra_data_size] = '\0'; sn->id_str = qemu_malloc(id_str_size + 1); if (!sn->id_str) @@ -1439,7 +1448,7 @@ static int qcow_write_snapshots(BlockDriverState *bs) QCowSnapshotHeader h; int i, name_size, id_str_size, snapshots_size; uint64_t data64; - uint32_t data32; + uint32_t data32, extra_data_size; int64_t offset, snapshots_offset; /* compute the size of the snapshots */ @@ -1448,6 +1457,7 @@ static int qcow_write_snapshots(BlockDriverState *bs) sn = s->snapshots + i; offset = align_offset(offset, 8); offset += sizeof(h); + offset += strlen(sn->annot); offset += strlen(sn->id_str); offset += strlen(sn->name); } @@ -1455,7 +1465,7 @@ static int qcow_write_snapshots(BlockDriverState *bs) snapshots_offset = alloc_clusters(bs, snapshots_size); offset = snapshots_offset; - + for(i = 0; i < s->nb_snapshots; i++) { sn = s->snapshots + i; memset(&h, 0, sizeof(h)); @@ -1465,7 +1475,9 @@ static int qcow_write_snapshots(BlockDriverState *bs) h.date_sec = cpu_to_be32(sn->date_sec); h.date_nsec = cpu_to_be32(sn->date_nsec); h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec); - + + extra_data_size = strlen(sn->annot); + h.extra_data_size = cpu_to_be32(extra_data_size); id_str_size = strlen(sn->id_str); name_size = strlen(sn->name); h.id_str_size = cpu_to_be16(id_str_size); @@ -1474,6 +1486,9 @@ static int qcow_write_snapshots(BlockDriverState *bs) if (bdrv_pwrite(s->hd, offset, &h, sizeof(h)) != sizeof(h)) goto fail; offset += sizeof(h); + if (bdrv_pwrite(s->hd, offset, sn->annot, extra_data_size) != extra_data_size) + goto fail; + offset += extra_data_size; if (bdrv_pwrite(s->hd, offset, sn->id_str, id_str_size) != id_str_size) goto fail; offset += id_str_size; @@ -1570,6 +1585,10 @@ static int qcow_snapshot_create(BlockDriverState *bs, sn->name = qemu_strdup(sn_info->name); if (!sn->name) goto fail; + sn->annot = qemu_strdup(sn_info->annot); + if (!sn->annot) + goto fail; + sn->vm_state_size = sn_info->vm_state_size; sn->date_sec = sn_info->date_sec; sn->date_nsec = sn_info->date_nsec; @@ -1680,6 +1699,8 @@ static int qcow_snapshot_delete(BlockDriverState *bs, const char *snapshot_id) qemu_free(sn->id_str); qemu_free(sn->name); + qemu_free(sn->annot); + memmove(sn, sn + 1, (s->nb_snapshots - snapshot_index - 1) * sizeof(*sn)); s->nb_snapshots--; ret = qcow_write_snapshots(bs); @@ -1707,10 +1728,14 @@ static int qcow_snapshot_list(BlockDriverState *bs, for(i = 0; i < s->nb_snapshots; i++) { sn_info = sn_tab + i; sn = s->snapshots + i; + pstrcpy(sn_info->id_str, sizeof(sn_info->id_str), sn->id_str); pstrcpy(sn_info->name, sizeof(sn_info->name), sn->name); + pstrcpy(sn_info->annot, sizeof(sn_info->annot), + sn->annot); + sn_info->vm_state_size = sn->vm_state_size; sn_info->date_sec = sn->date_sec; sn_info->date_nsec = sn->date_nsec; diff --git a/qemu/vl.h b/qemu/vl.h index 43f56bd..f0273fd 100644 --- a/qemu/vl.h +++ b/qemu/vl.h @@ -589,6 +589,7 @@ typedef struct QEMUSnapshotInfo { /* the following fields are informative. They are not needed for the consistency of the snapshot */ char name[256]; /* user choosen name */ + char annot[1024]; /* extra info, will be used to store command-line parameters */ uint32_t vm_state_size; /* VM state info size */ uint32_t date_sec; /* UTC date of the snapshot */ uint32_t date_nsec; @@ -631,6 +632,7 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset, int bdrv_pwrite(BlockDriverState *bs, int64_t offset, const void *buf, int count); int bdrv_truncate(BlockDriverState *bs, int64_t offset); + int64_t bdrv_getlength(BlockDriverState *bs); void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr); int bdrv_commit(BlockDriverState *bs); @@ -714,6 +716,12 @@ void path_combine(char *dest, int dest_size, const char *base_path, const char *filename); +/* annotations */ +int bdrv_snapshot_annotated(QEMUSnapshotInfo *sn_info); +int bdrv_set_annot(BlockDriverState *bs, const char *name, + const char *annotation); +char *bdrv_get_annot(BlockDriverState *bs, const char *name); + #ifndef QEMU_TOOL typedef void QEMUMachineInitFunc(int ram_size, int vga_ram_size,