1f364ec65SWenchao Xia /* 2f364ec65SWenchao Xia * Block layer qmp and info dump related functions 3f364ec65SWenchao Xia * 4f364ec65SWenchao Xia * Copyright (c) 2003-2008 Fabrice Bellard 5f364ec65SWenchao Xia * 6f364ec65SWenchao Xia * Permission is hereby granted, free of charge, to any person obtaining a copy 7f364ec65SWenchao Xia * of this software and associated documentation files (the "Software"), to deal 8f364ec65SWenchao Xia * in the Software without restriction, including without limitation the rights 9f364ec65SWenchao Xia * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10f364ec65SWenchao Xia * copies of the Software, and to permit persons to whom the Software is 11f364ec65SWenchao Xia * furnished to do so, subject to the following conditions: 12f364ec65SWenchao Xia * 13f364ec65SWenchao Xia * The above copyright notice and this permission notice shall be included in 14f364ec65SWenchao Xia * all copies or substantial portions of the Software. 15f364ec65SWenchao Xia * 16f364ec65SWenchao Xia * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17f364ec65SWenchao Xia * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18f364ec65SWenchao Xia * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19f364ec65SWenchao Xia * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20f364ec65SWenchao Xia * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21f364ec65SWenchao Xia * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22f364ec65SWenchao Xia * THE SOFTWARE. 23f364ec65SWenchao Xia */ 24f364ec65SWenchao Xia 25f364ec65SWenchao Xia #include "block/qapi.h" 26f364ec65SWenchao Xia #include "block/block_int.h" 27f364ec65SWenchao Xia #include "qmp-commands.h" 28f364ec65SWenchao Xia 29*fb0ed453SWenchao Xia /* 30*fb0ed453SWenchao Xia * Returns 0 on success, with *p_list either set to describe snapshot 31*fb0ed453SWenchao Xia * information, or NULL because there are no snapshots. Returns -errno on 32*fb0ed453SWenchao Xia * error, with *p_list untouched. 33*fb0ed453SWenchao Xia */ 34*fb0ed453SWenchao Xia int bdrv_query_snapshot_info_list(BlockDriverState *bs, 35*fb0ed453SWenchao Xia SnapshotInfoList **p_list, 36*fb0ed453SWenchao Xia Error **errp) 37f364ec65SWenchao Xia { 38f364ec65SWenchao Xia int i, sn_count; 39f364ec65SWenchao Xia QEMUSnapshotInfo *sn_tab = NULL; 40*fb0ed453SWenchao Xia SnapshotInfoList *info_list, *cur_item = NULL, *head = NULL; 41*fb0ed453SWenchao Xia SnapshotInfo *info; 42*fb0ed453SWenchao Xia 43f364ec65SWenchao Xia sn_count = bdrv_snapshot_list(bs, &sn_tab); 44*fb0ed453SWenchao Xia if (sn_count < 0) { 45*fb0ed453SWenchao Xia const char *dev = bdrv_get_device_name(bs); 46*fb0ed453SWenchao Xia switch (sn_count) { 47*fb0ed453SWenchao Xia case -ENOMEDIUM: 48*fb0ed453SWenchao Xia error_setg(errp, "Device '%s' is not inserted", dev); 49*fb0ed453SWenchao Xia break; 50*fb0ed453SWenchao Xia case -ENOTSUP: 51*fb0ed453SWenchao Xia error_setg(errp, 52*fb0ed453SWenchao Xia "Device '%s' does not support internal snapshots", 53*fb0ed453SWenchao Xia dev); 54*fb0ed453SWenchao Xia break; 55*fb0ed453SWenchao Xia default: 56*fb0ed453SWenchao Xia error_setg_errno(errp, -sn_count, 57*fb0ed453SWenchao Xia "Can't list snapshots of device '%s'", dev); 58*fb0ed453SWenchao Xia break; 59*fb0ed453SWenchao Xia } 60*fb0ed453SWenchao Xia return sn_count; 61*fb0ed453SWenchao Xia } 62f364ec65SWenchao Xia 63f364ec65SWenchao Xia for (i = 0; i < sn_count; i++) { 64*fb0ed453SWenchao Xia info = g_new0(SnapshotInfo, 1); 65*fb0ed453SWenchao Xia info->id = g_strdup(sn_tab[i].id_str); 66*fb0ed453SWenchao Xia info->name = g_strdup(sn_tab[i].name); 67*fb0ed453SWenchao Xia info->vm_state_size = sn_tab[i].vm_state_size; 68*fb0ed453SWenchao Xia info->date_sec = sn_tab[i].date_sec; 69*fb0ed453SWenchao Xia info->date_nsec = sn_tab[i].date_nsec; 70*fb0ed453SWenchao Xia info->vm_clock_sec = sn_tab[i].vm_clock_nsec / 1000000000; 71*fb0ed453SWenchao Xia info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000; 72f364ec65SWenchao Xia 73*fb0ed453SWenchao Xia info_list = g_new0(SnapshotInfoList, 1); 74*fb0ed453SWenchao Xia info_list->value = info; 75f364ec65SWenchao Xia 76f364ec65SWenchao Xia /* XXX: waiting for the qapi to support qemu-queue.h types */ 77f364ec65SWenchao Xia if (!cur_item) { 78*fb0ed453SWenchao Xia head = cur_item = info_list; 79f364ec65SWenchao Xia } else { 80f364ec65SWenchao Xia cur_item->next = info_list; 81f364ec65SWenchao Xia cur_item = info_list; 82f364ec65SWenchao Xia } 83f364ec65SWenchao Xia 84f364ec65SWenchao Xia } 85f364ec65SWenchao Xia 86f364ec65SWenchao Xia g_free(sn_tab); 87*fb0ed453SWenchao Xia *p_list = head; 88*fb0ed453SWenchao Xia return 0; 89f364ec65SWenchao Xia } 90f364ec65SWenchao Xia 91f364ec65SWenchao Xia void bdrv_collect_image_info(BlockDriverState *bs, 92f364ec65SWenchao Xia ImageInfo *info, 93f364ec65SWenchao Xia const char *filename) 94f364ec65SWenchao Xia { 95f364ec65SWenchao Xia uint64_t total_sectors; 96f364ec65SWenchao Xia char backing_filename[1024]; 97f364ec65SWenchao Xia char backing_filename2[1024]; 98f364ec65SWenchao Xia BlockDriverInfo bdi; 99f364ec65SWenchao Xia 100f364ec65SWenchao Xia bdrv_get_geometry(bs, &total_sectors); 101f364ec65SWenchao Xia 102f364ec65SWenchao Xia info->filename = g_strdup(filename); 103f364ec65SWenchao Xia info->format = g_strdup(bdrv_get_format_name(bs)); 104f364ec65SWenchao Xia info->virtual_size = total_sectors * 512; 105f364ec65SWenchao Xia info->actual_size = bdrv_get_allocated_file_size(bs); 106f364ec65SWenchao Xia info->has_actual_size = info->actual_size >= 0; 107f364ec65SWenchao Xia if (bdrv_is_encrypted(bs)) { 108f364ec65SWenchao Xia info->encrypted = true; 109f364ec65SWenchao Xia info->has_encrypted = true; 110f364ec65SWenchao Xia } 111f364ec65SWenchao Xia if (bdrv_get_info(bs, &bdi) >= 0) { 112f364ec65SWenchao Xia if (bdi.cluster_size != 0) { 113f364ec65SWenchao Xia info->cluster_size = bdi.cluster_size; 114f364ec65SWenchao Xia info->has_cluster_size = true; 115f364ec65SWenchao Xia } 116f364ec65SWenchao Xia info->dirty_flag = bdi.is_dirty; 117f364ec65SWenchao Xia info->has_dirty_flag = true; 118f364ec65SWenchao Xia } 119f364ec65SWenchao Xia bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename)); 120f364ec65SWenchao Xia if (backing_filename[0] != '\0') { 121f364ec65SWenchao Xia info->backing_filename = g_strdup(backing_filename); 122f364ec65SWenchao Xia info->has_backing_filename = true; 123f364ec65SWenchao Xia bdrv_get_full_backing_filename(bs, backing_filename2, 124f364ec65SWenchao Xia sizeof(backing_filename2)); 125f364ec65SWenchao Xia 126f364ec65SWenchao Xia if (strcmp(backing_filename, backing_filename2) != 0) { 127f364ec65SWenchao Xia info->full_backing_filename = 128f364ec65SWenchao Xia g_strdup(backing_filename2); 129f364ec65SWenchao Xia info->has_full_backing_filename = true; 130f364ec65SWenchao Xia } 131f364ec65SWenchao Xia 132f364ec65SWenchao Xia if (bs->backing_format[0]) { 133f364ec65SWenchao Xia info->backing_filename_format = g_strdup(bs->backing_format); 134f364ec65SWenchao Xia info->has_backing_filename_format = true; 135f364ec65SWenchao Xia } 136f364ec65SWenchao Xia } 137f364ec65SWenchao Xia } 138f364ec65SWenchao Xia 139f364ec65SWenchao Xia BlockInfo *bdrv_query_info(BlockDriverState *bs) 140f364ec65SWenchao Xia { 141f364ec65SWenchao Xia BlockInfo *info = g_malloc0(sizeof(*info)); 142f364ec65SWenchao Xia info->device = g_strdup(bs->device_name); 143f364ec65SWenchao Xia info->type = g_strdup("unknown"); 144f364ec65SWenchao Xia info->locked = bdrv_dev_is_medium_locked(bs); 145f364ec65SWenchao Xia info->removable = bdrv_dev_has_removable_media(bs); 146f364ec65SWenchao Xia 147f364ec65SWenchao Xia if (bdrv_dev_has_removable_media(bs)) { 148f364ec65SWenchao Xia info->has_tray_open = true; 149f364ec65SWenchao Xia info->tray_open = bdrv_dev_is_tray_open(bs); 150f364ec65SWenchao Xia } 151f364ec65SWenchao Xia 152f364ec65SWenchao Xia if (bdrv_iostatus_is_enabled(bs)) { 153f364ec65SWenchao Xia info->has_io_status = true; 154f364ec65SWenchao Xia info->io_status = bs->iostatus; 155f364ec65SWenchao Xia } 156f364ec65SWenchao Xia 157f364ec65SWenchao Xia if (bs->dirty_bitmap) { 158f364ec65SWenchao Xia info->has_dirty = true; 159f364ec65SWenchao Xia info->dirty = g_malloc0(sizeof(*info->dirty)); 160f364ec65SWenchao Xia info->dirty->count = bdrv_get_dirty_count(bs) * BDRV_SECTOR_SIZE; 161f364ec65SWenchao Xia info->dirty->granularity = 162f364ec65SWenchao Xia ((int64_t) BDRV_SECTOR_SIZE << hbitmap_granularity(bs->dirty_bitmap)); 163f364ec65SWenchao Xia } 164f364ec65SWenchao Xia 165f364ec65SWenchao Xia if (bs->drv) { 166f364ec65SWenchao Xia info->has_inserted = true; 167f364ec65SWenchao Xia info->inserted = g_malloc0(sizeof(*info->inserted)); 168f364ec65SWenchao Xia info->inserted->file = g_strdup(bs->filename); 169f364ec65SWenchao Xia info->inserted->ro = bs->read_only; 170f364ec65SWenchao Xia info->inserted->drv = g_strdup(bs->drv->format_name); 171f364ec65SWenchao Xia info->inserted->encrypted = bs->encrypted; 172f364ec65SWenchao Xia info->inserted->encryption_key_missing = bdrv_key_required(bs); 173f364ec65SWenchao Xia 174f364ec65SWenchao Xia if (bs->backing_file[0]) { 175f364ec65SWenchao Xia info->inserted->has_backing_file = true; 176f364ec65SWenchao Xia info->inserted->backing_file = g_strdup(bs->backing_file); 177f364ec65SWenchao Xia } 178f364ec65SWenchao Xia 179f364ec65SWenchao Xia info->inserted->backing_file_depth = bdrv_get_backing_file_depth(bs); 180f364ec65SWenchao Xia 181f364ec65SWenchao Xia if (bs->io_limits_enabled) { 182f364ec65SWenchao Xia info->inserted->bps = 183f364ec65SWenchao Xia bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL]; 184f364ec65SWenchao Xia info->inserted->bps_rd = 185f364ec65SWenchao Xia bs->io_limits.bps[BLOCK_IO_LIMIT_READ]; 186f364ec65SWenchao Xia info->inserted->bps_wr = 187f364ec65SWenchao Xia bs->io_limits.bps[BLOCK_IO_LIMIT_WRITE]; 188f364ec65SWenchao Xia info->inserted->iops = 189f364ec65SWenchao Xia bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]; 190f364ec65SWenchao Xia info->inserted->iops_rd = 191f364ec65SWenchao Xia bs->io_limits.iops[BLOCK_IO_LIMIT_READ]; 192f364ec65SWenchao Xia info->inserted->iops_wr = 193f364ec65SWenchao Xia bs->io_limits.iops[BLOCK_IO_LIMIT_WRITE]; 194f364ec65SWenchao Xia } 195f364ec65SWenchao Xia } 196f364ec65SWenchao Xia return info; 197f364ec65SWenchao Xia } 198f364ec65SWenchao Xia 199f364ec65SWenchao Xia BlockStats *bdrv_query_stats(const BlockDriverState *bs) 200f364ec65SWenchao Xia { 201f364ec65SWenchao Xia BlockStats *s; 202f364ec65SWenchao Xia 203f364ec65SWenchao Xia s = g_malloc0(sizeof(*s)); 204f364ec65SWenchao Xia 205f364ec65SWenchao Xia if (bs->device_name[0]) { 206f364ec65SWenchao Xia s->has_device = true; 207f364ec65SWenchao Xia s->device = g_strdup(bs->device_name); 208f364ec65SWenchao Xia } 209f364ec65SWenchao Xia 210f364ec65SWenchao Xia s->stats = g_malloc0(sizeof(*s->stats)); 211f364ec65SWenchao Xia s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ]; 212f364ec65SWenchao Xia s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE]; 213f364ec65SWenchao Xia s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ]; 214f364ec65SWenchao Xia s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE]; 215f364ec65SWenchao Xia s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE; 216f364ec65SWenchao Xia s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH]; 217f364ec65SWenchao Xia s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE]; 218f364ec65SWenchao Xia s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ]; 219f364ec65SWenchao Xia s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH]; 220f364ec65SWenchao Xia 221f364ec65SWenchao Xia if (bs->file) { 222f364ec65SWenchao Xia s->has_parent = true; 223f364ec65SWenchao Xia s->parent = bdrv_query_stats(bs->file); 224f364ec65SWenchao Xia } 225f364ec65SWenchao Xia 226f364ec65SWenchao Xia return s; 227f364ec65SWenchao Xia } 228f364ec65SWenchao Xia 229f364ec65SWenchao Xia BlockInfoList *qmp_query_block(Error **errp) 230f364ec65SWenchao Xia { 231f364ec65SWenchao Xia BlockInfoList *head = NULL, **p_next = &head; 232f364ec65SWenchao Xia BlockDriverState *bs = NULL; 233f364ec65SWenchao Xia 234f364ec65SWenchao Xia while ((bs = bdrv_next(bs))) { 235f364ec65SWenchao Xia BlockInfoList *info = g_malloc0(sizeof(*info)); 236f364ec65SWenchao Xia info->value = bdrv_query_info(bs); 237f364ec65SWenchao Xia 238f364ec65SWenchao Xia *p_next = info; 239f364ec65SWenchao Xia p_next = &info->next; 240f364ec65SWenchao Xia } 241f364ec65SWenchao Xia 242f364ec65SWenchao Xia return head; 243f364ec65SWenchao Xia } 244f364ec65SWenchao Xia 245f364ec65SWenchao Xia BlockStatsList *qmp_query_blockstats(Error **errp) 246f364ec65SWenchao Xia { 247f364ec65SWenchao Xia BlockStatsList *head = NULL, **p_next = &head; 248f364ec65SWenchao Xia BlockDriverState *bs = NULL; 249f364ec65SWenchao Xia 250f364ec65SWenchao Xia while ((bs = bdrv_next(bs))) { 251f364ec65SWenchao Xia BlockStatsList *info = g_malloc0(sizeof(*info)); 252f364ec65SWenchao Xia info->value = bdrv_query_stats(bs); 253f364ec65SWenchao Xia 254f364ec65SWenchao Xia *p_next = info; 255f364ec65SWenchao Xia p_next = &info->next; 256f364ec65SWenchao Xia } 257f364ec65SWenchao Xia 258f364ec65SWenchao Xia return head; 259f364ec65SWenchao Xia } 260f364ec65SWenchao Xia 261f364ec65SWenchao Xia #define NB_SUFFIXES 4 262f364ec65SWenchao Xia 263f364ec65SWenchao Xia static char *get_human_readable_size(char *buf, int buf_size, int64_t size) 264f364ec65SWenchao Xia { 265f364ec65SWenchao Xia static const char suffixes[NB_SUFFIXES] = "KMGT"; 266f364ec65SWenchao Xia int64_t base; 267f364ec65SWenchao Xia int i; 268f364ec65SWenchao Xia 269f364ec65SWenchao Xia if (size <= 999) { 270f364ec65SWenchao Xia snprintf(buf, buf_size, "%" PRId64, size); 271f364ec65SWenchao Xia } else { 272f364ec65SWenchao Xia base = 1024; 273f364ec65SWenchao Xia for (i = 0; i < NB_SUFFIXES; i++) { 274f364ec65SWenchao Xia if (size < (10 * base)) { 275f364ec65SWenchao Xia snprintf(buf, buf_size, "%0.1f%c", 276f364ec65SWenchao Xia (double)size / base, 277f364ec65SWenchao Xia suffixes[i]); 278f364ec65SWenchao Xia break; 279f364ec65SWenchao Xia } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 280f364ec65SWenchao Xia snprintf(buf, buf_size, "%" PRId64 "%c", 281f364ec65SWenchao Xia ((size + (base >> 1)) / base), 282f364ec65SWenchao Xia suffixes[i]); 283f364ec65SWenchao Xia break; 284f364ec65SWenchao Xia } 285f364ec65SWenchao Xia base = base * 1024; 286f364ec65SWenchao Xia } 287f364ec65SWenchao Xia } 288f364ec65SWenchao Xia return buf; 289f364ec65SWenchao Xia } 290f364ec65SWenchao Xia 2915b917044SWenchao Xia void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f, 2925b917044SWenchao Xia QEMUSnapshotInfo *sn) 293f364ec65SWenchao Xia { 294f364ec65SWenchao Xia char buf1[128], date_buf[128], clock_buf[128]; 295f364ec65SWenchao Xia struct tm tm; 296f364ec65SWenchao Xia time_t ti; 297f364ec65SWenchao Xia int64_t secs; 298f364ec65SWenchao Xia 299f364ec65SWenchao Xia if (!sn) { 3005b917044SWenchao Xia func_fprintf(f, 301f364ec65SWenchao Xia "%-10s%-20s%7s%20s%15s", 302f364ec65SWenchao Xia "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 303f364ec65SWenchao Xia } else { 304f364ec65SWenchao Xia ti = sn->date_sec; 305f364ec65SWenchao Xia localtime_r(&ti, &tm); 306f364ec65SWenchao Xia strftime(date_buf, sizeof(date_buf), 307f364ec65SWenchao Xia "%Y-%m-%d %H:%M:%S", &tm); 308f364ec65SWenchao Xia secs = sn->vm_clock_nsec / 1000000000; 309f364ec65SWenchao Xia snprintf(clock_buf, sizeof(clock_buf), 310f364ec65SWenchao Xia "%02d:%02d:%02d.%03d", 311f364ec65SWenchao Xia (int)(secs / 3600), 312f364ec65SWenchao Xia (int)((secs / 60) % 60), 313f364ec65SWenchao Xia (int)(secs % 60), 314f364ec65SWenchao Xia (int)((sn->vm_clock_nsec / 1000000) % 1000)); 3155b917044SWenchao Xia func_fprintf(f, 316f364ec65SWenchao Xia "%-10s%-20s%7s%20s%15s", 317f364ec65SWenchao Xia sn->id_str, sn->name, 3185b917044SWenchao Xia get_human_readable_size(buf1, sizeof(buf1), 3195b917044SWenchao Xia sn->vm_state_size), 320f364ec65SWenchao Xia date_buf, 321f364ec65SWenchao Xia clock_buf); 322f364ec65SWenchao Xia } 323f364ec65SWenchao Xia } 324f364ec65SWenchao Xia 3255b917044SWenchao Xia void bdrv_image_info_dump(fprintf_function func_fprintf, void *f, 3265b917044SWenchao Xia ImageInfo *info) 327f364ec65SWenchao Xia { 328f364ec65SWenchao Xia char size_buf[128], dsize_buf[128]; 329f364ec65SWenchao Xia if (!info->has_actual_size) { 330f364ec65SWenchao Xia snprintf(dsize_buf, sizeof(dsize_buf), "unavailable"); 331f364ec65SWenchao Xia } else { 332f364ec65SWenchao Xia get_human_readable_size(dsize_buf, sizeof(dsize_buf), 333f364ec65SWenchao Xia info->actual_size); 334f364ec65SWenchao Xia } 335f364ec65SWenchao Xia get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size); 3365b917044SWenchao Xia func_fprintf(f, 3375b917044SWenchao Xia "image: %s\n" 338f364ec65SWenchao Xia "file format: %s\n" 339f364ec65SWenchao Xia "virtual size: %s (%" PRId64 " bytes)\n" 340f364ec65SWenchao Xia "disk size: %s\n", 341f364ec65SWenchao Xia info->filename, info->format, size_buf, 342f364ec65SWenchao Xia info->virtual_size, 343f364ec65SWenchao Xia dsize_buf); 344f364ec65SWenchao Xia 345f364ec65SWenchao Xia if (info->has_encrypted && info->encrypted) { 3465b917044SWenchao Xia func_fprintf(f, "encrypted: yes\n"); 347f364ec65SWenchao Xia } 348f364ec65SWenchao Xia 349f364ec65SWenchao Xia if (info->has_cluster_size) { 3505b917044SWenchao Xia func_fprintf(f, "cluster_size: %" PRId64 "\n", 3515b917044SWenchao Xia info->cluster_size); 352f364ec65SWenchao Xia } 353f364ec65SWenchao Xia 354f364ec65SWenchao Xia if (info->has_dirty_flag && info->dirty_flag) { 3555b917044SWenchao Xia func_fprintf(f, "cleanly shut down: no\n"); 356f364ec65SWenchao Xia } 357f364ec65SWenchao Xia 358f364ec65SWenchao Xia if (info->has_backing_filename) { 3595b917044SWenchao Xia func_fprintf(f, "backing file: %s", info->backing_filename); 360f364ec65SWenchao Xia if (info->has_full_backing_filename) { 3615b917044SWenchao Xia func_fprintf(f, " (actual path: %s)", info->full_backing_filename); 362f364ec65SWenchao Xia } 3635b917044SWenchao Xia func_fprintf(f, "\n"); 364f364ec65SWenchao Xia if (info->has_backing_filename_format) { 3655b917044SWenchao Xia func_fprintf(f, "backing file format: %s\n", 3665b917044SWenchao Xia info->backing_filename_format); 367f364ec65SWenchao Xia } 368f364ec65SWenchao Xia } 369f364ec65SWenchao Xia 370f364ec65SWenchao Xia if (info->has_snapshots) { 371f364ec65SWenchao Xia SnapshotInfoList *elem; 372f364ec65SWenchao Xia 3735b917044SWenchao Xia func_fprintf(f, "Snapshot list:\n"); 3745b917044SWenchao Xia bdrv_snapshot_dump(func_fprintf, f, NULL); 3755b917044SWenchao Xia func_fprintf(f, "\n"); 376f364ec65SWenchao Xia 377f364ec65SWenchao Xia /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but 378f364ec65SWenchao Xia * we convert to the block layer's native QEMUSnapshotInfo for now. 379f364ec65SWenchao Xia */ 380f364ec65SWenchao Xia for (elem = info->snapshots; elem; elem = elem->next) { 381f364ec65SWenchao Xia QEMUSnapshotInfo sn = { 382f364ec65SWenchao Xia .vm_state_size = elem->value->vm_state_size, 383f364ec65SWenchao Xia .date_sec = elem->value->date_sec, 384f364ec65SWenchao Xia .date_nsec = elem->value->date_nsec, 385f364ec65SWenchao Xia .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL + 386f364ec65SWenchao Xia elem->value->vm_clock_nsec, 387f364ec65SWenchao Xia }; 388f364ec65SWenchao Xia 389f364ec65SWenchao Xia pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id); 390f364ec65SWenchao Xia pstrcpy(sn.name, sizeof(sn.name), elem->value->name); 3915b917044SWenchao Xia bdrv_snapshot_dump(func_fprintf, f, &sn); 3925b917044SWenchao Xia func_fprintf(f, "\n"); 393f364ec65SWenchao Xia } 394f364ec65SWenchao Xia } 395f364ec65SWenchao Xia } 396