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 29fb0ed453SWenchao Xia /* 30fb0ed453SWenchao Xia * Returns 0 on success, with *p_list either set to describe snapshot 31fb0ed453SWenchao Xia * information, or NULL because there are no snapshots. Returns -errno on 32fb0ed453SWenchao Xia * error, with *p_list untouched. 33fb0ed453SWenchao Xia */ 34fb0ed453SWenchao Xia int bdrv_query_snapshot_info_list(BlockDriverState *bs, 35fb0ed453SWenchao Xia SnapshotInfoList **p_list, 36fb0ed453SWenchao Xia Error **errp) 37f364ec65SWenchao Xia { 38f364ec65SWenchao Xia int i, sn_count; 39f364ec65SWenchao Xia QEMUSnapshotInfo *sn_tab = NULL; 40fb0ed453SWenchao Xia SnapshotInfoList *info_list, *cur_item = NULL, *head = NULL; 41fb0ed453SWenchao Xia SnapshotInfo *info; 42fb0ed453SWenchao Xia 43f364ec65SWenchao Xia sn_count = bdrv_snapshot_list(bs, &sn_tab); 44fb0ed453SWenchao Xia if (sn_count < 0) { 45fb0ed453SWenchao Xia const char *dev = bdrv_get_device_name(bs); 46fb0ed453SWenchao Xia switch (sn_count) { 47fb0ed453SWenchao Xia case -ENOMEDIUM: 48fb0ed453SWenchao Xia error_setg(errp, "Device '%s' is not inserted", dev); 49fb0ed453SWenchao Xia break; 50fb0ed453SWenchao Xia case -ENOTSUP: 51fb0ed453SWenchao Xia error_setg(errp, 52fb0ed453SWenchao Xia "Device '%s' does not support internal snapshots", 53fb0ed453SWenchao Xia dev); 54fb0ed453SWenchao Xia break; 55fb0ed453SWenchao Xia default: 56fb0ed453SWenchao Xia error_setg_errno(errp, -sn_count, 57fb0ed453SWenchao Xia "Can't list snapshots of device '%s'", dev); 58fb0ed453SWenchao Xia break; 59fb0ed453SWenchao Xia } 60fb0ed453SWenchao Xia return sn_count; 61fb0ed453SWenchao Xia } 62f364ec65SWenchao Xia 63f364ec65SWenchao Xia for (i = 0; i < sn_count; i++) { 64fb0ed453SWenchao Xia info = g_new0(SnapshotInfo, 1); 65fb0ed453SWenchao Xia info->id = g_strdup(sn_tab[i].id_str); 66fb0ed453SWenchao Xia info->name = g_strdup(sn_tab[i].name); 67fb0ed453SWenchao Xia info->vm_state_size = sn_tab[i].vm_state_size; 68fb0ed453SWenchao Xia info->date_sec = sn_tab[i].date_sec; 69fb0ed453SWenchao Xia info->date_nsec = sn_tab[i].date_nsec; 70fb0ed453SWenchao Xia info->vm_clock_sec = sn_tab[i].vm_clock_nsec / 1000000000; 71fb0ed453SWenchao Xia info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000; 72f364ec65SWenchao Xia 73fb0ed453SWenchao Xia info_list = g_new0(SnapshotInfoList, 1); 74fb0ed453SWenchao 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) { 78fb0ed453SWenchao 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); 87fb0ed453SWenchao Xia *p_list = head; 88fb0ed453SWenchao Xia return 0; 89f364ec65SWenchao Xia } 90f364ec65SWenchao Xia 91*43526ec8SWenchao Xia /** 92*43526ec8SWenchao Xia * bdrv_query_image_info: 93*43526ec8SWenchao Xia * @bs: block device to examine 94*43526ec8SWenchao Xia * @p_info: location to store image information 95*43526ec8SWenchao Xia * @errp: location to store error information 96*43526ec8SWenchao Xia * 97*43526ec8SWenchao Xia * @p_info will be set only on success. On error, store error in @errp. 98*43526ec8SWenchao Xia */ 99*43526ec8SWenchao Xia void bdrv_query_image_info(BlockDriverState *bs, 100*43526ec8SWenchao Xia ImageInfo **p_info, 101*43526ec8SWenchao Xia Error **errp) 102f364ec65SWenchao Xia { 103f364ec65SWenchao Xia uint64_t total_sectors; 104*43526ec8SWenchao Xia const char *backing_filename; 105f364ec65SWenchao Xia char backing_filename2[1024]; 106f364ec65SWenchao Xia BlockDriverInfo bdi; 107*43526ec8SWenchao Xia int ret; 108*43526ec8SWenchao Xia Error *err = NULL; 109*43526ec8SWenchao Xia ImageInfo *info = g_new0(ImageInfo, 1); 110f364ec65SWenchao Xia 111f364ec65SWenchao Xia bdrv_get_geometry(bs, &total_sectors); 112f364ec65SWenchao Xia 113*43526ec8SWenchao Xia info->filename = g_strdup(bs->filename); 114f364ec65SWenchao Xia info->format = g_strdup(bdrv_get_format_name(bs)); 115f364ec65SWenchao Xia info->virtual_size = total_sectors * 512; 116f364ec65SWenchao Xia info->actual_size = bdrv_get_allocated_file_size(bs); 117f364ec65SWenchao Xia info->has_actual_size = info->actual_size >= 0; 118f364ec65SWenchao Xia if (bdrv_is_encrypted(bs)) { 119f364ec65SWenchao Xia info->encrypted = true; 120f364ec65SWenchao Xia info->has_encrypted = true; 121f364ec65SWenchao Xia } 122f364ec65SWenchao Xia if (bdrv_get_info(bs, &bdi) >= 0) { 123f364ec65SWenchao Xia if (bdi.cluster_size != 0) { 124f364ec65SWenchao Xia info->cluster_size = bdi.cluster_size; 125f364ec65SWenchao Xia info->has_cluster_size = true; 126f364ec65SWenchao Xia } 127f364ec65SWenchao Xia info->dirty_flag = bdi.is_dirty; 128f364ec65SWenchao Xia info->has_dirty_flag = true; 129f364ec65SWenchao Xia } 130*43526ec8SWenchao Xia backing_filename = bs->backing_file; 131f364ec65SWenchao Xia if (backing_filename[0] != '\0') { 132f364ec65SWenchao Xia info->backing_filename = g_strdup(backing_filename); 133f364ec65SWenchao Xia info->has_backing_filename = true; 134f364ec65SWenchao Xia bdrv_get_full_backing_filename(bs, backing_filename2, 135f364ec65SWenchao Xia sizeof(backing_filename2)); 136f364ec65SWenchao Xia 137f364ec65SWenchao Xia if (strcmp(backing_filename, backing_filename2) != 0) { 138f364ec65SWenchao Xia info->full_backing_filename = 139f364ec65SWenchao Xia g_strdup(backing_filename2); 140f364ec65SWenchao Xia info->has_full_backing_filename = true; 141f364ec65SWenchao Xia } 142f364ec65SWenchao Xia 143f364ec65SWenchao Xia if (bs->backing_format[0]) { 144f364ec65SWenchao Xia info->backing_filename_format = g_strdup(bs->backing_format); 145f364ec65SWenchao Xia info->has_backing_filename_format = true; 146f364ec65SWenchao Xia } 147f364ec65SWenchao Xia } 148*43526ec8SWenchao Xia 149*43526ec8SWenchao Xia ret = bdrv_query_snapshot_info_list(bs, &info->snapshots, &err); 150*43526ec8SWenchao Xia switch (ret) { 151*43526ec8SWenchao Xia case 0: 152*43526ec8SWenchao Xia if (info->snapshots) { 153*43526ec8SWenchao Xia info->has_snapshots = true; 154*43526ec8SWenchao Xia } 155*43526ec8SWenchao Xia break; 156*43526ec8SWenchao Xia /* recoverable error */ 157*43526ec8SWenchao Xia case -ENOMEDIUM: 158*43526ec8SWenchao Xia case -ENOTSUP: 159*43526ec8SWenchao Xia error_free(err); 160*43526ec8SWenchao Xia break; 161*43526ec8SWenchao Xia default: 162*43526ec8SWenchao Xia error_propagate(errp, err); 163*43526ec8SWenchao Xia qapi_free_ImageInfo(info); 164*43526ec8SWenchao Xia return; 165*43526ec8SWenchao Xia } 166*43526ec8SWenchao Xia 167*43526ec8SWenchao Xia *p_info = info; 168f364ec65SWenchao Xia } 169f364ec65SWenchao Xia 170f364ec65SWenchao Xia BlockInfo *bdrv_query_info(BlockDriverState *bs) 171f364ec65SWenchao Xia { 172f364ec65SWenchao Xia BlockInfo *info = g_malloc0(sizeof(*info)); 173f364ec65SWenchao Xia info->device = g_strdup(bs->device_name); 174f364ec65SWenchao Xia info->type = g_strdup("unknown"); 175f364ec65SWenchao Xia info->locked = bdrv_dev_is_medium_locked(bs); 176f364ec65SWenchao Xia info->removable = bdrv_dev_has_removable_media(bs); 177f364ec65SWenchao Xia 178f364ec65SWenchao Xia if (bdrv_dev_has_removable_media(bs)) { 179f364ec65SWenchao Xia info->has_tray_open = true; 180f364ec65SWenchao Xia info->tray_open = bdrv_dev_is_tray_open(bs); 181f364ec65SWenchao Xia } 182f364ec65SWenchao Xia 183f364ec65SWenchao Xia if (bdrv_iostatus_is_enabled(bs)) { 184f364ec65SWenchao Xia info->has_io_status = true; 185f364ec65SWenchao Xia info->io_status = bs->iostatus; 186f364ec65SWenchao Xia } 187f364ec65SWenchao Xia 188f364ec65SWenchao Xia if (bs->dirty_bitmap) { 189f364ec65SWenchao Xia info->has_dirty = true; 190f364ec65SWenchao Xia info->dirty = g_malloc0(sizeof(*info->dirty)); 191f364ec65SWenchao Xia info->dirty->count = bdrv_get_dirty_count(bs) * BDRV_SECTOR_SIZE; 192f364ec65SWenchao Xia info->dirty->granularity = 193f364ec65SWenchao Xia ((int64_t) BDRV_SECTOR_SIZE << hbitmap_granularity(bs->dirty_bitmap)); 194f364ec65SWenchao Xia } 195f364ec65SWenchao Xia 196f364ec65SWenchao Xia if (bs->drv) { 197f364ec65SWenchao Xia info->has_inserted = true; 198f364ec65SWenchao Xia info->inserted = g_malloc0(sizeof(*info->inserted)); 199f364ec65SWenchao Xia info->inserted->file = g_strdup(bs->filename); 200f364ec65SWenchao Xia info->inserted->ro = bs->read_only; 201f364ec65SWenchao Xia info->inserted->drv = g_strdup(bs->drv->format_name); 202f364ec65SWenchao Xia info->inserted->encrypted = bs->encrypted; 203f364ec65SWenchao Xia info->inserted->encryption_key_missing = bdrv_key_required(bs); 204f364ec65SWenchao Xia 205f364ec65SWenchao Xia if (bs->backing_file[0]) { 206f364ec65SWenchao Xia info->inserted->has_backing_file = true; 207f364ec65SWenchao Xia info->inserted->backing_file = g_strdup(bs->backing_file); 208f364ec65SWenchao Xia } 209f364ec65SWenchao Xia 210f364ec65SWenchao Xia info->inserted->backing_file_depth = bdrv_get_backing_file_depth(bs); 211f364ec65SWenchao Xia 212f364ec65SWenchao Xia if (bs->io_limits_enabled) { 213f364ec65SWenchao Xia info->inserted->bps = 214f364ec65SWenchao Xia bs->io_limits.bps[BLOCK_IO_LIMIT_TOTAL]; 215f364ec65SWenchao Xia info->inserted->bps_rd = 216f364ec65SWenchao Xia bs->io_limits.bps[BLOCK_IO_LIMIT_READ]; 217f364ec65SWenchao Xia info->inserted->bps_wr = 218f364ec65SWenchao Xia bs->io_limits.bps[BLOCK_IO_LIMIT_WRITE]; 219f364ec65SWenchao Xia info->inserted->iops = 220f364ec65SWenchao Xia bs->io_limits.iops[BLOCK_IO_LIMIT_TOTAL]; 221f364ec65SWenchao Xia info->inserted->iops_rd = 222f364ec65SWenchao Xia bs->io_limits.iops[BLOCK_IO_LIMIT_READ]; 223f364ec65SWenchao Xia info->inserted->iops_wr = 224f364ec65SWenchao Xia bs->io_limits.iops[BLOCK_IO_LIMIT_WRITE]; 225f364ec65SWenchao Xia } 226f364ec65SWenchao Xia } 227f364ec65SWenchao Xia return info; 228f364ec65SWenchao Xia } 229f364ec65SWenchao Xia 230f364ec65SWenchao Xia BlockStats *bdrv_query_stats(const BlockDriverState *bs) 231f364ec65SWenchao Xia { 232f364ec65SWenchao Xia BlockStats *s; 233f364ec65SWenchao Xia 234f364ec65SWenchao Xia s = g_malloc0(sizeof(*s)); 235f364ec65SWenchao Xia 236f364ec65SWenchao Xia if (bs->device_name[0]) { 237f364ec65SWenchao Xia s->has_device = true; 238f364ec65SWenchao Xia s->device = g_strdup(bs->device_name); 239f364ec65SWenchao Xia } 240f364ec65SWenchao Xia 241f364ec65SWenchao Xia s->stats = g_malloc0(sizeof(*s->stats)); 242f364ec65SWenchao Xia s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ]; 243f364ec65SWenchao Xia s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE]; 244f364ec65SWenchao Xia s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ]; 245f364ec65SWenchao Xia s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE]; 246f364ec65SWenchao Xia s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE; 247f364ec65SWenchao Xia s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH]; 248f364ec65SWenchao Xia s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE]; 249f364ec65SWenchao Xia s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ]; 250f364ec65SWenchao Xia s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH]; 251f364ec65SWenchao Xia 252f364ec65SWenchao Xia if (bs->file) { 253f364ec65SWenchao Xia s->has_parent = true; 254f364ec65SWenchao Xia s->parent = bdrv_query_stats(bs->file); 255f364ec65SWenchao Xia } 256f364ec65SWenchao Xia 257f364ec65SWenchao Xia return s; 258f364ec65SWenchao Xia } 259f364ec65SWenchao Xia 260f364ec65SWenchao Xia BlockInfoList *qmp_query_block(Error **errp) 261f364ec65SWenchao Xia { 262f364ec65SWenchao Xia BlockInfoList *head = NULL, **p_next = &head; 263f364ec65SWenchao Xia BlockDriverState *bs = NULL; 264f364ec65SWenchao Xia 265f364ec65SWenchao Xia while ((bs = bdrv_next(bs))) { 266f364ec65SWenchao Xia BlockInfoList *info = g_malloc0(sizeof(*info)); 267f364ec65SWenchao Xia info->value = bdrv_query_info(bs); 268f364ec65SWenchao Xia 269f364ec65SWenchao Xia *p_next = info; 270f364ec65SWenchao Xia p_next = &info->next; 271f364ec65SWenchao Xia } 272f364ec65SWenchao Xia 273f364ec65SWenchao Xia return head; 274f364ec65SWenchao Xia } 275f364ec65SWenchao Xia 276f364ec65SWenchao Xia BlockStatsList *qmp_query_blockstats(Error **errp) 277f364ec65SWenchao Xia { 278f364ec65SWenchao Xia BlockStatsList *head = NULL, **p_next = &head; 279f364ec65SWenchao Xia BlockDriverState *bs = NULL; 280f364ec65SWenchao Xia 281f364ec65SWenchao Xia while ((bs = bdrv_next(bs))) { 282f364ec65SWenchao Xia BlockStatsList *info = g_malloc0(sizeof(*info)); 283f364ec65SWenchao Xia info->value = bdrv_query_stats(bs); 284f364ec65SWenchao Xia 285f364ec65SWenchao Xia *p_next = info; 286f364ec65SWenchao Xia p_next = &info->next; 287f364ec65SWenchao Xia } 288f364ec65SWenchao Xia 289f364ec65SWenchao Xia return head; 290f364ec65SWenchao Xia } 291f364ec65SWenchao Xia 292f364ec65SWenchao Xia #define NB_SUFFIXES 4 293f364ec65SWenchao Xia 294f364ec65SWenchao Xia static char *get_human_readable_size(char *buf, int buf_size, int64_t size) 295f364ec65SWenchao Xia { 296f364ec65SWenchao Xia static const char suffixes[NB_SUFFIXES] = "KMGT"; 297f364ec65SWenchao Xia int64_t base; 298f364ec65SWenchao Xia int i; 299f364ec65SWenchao Xia 300f364ec65SWenchao Xia if (size <= 999) { 301f364ec65SWenchao Xia snprintf(buf, buf_size, "%" PRId64, size); 302f364ec65SWenchao Xia } else { 303f364ec65SWenchao Xia base = 1024; 304f364ec65SWenchao Xia for (i = 0; i < NB_SUFFIXES; i++) { 305f364ec65SWenchao Xia if (size < (10 * base)) { 306f364ec65SWenchao Xia snprintf(buf, buf_size, "%0.1f%c", 307f364ec65SWenchao Xia (double)size / base, 308f364ec65SWenchao Xia suffixes[i]); 309f364ec65SWenchao Xia break; 310f364ec65SWenchao Xia } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) { 311f364ec65SWenchao Xia snprintf(buf, buf_size, "%" PRId64 "%c", 312f364ec65SWenchao Xia ((size + (base >> 1)) / base), 313f364ec65SWenchao Xia suffixes[i]); 314f364ec65SWenchao Xia break; 315f364ec65SWenchao Xia } 316f364ec65SWenchao Xia base = base * 1024; 317f364ec65SWenchao Xia } 318f364ec65SWenchao Xia } 319f364ec65SWenchao Xia return buf; 320f364ec65SWenchao Xia } 321f364ec65SWenchao Xia 3225b917044SWenchao Xia void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f, 3235b917044SWenchao Xia QEMUSnapshotInfo *sn) 324f364ec65SWenchao Xia { 325f364ec65SWenchao Xia char buf1[128], date_buf[128], clock_buf[128]; 326f364ec65SWenchao Xia struct tm tm; 327f364ec65SWenchao Xia time_t ti; 328f364ec65SWenchao Xia int64_t secs; 329f364ec65SWenchao Xia 330f364ec65SWenchao Xia if (!sn) { 3315b917044SWenchao Xia func_fprintf(f, 332f364ec65SWenchao Xia "%-10s%-20s%7s%20s%15s", 333f364ec65SWenchao Xia "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK"); 334f364ec65SWenchao Xia } else { 335f364ec65SWenchao Xia ti = sn->date_sec; 336f364ec65SWenchao Xia localtime_r(&ti, &tm); 337f364ec65SWenchao Xia strftime(date_buf, sizeof(date_buf), 338f364ec65SWenchao Xia "%Y-%m-%d %H:%M:%S", &tm); 339f364ec65SWenchao Xia secs = sn->vm_clock_nsec / 1000000000; 340f364ec65SWenchao Xia snprintf(clock_buf, sizeof(clock_buf), 341f364ec65SWenchao Xia "%02d:%02d:%02d.%03d", 342f364ec65SWenchao Xia (int)(secs / 3600), 343f364ec65SWenchao Xia (int)((secs / 60) % 60), 344f364ec65SWenchao Xia (int)(secs % 60), 345f364ec65SWenchao Xia (int)((sn->vm_clock_nsec / 1000000) % 1000)); 3465b917044SWenchao Xia func_fprintf(f, 347f364ec65SWenchao Xia "%-10s%-20s%7s%20s%15s", 348f364ec65SWenchao Xia sn->id_str, sn->name, 3495b917044SWenchao Xia get_human_readable_size(buf1, sizeof(buf1), 3505b917044SWenchao Xia sn->vm_state_size), 351f364ec65SWenchao Xia date_buf, 352f364ec65SWenchao Xia clock_buf); 353f364ec65SWenchao Xia } 354f364ec65SWenchao Xia } 355f364ec65SWenchao Xia 3565b917044SWenchao Xia void bdrv_image_info_dump(fprintf_function func_fprintf, void *f, 3575b917044SWenchao Xia ImageInfo *info) 358f364ec65SWenchao Xia { 359f364ec65SWenchao Xia char size_buf[128], dsize_buf[128]; 360f364ec65SWenchao Xia if (!info->has_actual_size) { 361f364ec65SWenchao Xia snprintf(dsize_buf, sizeof(dsize_buf), "unavailable"); 362f364ec65SWenchao Xia } else { 363f364ec65SWenchao Xia get_human_readable_size(dsize_buf, sizeof(dsize_buf), 364f364ec65SWenchao Xia info->actual_size); 365f364ec65SWenchao Xia } 366f364ec65SWenchao Xia get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size); 3675b917044SWenchao Xia func_fprintf(f, 3685b917044SWenchao Xia "image: %s\n" 369f364ec65SWenchao Xia "file format: %s\n" 370f364ec65SWenchao Xia "virtual size: %s (%" PRId64 " bytes)\n" 371f364ec65SWenchao Xia "disk size: %s\n", 372f364ec65SWenchao Xia info->filename, info->format, size_buf, 373f364ec65SWenchao Xia info->virtual_size, 374f364ec65SWenchao Xia dsize_buf); 375f364ec65SWenchao Xia 376f364ec65SWenchao Xia if (info->has_encrypted && info->encrypted) { 3775b917044SWenchao Xia func_fprintf(f, "encrypted: yes\n"); 378f364ec65SWenchao Xia } 379f364ec65SWenchao Xia 380f364ec65SWenchao Xia if (info->has_cluster_size) { 3815b917044SWenchao Xia func_fprintf(f, "cluster_size: %" PRId64 "\n", 3825b917044SWenchao Xia info->cluster_size); 383f364ec65SWenchao Xia } 384f364ec65SWenchao Xia 385f364ec65SWenchao Xia if (info->has_dirty_flag && info->dirty_flag) { 3865b917044SWenchao Xia func_fprintf(f, "cleanly shut down: no\n"); 387f364ec65SWenchao Xia } 388f364ec65SWenchao Xia 389f364ec65SWenchao Xia if (info->has_backing_filename) { 3905b917044SWenchao Xia func_fprintf(f, "backing file: %s", info->backing_filename); 391f364ec65SWenchao Xia if (info->has_full_backing_filename) { 3925b917044SWenchao Xia func_fprintf(f, " (actual path: %s)", info->full_backing_filename); 393f364ec65SWenchao Xia } 3945b917044SWenchao Xia func_fprintf(f, "\n"); 395f364ec65SWenchao Xia if (info->has_backing_filename_format) { 3965b917044SWenchao Xia func_fprintf(f, "backing file format: %s\n", 3975b917044SWenchao Xia info->backing_filename_format); 398f364ec65SWenchao Xia } 399f364ec65SWenchao Xia } 400f364ec65SWenchao Xia 401f364ec65SWenchao Xia if (info->has_snapshots) { 402f364ec65SWenchao Xia SnapshotInfoList *elem; 403f364ec65SWenchao Xia 4045b917044SWenchao Xia func_fprintf(f, "Snapshot list:\n"); 4055b917044SWenchao Xia bdrv_snapshot_dump(func_fprintf, f, NULL); 4065b917044SWenchao Xia func_fprintf(f, "\n"); 407f364ec65SWenchao Xia 408f364ec65SWenchao Xia /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but 409f364ec65SWenchao Xia * we convert to the block layer's native QEMUSnapshotInfo for now. 410f364ec65SWenchao Xia */ 411f364ec65SWenchao Xia for (elem = info->snapshots; elem; elem = elem->next) { 412f364ec65SWenchao Xia QEMUSnapshotInfo sn = { 413f364ec65SWenchao Xia .vm_state_size = elem->value->vm_state_size, 414f364ec65SWenchao Xia .date_sec = elem->value->date_sec, 415f364ec65SWenchao Xia .date_nsec = elem->value->date_nsec, 416f364ec65SWenchao Xia .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL + 417f364ec65SWenchao Xia elem->value->vm_clock_nsec, 418f364ec65SWenchao Xia }; 419f364ec65SWenchao Xia 420f364ec65SWenchao Xia pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id); 421f364ec65SWenchao Xia pstrcpy(sn.name, sizeof(sn.name), elem->value->name); 4225b917044SWenchao Xia bdrv_snapshot_dump(func_fprintf, f, &sn); 4235b917044SWenchao Xia func_fprintf(f, "\n"); 424f364ec65SWenchao Xia } 425f364ec65SWenchao Xia } 426f364ec65SWenchao Xia } 427