[v3,10/13] monitor/hmp: move hmp_info_block* to block-hmp-cmds.c
diff mbox series

Message ID 20200127103647.17761-11-mlevitsk@redhat.com
State New
Headers show
Series
  • RFC: [for 5.0]: HMP monitor handlers cleanups
Related show

Commit Message

Maxim Levitsky Jan. 27, 2020, 10:36 a.m. UTC
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
---
 block/monitor/block-hmp-cmds.c     | 388 +++++++++++++++++++++++++++++
 include/block/block-hmp-commands.h |   4 +
 include/monitor/hmp.h              |   4 -
 monitor/hmp-cmds.c                 | 388 -----------------------------
 4 files changed, 392 insertions(+), 392 deletions(-)

Comments

Dr. David Alan Gilbert Jan. 28, 2020, 7 p.m. UTC | #1
* Maxim Levitsky (mlevitsk@redhat.com) wrote:
> Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>

Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

> ---
>  block/monitor/block-hmp-cmds.c     | 388 +++++++++++++++++++++++++++++
>  include/block/block-hmp-commands.h |   4 +
>  include/monitor/hmp.h              |   4 -
>  monitor/hmp-cmds.c                 | 388 -----------------------------
>  4 files changed, 392 insertions(+), 392 deletions(-)
> 
> diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
> index 60d63bfe18..a4b1604aee 100644
> --- a/block/monitor/block-hmp-cmds.c
> +++ b/block/monitor/block-hmp-cmds.c
> @@ -23,11 +23,13 @@
>  #include "qemu/config-file.h"
>  #include "qemu/option.h"
>  #include "qemu/sockets.h"
> +#include "qemu/cutils.h"
>  #include "sysemu/sysemu.h"
>  #include "monitor/monitor.h"
>  #include "block/nbd.h"
>  #include "block/block_int.h"
>  #include "block/block-hmp-commands.h"
> +#include "block/qapi.h"
>  #include "monitor/hmp.h"
>  #include "qemu-io.h"
>  
> @@ -553,3 +555,389 @@ fail:
>      blk_unref(local_blk);
>      hmp_handle_error(mon, err);
>  }
> +
> +static void print_block_info(Monitor *mon, BlockInfo *info,
> +                             BlockDeviceInfo *inserted, bool verbose)
> +{
> +    ImageInfo *image_info;
> +
> +    assert(!info || !info->has_inserted || info->inserted == inserted);
> +
> +    if (info && *info->device) {
> +        monitor_printf(mon, "%s", info->device);
> +        if (inserted && inserted->has_node_name) {
> +            monitor_printf(mon, " (%s)", inserted->node_name);
> +        }
> +    } else {
> +        assert(info || inserted);
> +        monitor_printf(mon, "%s",
> +                       inserted && inserted->has_node_name ? inserted->node_name
> +                       : info && info->has_qdev ? info->qdev
> +                       : "<anonymous>");
> +    }
> +
> +    if (inserted) {
> +        monitor_printf(mon, ": %s (%s%s%s)\n",
> +                       inserted->file,
> +                       inserted->drv,
> +                       inserted->ro ? ", read-only" : "",
> +                       inserted->encrypted ? ", encrypted" : "");
> +    } else {
> +        monitor_printf(mon, ": [not inserted]\n");
> +    }
> +
> +    if (info) {
> +        if (info->has_qdev) {
> +            monitor_printf(mon, "    Attached to:      %s\n", info->qdev);
> +        }
> +        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
> +            monitor_printf(mon, "    I/O status:       %s\n",
> +                           BlockDeviceIoStatus_str(info->io_status));
> +        }
> +
> +        if (info->removable) {
> +            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",
> +                           info->locked ? "" : "not ",
> +                           info->tray_open ? "open" : "closed");
> +        }
> +    }
> +
> +
> +    if (!inserted) {
> +        return;
> +    }
> +
> +    monitor_printf(mon, "    Cache mode:       %s%s%s\n",
> +                   inserted->cache->writeback ? "writeback" : "writethrough",
> +                   inserted->cache->direct ? ", direct" : "",
> +                   inserted->cache->no_flush ? ", ignore flushes" : "");
> +
> +    if (inserted->has_backing_file) {
> +        monitor_printf(mon,
> +                       "    Backing file:     %s "
> +                       "(chain depth: %" PRId64 ")\n",
> +                       inserted->backing_file,
> +                       inserted->backing_file_depth);
> +    }
> +
> +    if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
> +        monitor_printf(mon, "    Detect zeroes:    %s\n",
> +                BlockdevDetectZeroesOptions_str(inserted->detect_zeroes));
> +    }
> +
> +    if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||
> +        inserted->iops || inserted->iops_rd || inserted->iops_wr)
> +    {
> +        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
> +                        " bps_rd=%" PRId64  " bps_wr=%" PRId64
> +                        " bps_max=%" PRId64
> +                        " bps_rd_max=%" PRId64
> +                        " bps_wr_max=%" PRId64
> +                        " iops=%" PRId64 " iops_rd=%" PRId64
> +                        " iops_wr=%" PRId64
> +                        " iops_max=%" PRId64
> +                        " iops_rd_max=%" PRId64
> +                        " iops_wr_max=%" PRId64
> +                        " iops_size=%" PRId64
> +                        " group=%s\n",
> +                        inserted->bps,
> +                        inserted->bps_rd,
> +                        inserted->bps_wr,
> +                        inserted->bps_max,
> +                        inserted->bps_rd_max,
> +                        inserted->bps_wr_max,
> +                        inserted->iops,
> +                        inserted->iops_rd,
> +                        inserted->iops_wr,
> +                        inserted->iops_max,
> +                        inserted->iops_rd_max,
> +                        inserted->iops_wr_max,
> +                        inserted->iops_size,
> +                        inserted->group);
> +    }
> +
> +    if (verbose) {
> +        monitor_printf(mon, "\nImages:\n");
> +        image_info = inserted->image;
> +        while (1) {
> +                bdrv_image_info_dump(image_info);
> +            if (image_info->has_backing_image) {
> +                image_info = image_info->backing_image;
> +            } else {
> +                break;
> +            }
> +        }
> +    }
> +}
> +
> +void hmp_info_block(Monitor *mon, const QDict *qdict)
> +{
> +    BlockInfoList *block_list, *info;
> +    BlockDeviceInfoList *blockdev_list, *blockdev;
> +    const char *device = qdict_get_try_str(qdict, "device");
> +    bool verbose = qdict_get_try_bool(qdict, "verbose", false);
> +    bool nodes = qdict_get_try_bool(qdict, "nodes", false);
> +    bool printed = false;
> +
> +    /* Print BlockBackend information */
> +    if (!nodes) {
> +        block_list = qmp_query_block(NULL);
> +    } else {
> +        block_list = NULL;
> +    }
> +
> +    for (info = block_list; info; info = info->next) {
> +        if (device && strcmp(device, info->value->device)) {
> +            continue;
> +        }
> +
> +        if (info != block_list) {
> +            monitor_printf(mon, "\n");
> +        }
> +
> +        print_block_info(mon, info->value, info->value->has_inserted
> +                                           ? info->value->inserted : NULL,
> +                         verbose);
> +        printed = true;
> +    }
> +
> +    qapi_free_BlockInfoList(block_list);
> +
> +    if ((!device && !nodes) || printed) {
> +        return;
> +    }
> +
> +    /* Print node information */
> +    blockdev_list = qmp_query_named_block_nodes(NULL);
> +    for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
> +        assert(blockdev->value->has_node_name);
> +        if (device && strcmp(device, blockdev->value->node_name)) {
> +            continue;
> +        }
> +
> +        if (blockdev != blockdev_list) {
> +            monitor_printf(mon, "\n");
> +        }
> +
> +        print_block_info(mon, NULL, blockdev->value, verbose);
> +    }
> +    qapi_free_BlockDeviceInfoList(blockdev_list);
> +}
> +
> +void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
> +{
> +    BlockStatsList *stats_list, *stats;
> +
> +    stats_list = qmp_query_blockstats(false, false, NULL);
> +
> +    for (stats = stats_list; stats; stats = stats->next) {
> +        if (!stats->value->has_device) {
> +            continue;
> +        }
> +
> +        monitor_printf(mon, "%s:", stats->value->device);
> +        monitor_printf(mon, " rd_bytes=%" PRId64
> +                       " wr_bytes=%" PRId64
> +                       " rd_operations=%" PRId64
> +                       " wr_operations=%" PRId64
> +                       " flush_operations=%" PRId64
> +                       " wr_total_time_ns=%" PRId64
> +                       " rd_total_time_ns=%" PRId64
> +                       " flush_total_time_ns=%" PRId64
> +                       " rd_merged=%" PRId64
> +                       " wr_merged=%" PRId64
> +                       " idle_time_ns=%" PRId64
> +                       "\n",
> +                       stats->value->stats->rd_bytes,
> +                       stats->value->stats->wr_bytes,
> +                       stats->value->stats->rd_operations,
> +                       stats->value->stats->wr_operations,
> +                       stats->value->stats->flush_operations,
> +                       stats->value->stats->wr_total_time_ns,
> +                       stats->value->stats->rd_total_time_ns,
> +                       stats->value->stats->flush_total_time_ns,
> +                       stats->value->stats->rd_merged,
> +                       stats->value->stats->wr_merged,
> +                       stats->value->stats->idle_time_ns);
> +    }
> +
> +    qapi_free_BlockStatsList(stats_list);
> +}
> +
> +void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
> +{
> +    BlockJobInfoList *list;
> +    Error *err = NULL;
> +
> +    list = qmp_query_block_jobs(&err);
> +    assert(!err);
> +
> +    if (!list) {
> +        monitor_printf(mon, "No active jobs\n");
> +        return;
> +    }
> +
> +    while (list) {
> +        if (strcmp(list->value->type, "stream") == 0) {
> +            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
> +                           " of %" PRId64 " bytes, speed limit %" PRId64
> +                           " bytes/s\n",
> +                           list->value->device,
> +                           list->value->offset,
> +                           list->value->len,
> +                           list->value->speed);
> +        } else {
> +            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
> +                           " of %" PRId64 " bytes, speed limit %" PRId64
> +                           " bytes/s\n",
> +                           list->value->type,
> +                           list->value->device,
> +                           list->value->offset,
> +                           list->value->len,
> +                           list->value->speed);
> +        }
> +        list = list->next;
> +    }
> +
> +    qapi_free_BlockJobInfoList(list);
> +}
> +
> +void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
> +{
> +    BlockDriverState *bs, *bs1;
> +    BdrvNextIterator it1;
> +    QEMUSnapshotInfo *sn_tab, *sn;
> +    bool no_snapshot = true;
> +    int nb_sns, i;
> +    int total;
> +    int *global_snapshots;
> +    AioContext *aio_context;
> +
> +    typedef struct SnapshotEntry {
> +        QEMUSnapshotInfo sn;
> +        QTAILQ_ENTRY(SnapshotEntry) next;
> +    } SnapshotEntry;
> +
> +    typedef struct ImageEntry {
> +        const char *imagename;
> +        QTAILQ_ENTRY(ImageEntry) next;
> +        QTAILQ_HEAD(, SnapshotEntry) snapshots;
> +    } ImageEntry;
> +
> +    QTAILQ_HEAD(, ImageEntry) image_list =
> +        QTAILQ_HEAD_INITIALIZER(image_list);
> +
> +    ImageEntry *image_entry, *next_ie;
> +    SnapshotEntry *snapshot_entry;
> +
> +    bs = bdrv_all_find_vmstate_bs();
> +    if (!bs) {
> +        monitor_printf(mon, "No available block device supports snapshots\n");
> +        return;
> +    }
> +    aio_context = bdrv_get_aio_context(bs);
> +
> +    aio_context_acquire(aio_context);
> +    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
> +    aio_context_release(aio_context);
> +
> +    if (nb_sns < 0) {
> +        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
> +        return;
> +    }
> +
> +    for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) {
> +        int bs1_nb_sns = 0;
> +        ImageEntry *ie;
> +        SnapshotEntry *se;
> +        AioContext *ctx = bdrv_get_aio_context(bs1);
> +
> +        aio_context_acquire(ctx);
> +        if (bdrv_can_snapshot(bs1)) {
> +            sn = NULL;
> +            bs1_nb_sns = bdrv_snapshot_list(bs1, &sn);
> +            if (bs1_nb_sns > 0) {
> +                no_snapshot = false;
> +                ie = g_new0(ImageEntry, 1);
> +                ie->imagename = bdrv_get_device_name(bs1);
> +                QTAILQ_INIT(&ie->snapshots);
> +                QTAILQ_INSERT_TAIL(&image_list, ie, next);
> +                for (i = 0; i < bs1_nb_sns; i++) {
> +                    se = g_new0(SnapshotEntry, 1);
> +                    se->sn = sn[i];
> +                    QTAILQ_INSERT_TAIL(&ie->snapshots, se, next);
> +                }
> +            }
> +            g_free(sn);
> +        }
> +        aio_context_release(ctx);
> +    }
> +
> +    if (no_snapshot) {
> +        monitor_printf(mon, "There is no snapshot available.\n");
> +        return;
> +    }
> +
> +    global_snapshots = g_new0(int, nb_sns);
> +    total = 0;
> +    for (i = 0; i < nb_sns; i++) {
> +        SnapshotEntry *next_sn;
> +        if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) {
> +            global_snapshots[total] = i;
> +            total++;
> +            QTAILQ_FOREACH(image_entry, &image_list, next) {
> +                QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots,
> +                                    next, next_sn) {
> +                    if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) {
> +                        QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry,
> +                                      next);
> +                        g_free(snapshot_entry);
> +                    }
> +                }
> +            }
> +        }
> +    }
> +    monitor_printf(mon, "List of snapshots present on all disks:\n");
> +
> +    if (total > 0) {
> +        bdrv_snapshot_dump(NULL);
> +        monitor_printf(mon, "\n");
> +        for (i = 0; i < total; i++) {
> +            sn = &sn_tab[global_snapshots[i]];
> +            /* The ID is not guaranteed to be the same on all images, so
> +             * overwrite it.
> +             */
> +            pstrcpy(sn->id_str, sizeof(sn->id_str), "--");
> +            bdrv_snapshot_dump(sn);
> +            monitor_printf(mon, "\n");
> +        }
> +    } else {
> +        monitor_printf(mon, "None\n");
> +    }
> +
> +    QTAILQ_FOREACH(image_entry, &image_list, next) {
> +        if (QTAILQ_EMPTY(&image_entry->snapshots)) {
> +            continue;
> +        }
> +        monitor_printf(mon,
> +                       "\nList of partial (non-loadable) snapshots on '%s':\n",
> +                       image_entry->imagename);
> +        bdrv_snapshot_dump(NULL);
> +        monitor_printf(mon, "\n");
> +        QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) {
> +            bdrv_snapshot_dump(&snapshot_entry->sn);
> +            monitor_printf(mon, "\n");
> +        }
> +    }
> +
> +    QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) {
> +        SnapshotEntry *next_sn;
> +        QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next,
> +                            next_sn) {
> +            g_free(snapshot_entry);
> +        }
> +        g_free(image_entry);
> +    }
> +    g_free(sn_tab);
> +    g_free(global_snapshots);
> +}
> diff --git a/include/block/block-hmp-commands.h b/include/block/block-hmp-commands.h
> index 99145c8fcf..206635ffed 100644
> --- a/include/block/block-hmp-commands.h
> +++ b/include/block/block-hmp-commands.h
> @@ -34,5 +34,9 @@ void hmp_eject(Monitor *mon, const QDict *qdict);
>  
>  void hmp_qemu_io(Monitor *mon, const QDict *qdict);
>  
> +void hmp_info_block(Monitor *mon, const QDict *qdict);
> +void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
> +void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
> +void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
>  
>  #endif
> diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
> index 47a7cad734..e33ca5a911 100644
> --- a/include/monitor/hmp.h
> +++ b/include/monitor/hmp.h
> @@ -30,8 +30,6 @@ void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
>  void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
>  void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict);
>  void hmp_info_cpus(Monitor *mon, const QDict *qdict);
> -void hmp_info_block(Monitor *mon, const QDict *qdict);
> -void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
>  void hmp_info_vnc(Monitor *mon, const QDict *qdict);
>  void hmp_info_spice(Monitor *mon, const QDict *qdict);
>  void hmp_info_balloon(Monitor *mon, const QDict *qdict);
> @@ -39,7 +37,6 @@ void hmp_info_irq(Monitor *mon, const QDict *qdict);
>  void hmp_info_pic(Monitor *mon, const QDict *qdict);
>  void hmp_info_rdma(Monitor *mon, const QDict *qdict);
>  void hmp_info_pci(Monitor *mon, const QDict *qdict);
> -void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
>  void hmp_info_tpm(Monitor *mon, const QDict *qdict);
>  void hmp_info_iothreads(Monitor *mon, const QDict *qdict);
>  void hmp_quit(Monitor *mon, const QDict *qdict);
> @@ -62,7 +59,6 @@ void hmp_balloon(Monitor *mon, const QDict *qdict);
>  void hmp_loadvm(Monitor *mon, const QDict *qdict);
>  void hmp_savevm(Monitor *mon, const QDict *qdict);
>  void hmp_delvm(Monitor *mon, const QDict *qdict);
> -void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
>  void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
>  void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
>  void hmp_migrate_incoming(Monitor *mon, const QDict *qdict);
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index c224e0f338..1ddfe2fceb 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -45,7 +45,6 @@
>  #include "qapi/string-output-visitor.h"
>  #include "qom/object_interfaces.h"
>  #include "ui/console.h"
> -#include "block/qapi.h"
>  #include "qemu/cutils.h"
>  #include "qemu/error-report.h"
>  #include "exec/ramlist.h"
> @@ -465,213 +464,6 @@ void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
>                     qmp_query_migrate_cache_size(NULL) >> 10);
>  }
>  
> -static void print_block_info(Monitor *mon, BlockInfo *info,
> -                             BlockDeviceInfo *inserted, bool verbose)
> -{
> -    ImageInfo *image_info;
> -
> -    assert(!info || !info->has_inserted || info->inserted == inserted);
> -
> -    if (info && *info->device) {
> -        monitor_printf(mon, "%s", info->device);
> -        if (inserted && inserted->has_node_name) {
> -            monitor_printf(mon, " (%s)", inserted->node_name);
> -        }
> -    } else {
> -        assert(info || inserted);
> -        monitor_printf(mon, "%s",
> -                       inserted && inserted->has_node_name ? inserted->node_name
> -                       : info && info->has_qdev ? info->qdev
> -                       : "<anonymous>");
> -    }
> -
> -    if (inserted) {
> -        monitor_printf(mon, ": %s (%s%s%s)\n",
> -                       inserted->file,
> -                       inserted->drv,
> -                       inserted->ro ? ", read-only" : "",
> -                       inserted->encrypted ? ", encrypted" : "");
> -    } else {
> -        monitor_printf(mon, ": [not inserted]\n");
> -    }
> -
> -    if (info) {
> -        if (info->has_qdev) {
> -            monitor_printf(mon, "    Attached to:      %s\n", info->qdev);
> -        }
> -        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
> -            monitor_printf(mon, "    I/O status:       %s\n",
> -                           BlockDeviceIoStatus_str(info->io_status));
> -        }
> -
> -        if (info->removable) {
> -            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",
> -                           info->locked ? "" : "not ",
> -                           info->tray_open ? "open" : "closed");
> -        }
> -    }
> -
> -
> -    if (!inserted) {
> -        return;
> -    }
> -
> -    monitor_printf(mon, "    Cache mode:       %s%s%s\n",
> -                   inserted->cache->writeback ? "writeback" : "writethrough",
> -                   inserted->cache->direct ? ", direct" : "",
> -                   inserted->cache->no_flush ? ", ignore flushes" : "");
> -
> -    if (inserted->has_backing_file) {
> -        monitor_printf(mon,
> -                       "    Backing file:     %s "
> -                       "(chain depth: %" PRId64 ")\n",
> -                       inserted->backing_file,
> -                       inserted->backing_file_depth);
> -    }
> -
> -    if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
> -        monitor_printf(mon, "    Detect zeroes:    %s\n",
> -                BlockdevDetectZeroesOptions_str(inserted->detect_zeroes));
> -    }
> -
> -    if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||
> -        inserted->iops || inserted->iops_rd || inserted->iops_wr)
> -    {
> -        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
> -                        " bps_rd=%" PRId64  " bps_wr=%" PRId64
> -                        " bps_max=%" PRId64
> -                        " bps_rd_max=%" PRId64
> -                        " bps_wr_max=%" PRId64
> -                        " iops=%" PRId64 " iops_rd=%" PRId64
> -                        " iops_wr=%" PRId64
> -                        " iops_max=%" PRId64
> -                        " iops_rd_max=%" PRId64
> -                        " iops_wr_max=%" PRId64
> -                        " iops_size=%" PRId64
> -                        " group=%s\n",
> -                        inserted->bps,
> -                        inserted->bps_rd,
> -                        inserted->bps_wr,
> -                        inserted->bps_max,
> -                        inserted->bps_rd_max,
> -                        inserted->bps_wr_max,
> -                        inserted->iops,
> -                        inserted->iops_rd,
> -                        inserted->iops_wr,
> -                        inserted->iops_max,
> -                        inserted->iops_rd_max,
> -                        inserted->iops_wr_max,
> -                        inserted->iops_size,
> -                        inserted->group);
> -    }
> -
> -    if (verbose) {
> -        monitor_printf(mon, "\nImages:\n");
> -        image_info = inserted->image;
> -        while (1) {
> -                bdrv_image_info_dump(image_info);
> -            if (image_info->has_backing_image) {
> -                image_info = image_info->backing_image;
> -            } else {
> -                break;
> -            }
> -        }
> -    }
> -}
> -
> -void hmp_info_block(Monitor *mon, const QDict *qdict)
> -{
> -    BlockInfoList *block_list, *info;
> -    BlockDeviceInfoList *blockdev_list, *blockdev;
> -    const char *device = qdict_get_try_str(qdict, "device");
> -    bool verbose = qdict_get_try_bool(qdict, "verbose", false);
> -    bool nodes = qdict_get_try_bool(qdict, "nodes", false);
> -    bool printed = false;
> -
> -    /* Print BlockBackend information */
> -    if (!nodes) {
> -        block_list = qmp_query_block(NULL);
> -    } else {
> -        block_list = NULL;
> -    }
> -
> -    for (info = block_list; info; info = info->next) {
> -        if (device && strcmp(device, info->value->device)) {
> -            continue;
> -        }
> -
> -        if (info != block_list) {
> -            monitor_printf(mon, "\n");
> -        }
> -
> -        print_block_info(mon, info->value, info->value->has_inserted
> -                                           ? info->value->inserted : NULL,
> -                         verbose);
> -        printed = true;
> -    }
> -
> -    qapi_free_BlockInfoList(block_list);
> -
> -    if ((!device && !nodes) || printed) {
> -        return;
> -    }
> -
> -    /* Print node information */
> -    blockdev_list = qmp_query_named_block_nodes(NULL);
> -    for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
> -        assert(blockdev->value->has_node_name);
> -        if (device && strcmp(device, blockdev->value->node_name)) {
> -            continue;
> -        }
> -
> -        if (blockdev != blockdev_list) {
> -            monitor_printf(mon, "\n");
> -        }
> -
> -        print_block_info(mon, NULL, blockdev->value, verbose);
> -    }
> -    qapi_free_BlockDeviceInfoList(blockdev_list);
> -}
> -
> -void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
> -{
> -    BlockStatsList *stats_list, *stats;
> -
> -    stats_list = qmp_query_blockstats(false, false, NULL);
> -
> -    for (stats = stats_list; stats; stats = stats->next) {
> -        if (!stats->value->has_device) {
> -            continue;
> -        }
> -
> -        monitor_printf(mon, "%s:", stats->value->device);
> -        monitor_printf(mon, " rd_bytes=%" PRId64
> -                       " wr_bytes=%" PRId64
> -                       " rd_operations=%" PRId64
> -                       " wr_operations=%" PRId64
> -                       " flush_operations=%" PRId64
> -                       " wr_total_time_ns=%" PRId64
> -                       " rd_total_time_ns=%" PRId64
> -                       " flush_total_time_ns=%" PRId64
> -                       " rd_merged=%" PRId64
> -                       " wr_merged=%" PRId64
> -                       " idle_time_ns=%" PRId64
> -                       "\n",
> -                       stats->value->stats->rd_bytes,
> -                       stats->value->stats->wr_bytes,
> -                       stats->value->stats->rd_operations,
> -                       stats->value->stats->wr_operations,
> -                       stats->value->stats->flush_operations,
> -                       stats->value->stats->wr_total_time_ns,
> -                       stats->value->stats->rd_total_time_ns,
> -                       stats->value->stats->flush_total_time_ns,
> -                       stats->value->stats->rd_merged,
> -                       stats->value->stats->wr_merged,
> -                       stats->value->stats->idle_time_ns);
> -    }
> -
> -    qapi_free_BlockStatsList(stats_list);
> -}
>  
>  #ifdef CONFIG_VNC
>  /* Helper for hmp_info_vnc_clients, _servers */
> @@ -1051,44 +843,6 @@ void hmp_info_pci(Monitor *mon, const QDict *qdict)
>      qapi_free_PciInfoList(info_list);
>  }
>  
> -void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
> -{
> -    BlockJobInfoList *list;
> -    Error *err = NULL;
> -
> -    list = qmp_query_block_jobs(&err);
> -    assert(!err);
> -
> -    if (!list) {
> -        monitor_printf(mon, "No active jobs\n");
> -        return;
> -    }
> -
> -    while (list) {
> -        if (strcmp(list->value->type, "stream") == 0) {
> -            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
> -                           " of %" PRId64 " bytes, speed limit %" PRId64
> -                           " bytes/s\n",
> -                           list->value->device,
> -                           list->value->offset,
> -                           list->value->len,
> -                           list->value->speed);
> -        } else {
> -            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
> -                           " of %" PRId64 " bytes, speed limit %" PRId64
> -                           " bytes/s\n",
> -                           list->value->type,
> -                           list->value->device,
> -                           list->value->offset,
> -                           list->value->len,
> -                           list->value->speed);
> -        }
> -        list = list->next;
> -    }
> -
> -    qapi_free_BlockJobInfoList(list);
> -}
> -
>  void hmp_info_tpm(Monitor *mon, const QDict *qdict)
>  {
>      TPMInfoList *info_list, *info;
> @@ -1351,148 +1105,6 @@ void hmp_delvm(Monitor *mon, const QDict *qdict)
>      hmp_handle_error(mon, err);
>  }
>  
> -void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
> -{
> -    BlockDriverState *bs, *bs1;
> -    BdrvNextIterator it1;
> -    QEMUSnapshotInfo *sn_tab, *sn;
> -    bool no_snapshot = true;
> -    int nb_sns, i;
> -    int total;
> -    int *global_snapshots;
> -    AioContext *aio_context;
> -
> -    typedef struct SnapshotEntry {
> -        QEMUSnapshotInfo sn;
> -        QTAILQ_ENTRY(SnapshotEntry) next;
> -    } SnapshotEntry;
> -
> -    typedef struct ImageEntry {
> -        const char *imagename;
> -        QTAILQ_ENTRY(ImageEntry) next;
> -        QTAILQ_HEAD(, SnapshotEntry) snapshots;
> -    } ImageEntry;
> -
> -    QTAILQ_HEAD(, ImageEntry) image_list =
> -        QTAILQ_HEAD_INITIALIZER(image_list);
> -
> -    ImageEntry *image_entry, *next_ie;
> -    SnapshotEntry *snapshot_entry;
> -
> -    bs = bdrv_all_find_vmstate_bs();
> -    if (!bs) {
> -        monitor_printf(mon, "No available block device supports snapshots\n");
> -        return;
> -    }
> -    aio_context = bdrv_get_aio_context(bs);
> -
> -    aio_context_acquire(aio_context);
> -    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
> -    aio_context_release(aio_context);
> -
> -    if (nb_sns < 0) {
> -        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
> -        return;
> -    }
> -
> -    for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) {
> -        int bs1_nb_sns = 0;
> -        ImageEntry *ie;
> -        SnapshotEntry *se;
> -        AioContext *ctx = bdrv_get_aio_context(bs1);
> -
> -        aio_context_acquire(ctx);
> -        if (bdrv_can_snapshot(bs1)) {
> -            sn = NULL;
> -            bs1_nb_sns = bdrv_snapshot_list(bs1, &sn);
> -            if (bs1_nb_sns > 0) {
> -                no_snapshot = false;
> -                ie = g_new0(ImageEntry, 1);
> -                ie->imagename = bdrv_get_device_name(bs1);
> -                QTAILQ_INIT(&ie->snapshots);
> -                QTAILQ_INSERT_TAIL(&image_list, ie, next);
> -                for (i = 0; i < bs1_nb_sns; i++) {
> -                    se = g_new0(SnapshotEntry, 1);
> -                    se->sn = sn[i];
> -                    QTAILQ_INSERT_TAIL(&ie->snapshots, se, next);
> -                }
> -            }
> -            g_free(sn);
> -        }
> -        aio_context_release(ctx);
> -    }
> -
> -    if (no_snapshot) {
> -        monitor_printf(mon, "There is no snapshot available.\n");
> -        return;
> -    }
> -
> -    global_snapshots = g_new0(int, nb_sns);
> -    total = 0;
> -    for (i = 0; i < nb_sns; i++) {
> -        SnapshotEntry *next_sn;
> -        if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) {
> -            global_snapshots[total] = i;
> -            total++;
> -            QTAILQ_FOREACH(image_entry, &image_list, next) {
> -                QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots,
> -                                    next, next_sn) {
> -                    if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) {
> -                        QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry,
> -                                      next);
> -                        g_free(snapshot_entry);
> -                    }
> -                }
> -            }
> -        }
> -    }
> -
> -    monitor_printf(mon, "List of snapshots present on all disks:\n");
> -
> -    if (total > 0) {
> -        bdrv_snapshot_dump(NULL);
> -        monitor_printf(mon, "\n");
> -        for (i = 0; i < total; i++) {
> -            sn = &sn_tab[global_snapshots[i]];
> -            /* The ID is not guaranteed to be the same on all images, so
> -             * overwrite it.
> -             */
> -            pstrcpy(sn->id_str, sizeof(sn->id_str), "--");
> -            bdrv_snapshot_dump(sn);
> -            monitor_printf(mon, "\n");
> -        }
> -    } else {
> -        monitor_printf(mon, "None\n");
> -    }
> -
> -    QTAILQ_FOREACH(image_entry, &image_list, next) {
> -        if (QTAILQ_EMPTY(&image_entry->snapshots)) {
> -            continue;
> -        }
> -        monitor_printf(mon,
> -                       "\nList of partial (non-loadable) snapshots on '%s':\n",
> -                       image_entry->imagename);
> -        bdrv_snapshot_dump(NULL);
> -        monitor_printf(mon, "\n");
> -        QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) {
> -            bdrv_snapshot_dump(&snapshot_entry->sn);
> -            monitor_printf(mon, "\n");
> -        }
> -    }
> -
> -    QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) {
> -        SnapshotEntry *next_sn;
> -        QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next,
> -                            next_sn) {
> -            g_free(snapshot_entry);
> -        }
> -        g_free(image_entry);
> -    }
> -    g_free(sn_tab);
> -    g_free(global_snapshots);
> -
> -}
> -
>  void hmp_announce_self(Monitor *mon, const QDict *qdict)
>  {
>      const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
> -- 
> 2.17.2
> 
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

Patch
diff mbox series

diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 60d63bfe18..a4b1604aee 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -23,11 +23,13 @@ 
 #include "qemu/config-file.h"
 #include "qemu/option.h"
 #include "qemu/sockets.h"
+#include "qemu/cutils.h"
 #include "sysemu/sysemu.h"
 #include "monitor/monitor.h"
 #include "block/nbd.h"
 #include "block/block_int.h"
 #include "block/block-hmp-commands.h"
+#include "block/qapi.h"
 #include "monitor/hmp.h"
 #include "qemu-io.h"
 
@@ -553,3 +555,389 @@  fail:
     blk_unref(local_blk);
     hmp_handle_error(mon, err);
 }
+
+static void print_block_info(Monitor *mon, BlockInfo *info,
+                             BlockDeviceInfo *inserted, bool verbose)
+{
+    ImageInfo *image_info;
+
+    assert(!info || !info->has_inserted || info->inserted == inserted);
+
+    if (info && *info->device) {
+        monitor_printf(mon, "%s", info->device);
+        if (inserted && inserted->has_node_name) {
+            monitor_printf(mon, " (%s)", inserted->node_name);
+        }
+    } else {
+        assert(info || inserted);
+        monitor_printf(mon, "%s",
+                       inserted && inserted->has_node_name ? inserted->node_name
+                       : info && info->has_qdev ? info->qdev
+                       : "<anonymous>");
+    }
+
+    if (inserted) {
+        monitor_printf(mon, ": %s (%s%s%s)\n",
+                       inserted->file,
+                       inserted->drv,
+                       inserted->ro ? ", read-only" : "",
+                       inserted->encrypted ? ", encrypted" : "");
+    } else {
+        monitor_printf(mon, ": [not inserted]\n");
+    }
+
+    if (info) {
+        if (info->has_qdev) {
+            monitor_printf(mon, "    Attached to:      %s\n", info->qdev);
+        }
+        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
+            monitor_printf(mon, "    I/O status:       %s\n",
+                           BlockDeviceIoStatus_str(info->io_status));
+        }
+
+        if (info->removable) {
+            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",
+                           info->locked ? "" : "not ",
+                           info->tray_open ? "open" : "closed");
+        }
+    }
+
+
+    if (!inserted) {
+        return;
+    }
+
+    monitor_printf(mon, "    Cache mode:       %s%s%s\n",
+                   inserted->cache->writeback ? "writeback" : "writethrough",
+                   inserted->cache->direct ? ", direct" : "",
+                   inserted->cache->no_flush ? ", ignore flushes" : "");
+
+    if (inserted->has_backing_file) {
+        monitor_printf(mon,
+                       "    Backing file:     %s "
+                       "(chain depth: %" PRId64 ")\n",
+                       inserted->backing_file,
+                       inserted->backing_file_depth);
+    }
+
+    if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
+        monitor_printf(mon, "    Detect zeroes:    %s\n",
+                BlockdevDetectZeroesOptions_str(inserted->detect_zeroes));
+    }
+
+    if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||
+        inserted->iops || inserted->iops_rd || inserted->iops_wr)
+    {
+        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
+                        " bps_rd=%" PRId64  " bps_wr=%" PRId64
+                        " bps_max=%" PRId64
+                        " bps_rd_max=%" PRId64
+                        " bps_wr_max=%" PRId64
+                        " iops=%" PRId64 " iops_rd=%" PRId64
+                        " iops_wr=%" PRId64
+                        " iops_max=%" PRId64
+                        " iops_rd_max=%" PRId64
+                        " iops_wr_max=%" PRId64
+                        " iops_size=%" PRId64
+                        " group=%s\n",
+                        inserted->bps,
+                        inserted->bps_rd,
+                        inserted->bps_wr,
+                        inserted->bps_max,
+                        inserted->bps_rd_max,
+                        inserted->bps_wr_max,
+                        inserted->iops,
+                        inserted->iops_rd,
+                        inserted->iops_wr,
+                        inserted->iops_max,
+                        inserted->iops_rd_max,
+                        inserted->iops_wr_max,
+                        inserted->iops_size,
+                        inserted->group);
+    }
+
+    if (verbose) {
+        monitor_printf(mon, "\nImages:\n");
+        image_info = inserted->image;
+        while (1) {
+                bdrv_image_info_dump(image_info);
+            if (image_info->has_backing_image) {
+                image_info = image_info->backing_image;
+            } else {
+                break;
+            }
+        }
+    }
+}
+
+void hmp_info_block(Monitor *mon, const QDict *qdict)
+{
+    BlockInfoList *block_list, *info;
+    BlockDeviceInfoList *blockdev_list, *blockdev;
+    const char *device = qdict_get_try_str(qdict, "device");
+    bool verbose = qdict_get_try_bool(qdict, "verbose", false);
+    bool nodes = qdict_get_try_bool(qdict, "nodes", false);
+    bool printed = false;
+
+    /* Print BlockBackend information */
+    if (!nodes) {
+        block_list = qmp_query_block(NULL);
+    } else {
+        block_list = NULL;
+    }
+
+    for (info = block_list; info; info = info->next) {
+        if (device && strcmp(device, info->value->device)) {
+            continue;
+        }
+
+        if (info != block_list) {
+            monitor_printf(mon, "\n");
+        }
+
+        print_block_info(mon, info->value, info->value->has_inserted
+                                           ? info->value->inserted : NULL,
+                         verbose);
+        printed = true;
+    }
+
+    qapi_free_BlockInfoList(block_list);
+
+    if ((!device && !nodes) || printed) {
+        return;
+    }
+
+    /* Print node information */
+    blockdev_list = qmp_query_named_block_nodes(NULL);
+    for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
+        assert(blockdev->value->has_node_name);
+        if (device && strcmp(device, blockdev->value->node_name)) {
+            continue;
+        }
+
+        if (blockdev != blockdev_list) {
+            monitor_printf(mon, "\n");
+        }
+
+        print_block_info(mon, NULL, blockdev->value, verbose);
+    }
+    qapi_free_BlockDeviceInfoList(blockdev_list);
+}
+
+void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
+{
+    BlockStatsList *stats_list, *stats;
+
+    stats_list = qmp_query_blockstats(false, false, NULL);
+
+    for (stats = stats_list; stats; stats = stats->next) {
+        if (!stats->value->has_device) {
+            continue;
+        }
+
+        monitor_printf(mon, "%s:", stats->value->device);
+        monitor_printf(mon, " rd_bytes=%" PRId64
+                       " wr_bytes=%" PRId64
+                       " rd_operations=%" PRId64
+                       " wr_operations=%" PRId64
+                       " flush_operations=%" PRId64
+                       " wr_total_time_ns=%" PRId64
+                       " rd_total_time_ns=%" PRId64
+                       " flush_total_time_ns=%" PRId64
+                       " rd_merged=%" PRId64
+                       " wr_merged=%" PRId64
+                       " idle_time_ns=%" PRId64
+                       "\n",
+                       stats->value->stats->rd_bytes,
+                       stats->value->stats->wr_bytes,
+                       stats->value->stats->rd_operations,
+                       stats->value->stats->wr_operations,
+                       stats->value->stats->flush_operations,
+                       stats->value->stats->wr_total_time_ns,
+                       stats->value->stats->rd_total_time_ns,
+                       stats->value->stats->flush_total_time_ns,
+                       stats->value->stats->rd_merged,
+                       stats->value->stats->wr_merged,
+                       stats->value->stats->idle_time_ns);
+    }
+
+    qapi_free_BlockStatsList(stats_list);
+}
+
+void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
+{
+    BlockJobInfoList *list;
+    Error *err = NULL;
+
+    list = qmp_query_block_jobs(&err);
+    assert(!err);
+
+    if (!list) {
+        monitor_printf(mon, "No active jobs\n");
+        return;
+    }
+
+    while (list) {
+        if (strcmp(list->value->type, "stream") == 0) {
+            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
+                           " of %" PRId64 " bytes, speed limit %" PRId64
+                           " bytes/s\n",
+                           list->value->device,
+                           list->value->offset,
+                           list->value->len,
+                           list->value->speed);
+        } else {
+            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
+                           " of %" PRId64 " bytes, speed limit %" PRId64
+                           " bytes/s\n",
+                           list->value->type,
+                           list->value->device,
+                           list->value->offset,
+                           list->value->len,
+                           list->value->speed);
+        }
+        list = list->next;
+    }
+
+    qapi_free_BlockJobInfoList(list);
+}
+
+void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
+{
+    BlockDriverState *bs, *bs1;
+    BdrvNextIterator it1;
+    QEMUSnapshotInfo *sn_tab, *sn;
+    bool no_snapshot = true;
+    int nb_sns, i;
+    int total;
+    int *global_snapshots;
+    AioContext *aio_context;
+
+    typedef struct SnapshotEntry {
+        QEMUSnapshotInfo sn;
+        QTAILQ_ENTRY(SnapshotEntry) next;
+    } SnapshotEntry;
+
+    typedef struct ImageEntry {
+        const char *imagename;
+        QTAILQ_ENTRY(ImageEntry) next;
+        QTAILQ_HEAD(, SnapshotEntry) snapshots;
+    } ImageEntry;
+
+    QTAILQ_HEAD(, ImageEntry) image_list =
+        QTAILQ_HEAD_INITIALIZER(image_list);
+
+    ImageEntry *image_entry, *next_ie;
+    SnapshotEntry *snapshot_entry;
+
+    bs = bdrv_all_find_vmstate_bs();
+    if (!bs) {
+        monitor_printf(mon, "No available block device supports snapshots\n");
+        return;
+    }
+    aio_context = bdrv_get_aio_context(bs);
+
+    aio_context_acquire(aio_context);
+    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
+    aio_context_release(aio_context);
+
+    if (nb_sns < 0) {
+        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
+        return;
+    }
+
+    for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) {
+        int bs1_nb_sns = 0;
+        ImageEntry *ie;
+        SnapshotEntry *se;
+        AioContext *ctx = bdrv_get_aio_context(bs1);
+
+        aio_context_acquire(ctx);
+        if (bdrv_can_snapshot(bs1)) {
+            sn = NULL;
+            bs1_nb_sns = bdrv_snapshot_list(bs1, &sn);
+            if (bs1_nb_sns > 0) {
+                no_snapshot = false;
+                ie = g_new0(ImageEntry, 1);
+                ie->imagename = bdrv_get_device_name(bs1);
+                QTAILQ_INIT(&ie->snapshots);
+                QTAILQ_INSERT_TAIL(&image_list, ie, next);
+                for (i = 0; i < bs1_nb_sns; i++) {
+                    se = g_new0(SnapshotEntry, 1);
+                    se->sn = sn[i];
+                    QTAILQ_INSERT_TAIL(&ie->snapshots, se, next);
+                }
+            }
+            g_free(sn);
+        }
+        aio_context_release(ctx);
+    }
+
+    if (no_snapshot) {
+        monitor_printf(mon, "There is no snapshot available.\n");
+        return;
+    }
+
+    global_snapshots = g_new0(int, nb_sns);
+    total = 0;
+    for (i = 0; i < nb_sns; i++) {
+        SnapshotEntry *next_sn;
+        if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) {
+            global_snapshots[total] = i;
+            total++;
+            QTAILQ_FOREACH(image_entry, &image_list, next) {
+                QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots,
+                                    next, next_sn) {
+                    if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) {
+                        QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry,
+                                      next);
+                        g_free(snapshot_entry);
+                    }
+                }
+            }
+        }
+    }
+    monitor_printf(mon, "List of snapshots present on all disks:\n");
+
+    if (total > 0) {
+        bdrv_snapshot_dump(NULL);
+        monitor_printf(mon, "\n");
+        for (i = 0; i < total; i++) {
+            sn = &sn_tab[global_snapshots[i]];
+            /* The ID is not guaranteed to be the same on all images, so
+             * overwrite it.
+             */
+            pstrcpy(sn->id_str, sizeof(sn->id_str), "--");
+            bdrv_snapshot_dump(sn);
+            monitor_printf(mon, "\n");
+        }
+    } else {
+        monitor_printf(mon, "None\n");
+    }
+
+    QTAILQ_FOREACH(image_entry, &image_list, next) {
+        if (QTAILQ_EMPTY(&image_entry->snapshots)) {
+            continue;
+        }
+        monitor_printf(mon,
+                       "\nList of partial (non-loadable) snapshots on '%s':\n",
+                       image_entry->imagename);
+        bdrv_snapshot_dump(NULL);
+        monitor_printf(mon, "\n");
+        QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) {
+            bdrv_snapshot_dump(&snapshot_entry->sn);
+            monitor_printf(mon, "\n");
+        }
+    }
+
+    QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) {
+        SnapshotEntry *next_sn;
+        QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next,
+                            next_sn) {
+            g_free(snapshot_entry);
+        }
+        g_free(image_entry);
+    }
+    g_free(sn_tab);
+    g_free(global_snapshots);
+}
diff --git a/include/block/block-hmp-commands.h b/include/block/block-hmp-commands.h
index 99145c8fcf..206635ffed 100644
--- a/include/block/block-hmp-commands.h
+++ b/include/block/block-hmp-commands.h
@@ -34,5 +34,9 @@  void hmp_eject(Monitor *mon, const QDict *qdict);
 
 void hmp_qemu_io(Monitor *mon, const QDict *qdict);
 
+void hmp_info_block(Monitor *mon, const QDict *qdict);
+void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
+void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
+void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/include/monitor/hmp.h b/include/monitor/hmp.h
index 47a7cad734..e33ca5a911 100644
--- a/include/monitor/hmp.h
+++ b/include/monitor/hmp.h
@@ -30,8 +30,6 @@  void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
 void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict);
 void hmp_info_cpus(Monitor *mon, const QDict *qdict);
-void hmp_info_block(Monitor *mon, const QDict *qdict);
-void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
 void hmp_info_vnc(Monitor *mon, const QDict *qdict);
 void hmp_info_spice(Monitor *mon, const QDict *qdict);
 void hmp_info_balloon(Monitor *mon, const QDict *qdict);
@@ -39,7 +37,6 @@  void hmp_info_irq(Monitor *mon, const QDict *qdict);
 void hmp_info_pic(Monitor *mon, const QDict *qdict);
 void hmp_info_rdma(Monitor *mon, const QDict *qdict);
 void hmp_info_pci(Monitor *mon, const QDict *qdict);
-void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
 void hmp_info_tpm(Monitor *mon, const QDict *qdict);
 void hmp_info_iothreads(Monitor *mon, const QDict *qdict);
 void hmp_quit(Monitor *mon, const QDict *qdict);
@@ -62,7 +59,6 @@  void hmp_balloon(Monitor *mon, const QDict *qdict);
 void hmp_loadvm(Monitor *mon, const QDict *qdict);
 void hmp_savevm(Monitor *mon, const QDict *qdict);
 void hmp_delvm(Monitor *mon, const QDict *qdict);
-void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
 void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict);
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index c224e0f338..1ddfe2fceb 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -45,7 +45,6 @@ 
 #include "qapi/string-output-visitor.h"
 #include "qom/object_interfaces.h"
 #include "ui/console.h"
-#include "block/qapi.h"
 #include "qemu/cutils.h"
 #include "qemu/error-report.h"
 #include "exec/ramlist.h"
@@ -465,213 +464,6 @@  void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
                    qmp_query_migrate_cache_size(NULL) >> 10);
 }
 
-static void print_block_info(Monitor *mon, BlockInfo *info,
-                             BlockDeviceInfo *inserted, bool verbose)
-{
-    ImageInfo *image_info;
-
-    assert(!info || !info->has_inserted || info->inserted == inserted);
-
-    if (info && *info->device) {
-        monitor_printf(mon, "%s", info->device);
-        if (inserted && inserted->has_node_name) {
-            monitor_printf(mon, " (%s)", inserted->node_name);
-        }
-    } else {
-        assert(info || inserted);
-        monitor_printf(mon, "%s",
-                       inserted && inserted->has_node_name ? inserted->node_name
-                       : info && info->has_qdev ? info->qdev
-                       : "<anonymous>");
-    }
-
-    if (inserted) {
-        monitor_printf(mon, ": %s (%s%s%s)\n",
-                       inserted->file,
-                       inserted->drv,
-                       inserted->ro ? ", read-only" : "",
-                       inserted->encrypted ? ", encrypted" : "");
-    } else {
-        monitor_printf(mon, ": [not inserted]\n");
-    }
-
-    if (info) {
-        if (info->has_qdev) {
-            monitor_printf(mon, "    Attached to:      %s\n", info->qdev);
-        }
-        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
-            monitor_printf(mon, "    I/O status:       %s\n",
-                           BlockDeviceIoStatus_str(info->io_status));
-        }
-
-        if (info->removable) {
-            monitor_printf(mon, "    Removable device: %slocked, tray %s\n",
-                           info->locked ? "" : "not ",
-                           info->tray_open ? "open" : "closed");
-        }
-    }
-
-
-    if (!inserted) {
-        return;
-    }
-
-    monitor_printf(mon, "    Cache mode:       %s%s%s\n",
-                   inserted->cache->writeback ? "writeback" : "writethrough",
-                   inserted->cache->direct ? ", direct" : "",
-                   inserted->cache->no_flush ? ", ignore flushes" : "");
-
-    if (inserted->has_backing_file) {
-        monitor_printf(mon,
-                       "    Backing file:     %s "
-                       "(chain depth: %" PRId64 ")\n",
-                       inserted->backing_file,
-                       inserted->backing_file_depth);
-    }
-
-    if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
-        monitor_printf(mon, "    Detect zeroes:    %s\n",
-                BlockdevDetectZeroesOptions_str(inserted->detect_zeroes));
-    }
-
-    if (inserted->bps  || inserted->bps_rd  || inserted->bps_wr  ||
-        inserted->iops || inserted->iops_rd || inserted->iops_wr)
-    {
-        monitor_printf(mon, "    I/O throttling:   bps=%" PRId64
-                        " bps_rd=%" PRId64  " bps_wr=%" PRId64
-                        " bps_max=%" PRId64
-                        " bps_rd_max=%" PRId64
-                        " bps_wr_max=%" PRId64
-                        " iops=%" PRId64 " iops_rd=%" PRId64
-                        " iops_wr=%" PRId64
-                        " iops_max=%" PRId64
-                        " iops_rd_max=%" PRId64
-                        " iops_wr_max=%" PRId64
-                        " iops_size=%" PRId64
-                        " group=%s\n",
-                        inserted->bps,
-                        inserted->bps_rd,
-                        inserted->bps_wr,
-                        inserted->bps_max,
-                        inserted->bps_rd_max,
-                        inserted->bps_wr_max,
-                        inserted->iops,
-                        inserted->iops_rd,
-                        inserted->iops_wr,
-                        inserted->iops_max,
-                        inserted->iops_rd_max,
-                        inserted->iops_wr_max,
-                        inserted->iops_size,
-                        inserted->group);
-    }
-
-    if (verbose) {
-        monitor_printf(mon, "\nImages:\n");
-        image_info = inserted->image;
-        while (1) {
-                bdrv_image_info_dump(image_info);
-            if (image_info->has_backing_image) {
-                image_info = image_info->backing_image;
-            } else {
-                break;
-            }
-        }
-    }
-}
-
-void hmp_info_block(Monitor *mon, const QDict *qdict)
-{
-    BlockInfoList *block_list, *info;
-    BlockDeviceInfoList *blockdev_list, *blockdev;
-    const char *device = qdict_get_try_str(qdict, "device");
-    bool verbose = qdict_get_try_bool(qdict, "verbose", false);
-    bool nodes = qdict_get_try_bool(qdict, "nodes", false);
-    bool printed = false;
-
-    /* Print BlockBackend information */
-    if (!nodes) {
-        block_list = qmp_query_block(NULL);
-    } else {
-        block_list = NULL;
-    }
-
-    for (info = block_list; info; info = info->next) {
-        if (device && strcmp(device, info->value->device)) {
-            continue;
-        }
-
-        if (info != block_list) {
-            monitor_printf(mon, "\n");
-        }
-
-        print_block_info(mon, info->value, info->value->has_inserted
-                                           ? info->value->inserted : NULL,
-                         verbose);
-        printed = true;
-    }
-
-    qapi_free_BlockInfoList(block_list);
-
-    if ((!device && !nodes) || printed) {
-        return;
-    }
-
-    /* Print node information */
-    blockdev_list = qmp_query_named_block_nodes(NULL);
-    for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
-        assert(blockdev->value->has_node_name);
-        if (device && strcmp(device, blockdev->value->node_name)) {
-            continue;
-        }
-
-        if (blockdev != blockdev_list) {
-            monitor_printf(mon, "\n");
-        }
-
-        print_block_info(mon, NULL, blockdev->value, verbose);
-    }
-    qapi_free_BlockDeviceInfoList(blockdev_list);
-}
-
-void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
-{
-    BlockStatsList *stats_list, *stats;
-
-    stats_list = qmp_query_blockstats(false, false, NULL);
-
-    for (stats = stats_list; stats; stats = stats->next) {
-        if (!stats->value->has_device) {
-            continue;
-        }
-
-        monitor_printf(mon, "%s:", stats->value->device);
-        monitor_printf(mon, " rd_bytes=%" PRId64
-                       " wr_bytes=%" PRId64
-                       " rd_operations=%" PRId64
-                       " wr_operations=%" PRId64
-                       " flush_operations=%" PRId64
-                       " wr_total_time_ns=%" PRId64
-                       " rd_total_time_ns=%" PRId64
-                       " flush_total_time_ns=%" PRId64
-                       " rd_merged=%" PRId64
-                       " wr_merged=%" PRId64
-                       " idle_time_ns=%" PRId64
-                       "\n",
-                       stats->value->stats->rd_bytes,
-                       stats->value->stats->wr_bytes,
-                       stats->value->stats->rd_operations,
-                       stats->value->stats->wr_operations,
-                       stats->value->stats->flush_operations,
-                       stats->value->stats->wr_total_time_ns,
-                       stats->value->stats->rd_total_time_ns,
-                       stats->value->stats->flush_total_time_ns,
-                       stats->value->stats->rd_merged,
-                       stats->value->stats->wr_merged,
-                       stats->value->stats->idle_time_ns);
-    }
-
-    qapi_free_BlockStatsList(stats_list);
-}
 
 #ifdef CONFIG_VNC
 /* Helper for hmp_info_vnc_clients, _servers */
@@ -1051,44 +843,6 @@  void hmp_info_pci(Monitor *mon, const QDict *qdict)
     qapi_free_PciInfoList(info_list);
 }
 
-void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
-{
-    BlockJobInfoList *list;
-    Error *err = NULL;
-
-    list = qmp_query_block_jobs(&err);
-    assert(!err);
-
-    if (!list) {
-        monitor_printf(mon, "No active jobs\n");
-        return;
-    }
-
-    while (list) {
-        if (strcmp(list->value->type, "stream") == 0) {
-            monitor_printf(mon, "Streaming device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRId64
-                           " bytes/s\n",
-                           list->value->device,
-                           list->value->offset,
-                           list->value->len,
-                           list->value->speed);
-        } else {
-            monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
-                           " of %" PRId64 " bytes, speed limit %" PRId64
-                           " bytes/s\n",
-                           list->value->type,
-                           list->value->device,
-                           list->value->offset,
-                           list->value->len,
-                           list->value->speed);
-        }
-        list = list->next;
-    }
-
-    qapi_free_BlockJobInfoList(list);
-}
-
 void hmp_info_tpm(Monitor *mon, const QDict *qdict)
 {
     TPMInfoList *info_list, *info;
@@ -1351,148 +1105,6 @@  void hmp_delvm(Monitor *mon, const QDict *qdict)
     hmp_handle_error(mon, err);
 }
 
-void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
-{
-    BlockDriverState *bs, *bs1;
-    BdrvNextIterator it1;
-    QEMUSnapshotInfo *sn_tab, *sn;
-    bool no_snapshot = true;
-    int nb_sns, i;
-    int total;
-    int *global_snapshots;
-    AioContext *aio_context;
-
-    typedef struct SnapshotEntry {
-        QEMUSnapshotInfo sn;
-        QTAILQ_ENTRY(SnapshotEntry) next;
-    } SnapshotEntry;
-
-    typedef struct ImageEntry {
-        const char *imagename;
-        QTAILQ_ENTRY(ImageEntry) next;
-        QTAILQ_HEAD(, SnapshotEntry) snapshots;
-    } ImageEntry;
-
-    QTAILQ_HEAD(, ImageEntry) image_list =
-        QTAILQ_HEAD_INITIALIZER(image_list);
-
-    ImageEntry *image_entry, *next_ie;
-    SnapshotEntry *snapshot_entry;
-
-    bs = bdrv_all_find_vmstate_bs();
-    if (!bs) {
-        monitor_printf(mon, "No available block device supports snapshots\n");
-        return;
-    }
-    aio_context = bdrv_get_aio_context(bs);
-
-    aio_context_acquire(aio_context);
-    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
-    aio_context_release(aio_context);
-
-    if (nb_sns < 0) {
-        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
-        return;
-    }
-
-    for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) {
-        int bs1_nb_sns = 0;
-        ImageEntry *ie;
-        SnapshotEntry *se;
-        AioContext *ctx = bdrv_get_aio_context(bs1);
-
-        aio_context_acquire(ctx);
-        if (bdrv_can_snapshot(bs1)) {
-            sn = NULL;
-            bs1_nb_sns = bdrv_snapshot_list(bs1, &sn);
-            if (bs1_nb_sns > 0) {
-                no_snapshot = false;
-                ie = g_new0(ImageEntry, 1);
-                ie->imagename = bdrv_get_device_name(bs1);
-                QTAILQ_INIT(&ie->snapshots);
-                QTAILQ_INSERT_TAIL(&image_list, ie, next);
-                for (i = 0; i < bs1_nb_sns; i++) {
-                    se = g_new0(SnapshotEntry, 1);
-                    se->sn = sn[i];
-                    QTAILQ_INSERT_TAIL(&ie->snapshots, se, next);
-                }
-            }
-            g_free(sn);
-        }
-        aio_context_release(ctx);
-    }
-
-    if (no_snapshot) {
-        monitor_printf(mon, "There is no snapshot available.\n");
-        return;
-    }
-
-    global_snapshots = g_new0(int, nb_sns);
-    total = 0;
-    for (i = 0; i < nb_sns; i++) {
-        SnapshotEntry *next_sn;
-        if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) {
-            global_snapshots[total] = i;
-            total++;
-            QTAILQ_FOREACH(image_entry, &image_list, next) {
-                QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots,
-                                    next, next_sn) {
-                    if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) {
-                        QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry,
-                                      next);
-                        g_free(snapshot_entry);
-                    }
-                }
-            }
-        }
-    }
-
-    monitor_printf(mon, "List of snapshots present on all disks:\n");
-
-    if (total > 0) {
-        bdrv_snapshot_dump(NULL);
-        monitor_printf(mon, "\n");
-        for (i = 0; i < total; i++) {
-            sn = &sn_tab[global_snapshots[i]];
-            /* The ID is not guaranteed to be the same on all images, so
-             * overwrite it.
-             */
-            pstrcpy(sn->id_str, sizeof(sn->id_str), "--");
-            bdrv_snapshot_dump(sn);
-            monitor_printf(mon, "\n");
-        }
-    } else {
-        monitor_printf(mon, "None\n");
-    }
-
-    QTAILQ_FOREACH(image_entry, &image_list, next) {
-        if (QTAILQ_EMPTY(&image_entry->snapshots)) {
-            continue;
-        }
-        monitor_printf(mon,
-                       "\nList of partial (non-loadable) snapshots on '%s':\n",
-                       image_entry->imagename);
-        bdrv_snapshot_dump(NULL);
-        monitor_printf(mon, "\n");
-        QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) {
-            bdrv_snapshot_dump(&snapshot_entry->sn);
-            monitor_printf(mon, "\n");
-        }
-    }
-
-    QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) {
-        SnapshotEntry *next_sn;
-        QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next,
-                            next_sn) {
-            g_free(snapshot_entry);
-        }
-        g_free(image_entry);
-    }
-    g_free(sn_tab);
-    g_free(global_snapshots);
-
-}
-
 void hmp_announce_self(Monitor *mon, const QDict *qdict)
 {
     const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");