/*
 * Block layer qmp and info dump related functions
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include "block/qapi.h"
#include "block/block_int.h"
#include "block/dirty-bitmap.h"
#include "block/throttle-groups.h"
#include "block/write-threshold.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-block-core.h"
#include "qapi/qobject-output-visitor.h"
#include "qapi/qapi-visit-block-core.h"
#include "qapi/qmp/qbool.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qnum.h"
#include "qapi/qmp/qstring.h"
#include "qemu/qemu-print.h"
#include "sysemu/block-backend.h"

BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
                                        BlockDriverState *bs,
                                        bool flat,
                                        Error **errp)
{
    ImageInfo **p_image_info;
    ImageInfo *backing_info;
    BlockDriverState *bs0, *backing;
    BlockDeviceInfo *info;
    ERRP_GUARD();

    if (!bs->drv) {
        error_setg(errp, "Block device %s is ejected", bs->node_name);
        return NULL;
    }

    bdrv_refresh_filename(bs);

    info = g_malloc0(sizeof(*info));
    info->file                   = g_strdup(bs->filename);
    info->ro                     = bdrv_is_read_only(bs);
    info->drv                    = g_strdup(bs->drv->format_name);
    info->encrypted              = bs->encrypted;

    info->cache = g_new(BlockdevCacheInfo, 1);
    *info->cache = (BlockdevCacheInfo) {
        .writeback      = blk ? blk_enable_write_cache(blk) : true,
        .direct         = !!(bs->open_flags & BDRV_O_NOCACHE),
        .no_flush       = !!(bs->open_flags & BDRV_O_NO_FLUSH),
    };

    if (bs->node_name[0]) {
        info->node_name = g_strdup(bs->node_name);
    }

    backing = bdrv_cow_bs(bs);
    if (backing) {
        info->backing_file = g_strdup(backing->filename);
    }

    if (!QLIST_EMPTY(&bs->dirty_bitmaps)) {
        info->has_dirty_bitmaps = true;
        info->dirty_bitmaps = bdrv_query_dirty_bitmaps(bs);
    }

    info->detect_zeroes = bs->detect_zeroes;

    if (blk && blk_get_public(blk)->throttle_group_member.throttle_state) {
        ThrottleConfig cfg;
        BlockBackendPublic *blkp = blk_get_public(blk);

        throttle_group_get_config(&blkp->throttle_group_member, &cfg);

        info->bps     = cfg.buckets[THROTTLE_BPS_TOTAL].avg;
        info->bps_rd  = cfg.buckets[THROTTLE_BPS_READ].avg;
        info->bps_wr  = cfg.buckets[THROTTLE_BPS_WRITE].avg;

        info->iops    = cfg.buckets[THROTTLE_OPS_TOTAL].avg;
        info->iops_rd = cfg.buckets[THROTTLE_OPS_READ].avg;
        info->iops_wr = cfg.buckets[THROTTLE_OPS_WRITE].avg;

        info->has_bps_max     = cfg.buckets[THROTTLE_BPS_TOTAL].max;
        info->bps_max         = cfg.buckets[THROTTLE_BPS_TOTAL].max;
        info->has_bps_rd_max  = cfg.buckets[THROTTLE_BPS_READ].max;
        info->bps_rd_max      = cfg.buckets[THROTTLE_BPS_READ].max;
        info->has_bps_wr_max  = cfg.buckets[THROTTLE_BPS_WRITE].max;
        info->bps_wr_max      = cfg.buckets[THROTTLE_BPS_WRITE].max;

        info->has_iops_max    = cfg.buckets[THROTTLE_OPS_TOTAL].max;
        info->iops_max        = cfg.buckets[THROTTLE_OPS_TOTAL].max;
        info->has_iops_rd_max = cfg.buckets[THROTTLE_OPS_READ].max;
        info->iops_rd_max     = cfg.buckets[THROTTLE_OPS_READ].max;
        info->has_iops_wr_max = cfg.buckets[THROTTLE_OPS_WRITE].max;
        info->iops_wr_max     = cfg.buckets[THROTTLE_OPS_WRITE].max;

        info->has_bps_max_length     = info->has_bps_max;
        info->bps_max_length         =
            cfg.buckets[THROTTLE_BPS_TOTAL].burst_length;
        info->has_bps_rd_max_length  = info->has_bps_rd_max;
        info->bps_rd_max_length      =
            cfg.buckets[THROTTLE_BPS_READ].burst_length;
        info->has_bps_wr_max_length  = info->has_bps_wr_max;
        info->bps_wr_max_length      =
            cfg.buckets[THROTTLE_BPS_WRITE].burst_length;

        info->has_iops_max_length    = info->has_iops_max;
        info->iops_max_length        =
            cfg.buckets[THROTTLE_OPS_TOTAL].burst_length;
        info->has_iops_rd_max_length = info->has_iops_rd_max;
        info->iops_rd_max_length     =
            cfg.buckets[THROTTLE_OPS_READ].burst_length;
        info->has_iops_wr_max_length = info->has_iops_wr_max;
        info->iops_wr_max_length     =
            cfg.buckets[THROTTLE_OPS_WRITE].burst_length;

        info->has_iops_size = cfg.op_size;
        info->iops_size = cfg.op_size;

        info->group =
            g_strdup(throttle_group_get_name(&blkp->throttle_group_member));
    }

    info->write_threshold = bdrv_write_threshold_get(bs);

    bs0 = bs;
    p_image_info = &info->image;
    info->backing_file_depth = 0;

    /*
     * Skip automatically inserted nodes that the user isn't aware of for
     * query-block (blk != NULL), but not for query-named-block-nodes
     */
    bdrv_query_image_info(bs0, p_image_info, flat, blk != NULL, errp);
    if (*errp) {
        qapi_free_BlockDeviceInfo(info);
        return NULL;
    }

    backing_info = info->image->backing_image;
    while (backing_info) {
        info->backing_file_depth++;
        backing_info = backing_info->backing_image;
    }

    return info;
}

/*
 * Returns 0 on success, with *p_list either set to describe snapshot
 * information, or NULL because there are no snapshots.  Returns -errno on
 * error, with *p_list untouched.
 */
int bdrv_query_snapshot_info_list(BlockDriverState *bs,
                                  SnapshotInfoList **p_list,
                                  Error **errp)
{
    int i, sn_count;
    QEMUSnapshotInfo *sn_tab = NULL;
    SnapshotInfoList *head = NULL, **tail = &head;
    SnapshotInfo *info;

    sn_count = bdrv_snapshot_list(bs, &sn_tab);
    if (sn_count < 0) {
        const char *dev = bdrv_get_device_name(bs);
        switch (sn_count) {
        case -ENOMEDIUM:
            error_setg(errp, "Device '%s' is not inserted", dev);
            break;
        case -ENOTSUP:
            error_setg(errp,
                       "Device '%s' does not support internal snapshots",
                       dev);
            break;
        default:
            error_setg_errno(errp, -sn_count,
                             "Can't list snapshots of device '%s'", dev);
            break;
        }
        return sn_count;
    }

    for (i = 0; i < sn_count; i++) {
        info = g_new0(SnapshotInfo, 1);
        info->id            = g_strdup(sn_tab[i].id_str);
        info->name          = g_strdup(sn_tab[i].name);
        info->vm_state_size = sn_tab[i].vm_state_size;
        info->date_sec      = sn_tab[i].date_sec;
        info->date_nsec     = sn_tab[i].date_nsec;
        info->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
        info->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
        info->icount        = sn_tab[i].icount;
        info->has_icount    = sn_tab[i].icount != -1ULL;

        QAPI_LIST_APPEND(tail, info);
    }

    g_free(sn_tab);
    *p_list = head;
    return 0;
}

/**
 * Helper function for other query info functions.  Store information about @bs
 * in @info, setting @errp on error.
 */
static void bdrv_do_query_node_info(BlockDriverState *bs,
                                    BlockNodeInfo *info,
                                    Error **errp)
{
    int64_t size;
    const char *backing_filename;
    BlockDriverInfo bdi;
    int ret;
    Error *err = NULL;

    aio_context_acquire(bdrv_get_aio_context(bs));

    size = bdrv_getlength(bs);
    if (size < 0) {
        error_setg_errno(errp, -size, "Can't get image size '%s'",
                         bs->exact_filename);
        goto out;
    }

    bdrv_refresh_filename(bs);

    info->filename        = g_strdup(bs->filename);
    info->format          = g_strdup(bdrv_get_format_name(bs));
    info->virtual_size    = size;
    info->actual_size     = bdrv_get_allocated_file_size(bs);
    info->has_actual_size = info->actual_size >= 0;
    if (bs->encrypted) {
        info->encrypted = true;
        info->has_encrypted = true;
    }
    if (bdrv_get_info(bs, &bdi) >= 0) {
        if (bdi.cluster_size != 0) {
            info->cluster_size = bdi.cluster_size;
            info->has_cluster_size = true;
        }
        info->dirty_flag = bdi.is_dirty;
        info->has_dirty_flag = true;
    }
    info->format_specific = bdrv_get_specific_info(bs, &err);
    if (err) {
        error_propagate(errp, err);
        goto out;
    }
    backing_filename = bs->backing_file;
    if (backing_filename[0] != '\0') {
        char *backing_filename2;

        info->backing_filename = g_strdup(backing_filename);
        backing_filename2 = bdrv_get_full_backing_filename(bs, NULL);

        /* Always report the full_backing_filename if present, even if it's the
         * same as backing_filename. That they are same is useful info. */
        if (backing_filename2) {
            info->full_backing_filename = g_strdup(backing_filename2);
        }

        if (bs->backing_format[0]) {
            info->backing_filename_format = g_strdup(bs->backing_format);
        }
        g_free(backing_filename2);
    }

    ret = bdrv_query_snapshot_info_list(bs, &info->snapshots, &err);
    switch (ret) {
    case 0:
        if (info->snapshots) {
            info->has_snapshots = true;
        }
        break;
    /* recoverable error */
    case -ENOMEDIUM:
    case -ENOTSUP:
        error_free(err);
        break;
    default:
        error_propagate(errp, err);
        goto out;
    }

out:
    aio_context_release(bdrv_get_aio_context(bs));
}

/**
 * bdrv_query_block_node_info:
 * @bs: block node to examine
 * @p_info: location to store node information
 * @errp: location to store error information
 *
 * Store image information about @bs in @p_info.
 *
 * @p_info will be set only on success. On error, store error in @errp.
 */
void bdrv_query_block_node_info(BlockDriverState *bs,
                                BlockNodeInfo **p_info,
                                Error **errp)
{
    BlockNodeInfo *info;
    ERRP_GUARD();

    info = g_new0(BlockNodeInfo, 1);
    bdrv_do_query_node_info(bs, info, errp);
    if (*errp) {
        qapi_free_BlockNodeInfo(info);
        return;
    }

    *p_info = info;
}

/**
 * bdrv_query_image_info:
 * @bs: block node to examine
 * @p_info: location to store image information
 * @flat: skip backing node information
 * @skip_implicit_filters: skip implicit filters in the backing chain
 * @errp: location to store error information
 *
 * Store image information in @p_info, potentially recursively covering the
 * backing chain.
 *
 * If @flat is true, do not query backing image information, i.e.
 * (*p_info)->has_backing_image will be set to false and
 * (*p_info)->backing_image to NULL even when the image does in fact have a
 * backing image.
 *
 * If @skip_implicit_filters is true, implicit filter nodes in the backing chain
 * will be skipped when querying backing image information.
 * (@skip_implicit_filters is ignored when @flat is true.)
 *
 * @p_info will be set only on success. On error, store error in @errp.
 */
void bdrv_query_image_info(BlockDriverState *bs,
                           ImageInfo **p_info,
                           bool flat,
                           bool skip_implicit_filters,
                           Error **errp)
{
    ImageInfo *info;
    ERRP_GUARD();

    info = g_new0(ImageInfo, 1);
    bdrv_do_query_node_info(bs, qapi_ImageInfo_base(info), errp);
    if (*errp) {
        goto fail;
    }

    if (!flat) {
        BlockDriverState *backing;

        /*
         * Use any filtered child here (for backwards compatibility to when
         * we always took bs->backing, which might be any filtered child).
         */
        backing = bdrv_filter_or_cow_bs(bs);
        if (skip_implicit_filters) {
            backing = bdrv_skip_implicit_filters(backing);
        }

        if (backing) {
            bdrv_query_image_info(backing, &info->backing_image, false,
                                  skip_implicit_filters, errp);
            if (*errp) {
                goto fail;
            }
        }
    }

    *p_info = info;
    return;

fail:
    assert(*errp);
    qapi_free_ImageInfo(info);
}

/**
 * bdrv_query_block_graph_info:
 * @bs: root node to start from
 * @p_info: location to store image information
 * @errp: location to store error information
 *
 * Store image information about the graph starting from @bs in @p_info.
 *
 * @p_info will be set only on success. On error, store error in @errp.
 */
void bdrv_query_block_graph_info(BlockDriverState *bs,
                                 BlockGraphInfo **p_info,
                                 Error **errp)
{
    BlockGraphInfo *info;
    BlockChildInfoList **children_list_tail;
    BdrvChild *c;
    ERRP_GUARD();

    info = g_new0(BlockGraphInfo, 1);
    bdrv_do_query_node_info(bs, qapi_BlockGraphInfo_base(info), errp);
    if (*errp) {
        goto fail;
    }

    children_list_tail = &info->children;

    QLIST_FOREACH(c, &bs->children, next) {
        BlockChildInfo *c_info;

        c_info = g_new0(BlockChildInfo, 1);
        QAPI_LIST_APPEND(children_list_tail, c_info);

        c_info->name = g_strdup(c->name);
        bdrv_query_block_graph_info(c->bs, &c_info->info, errp);
        if (*errp) {
            goto fail;
        }
    }

    *p_info = info;
    return;

fail:
    assert(*errp != NULL);
    qapi_free_BlockGraphInfo(info);
}

/* @p_info will be set only on success. */
static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
                            Error **errp)
{
    BlockInfo *info = g_malloc0(sizeof(*info));
    BlockDriverState *bs = blk_bs(blk);
    char *qdev;

    /* Skip automatically inserted nodes that the user isn't aware of */
    bs = bdrv_skip_implicit_filters(bs);

    info->device = g_strdup(blk_name(blk));
    info->type = g_strdup("unknown");
    info->locked = blk_dev_is_medium_locked(blk);
    info->removable = blk_dev_has_removable_media(blk);

    qdev = blk_get_attached_dev_id(blk);
    if (qdev && *qdev) {
        info->qdev = qdev;
    } else {
        g_free(qdev);
    }

    if (blk_dev_has_tray(blk)) {
        info->has_tray_open = true;
        info->tray_open = blk_dev_is_tray_open(blk);
    }

    if (blk_iostatus_is_enabled(blk)) {
        info->has_io_status = true;
        info->io_status = blk_iostatus(blk);
    }

    if (bs && bs->drv) {
        info->inserted = bdrv_block_device_info(blk, bs, false, errp);
        if (info->inserted == NULL) {
            goto err;
        }
    }

    *p_info = info;
    return;

 err:
    qapi_free_BlockInfo(info);
}

static uint64List *uint64_list(uint64_t *list, int size)
{
    int i;
    uint64List *out_list = NULL;
    uint64List **tail = &out_list;

    for (i = 0; i < size; i++) {
        QAPI_LIST_APPEND(tail, list[i]);
    }

    return out_list;
}

static BlockLatencyHistogramInfo *
bdrv_latency_histogram_stats(BlockLatencyHistogram *hist)
{
    BlockLatencyHistogramInfo *info;

    if (!hist->bins) {
        return NULL;
    }

    info = g_new0(BlockLatencyHistogramInfo, 1);
    info->boundaries = uint64_list(hist->boundaries, hist->nbins - 1);
    info->bins = uint64_list(hist->bins, hist->nbins);
    return info;
}

static void bdrv_query_blk_stats(BlockDeviceStats *ds, BlockBackend *blk)
{
    BlockAcctStats *stats = blk_get_stats(blk);
    BlockAcctTimedStats *ts = NULL;
    BlockLatencyHistogram *hgram;

    ds->rd_bytes = stats->nr_bytes[BLOCK_ACCT_READ];
    ds->wr_bytes = stats->nr_bytes[BLOCK_ACCT_WRITE];
    ds->unmap_bytes = stats->nr_bytes[BLOCK_ACCT_UNMAP];
    ds->rd_operations = stats->nr_ops[BLOCK_ACCT_READ];
    ds->wr_operations = stats->nr_ops[BLOCK_ACCT_WRITE];
    ds->unmap_operations = stats->nr_ops[BLOCK_ACCT_UNMAP];

    ds->failed_rd_operations = stats->failed_ops[BLOCK_ACCT_READ];
    ds->failed_wr_operations = stats->failed_ops[BLOCK_ACCT_WRITE];
    ds->failed_flush_operations = stats->failed_ops[BLOCK_ACCT_FLUSH];
    ds->failed_unmap_operations = stats->failed_ops[BLOCK_ACCT_UNMAP];

    ds->invalid_rd_operations = stats->invalid_ops[BLOCK_ACCT_READ];
    ds->invalid_wr_operations = stats->invalid_ops[BLOCK_ACCT_WRITE];
    ds->invalid_flush_operations =
        stats->invalid_ops[BLOCK_ACCT_FLUSH];
    ds->invalid_unmap_operations = stats->invalid_ops[BLOCK_ACCT_UNMAP];

    ds->rd_merged = stats->merged[BLOCK_ACCT_READ];
    ds->wr_merged = stats->merged[BLOCK_ACCT_WRITE];
    ds->unmap_merged = stats->merged[BLOCK_ACCT_UNMAP];
    ds->flush_operations = stats->nr_ops[BLOCK_ACCT_FLUSH];
    ds->wr_total_time_ns = stats->total_time_ns[BLOCK_ACCT_WRITE];
    ds->rd_total_time_ns = stats->total_time_ns[BLOCK_ACCT_READ];
    ds->flush_total_time_ns = stats->total_time_ns[BLOCK_ACCT_FLUSH];
    ds->unmap_total_time_ns = stats->total_time_ns[BLOCK_ACCT_UNMAP];

    ds->has_idle_time_ns = stats->last_access_time_ns > 0;
    if (ds->has_idle_time_ns) {
        ds->idle_time_ns = block_acct_idle_time_ns(stats);
    }

    ds->account_invalid = stats->account_invalid;
    ds->account_failed = stats->account_failed;

    while ((ts = block_acct_interval_next(stats, ts))) {
        BlockDeviceTimedStats *dev_stats = g_malloc0(sizeof(*dev_stats));

        TimedAverage *rd = &ts->latency[BLOCK_ACCT_READ];
        TimedAverage *wr = &ts->latency[BLOCK_ACCT_WRITE];
        TimedAverage *fl = &ts->latency[BLOCK_ACCT_FLUSH];

        dev_stats->interval_length = ts->interval_length;

        dev_stats->min_rd_latency_ns = timed_average_min(rd);
        dev_stats->max_rd_latency_ns = timed_average_max(rd);
        dev_stats->avg_rd_latency_ns = timed_average_avg(rd);

        dev_stats->min_wr_latency_ns = timed_average_min(wr);
        dev_stats->max_wr_latency_ns = timed_average_max(wr);
        dev_stats->avg_wr_latency_ns = timed_average_avg(wr);

        dev_stats->min_flush_latency_ns = timed_average_min(fl);
        dev_stats->max_flush_latency_ns = timed_average_max(fl);
        dev_stats->avg_flush_latency_ns = timed_average_avg(fl);

        dev_stats->avg_rd_queue_depth =
            block_acct_queue_depth(ts, BLOCK_ACCT_READ);
        dev_stats->avg_wr_queue_depth =
            block_acct_queue_depth(ts, BLOCK_ACCT_WRITE);

        QAPI_LIST_PREPEND(ds->timed_stats, dev_stats);
    }

    hgram = stats->latency_histogram;
    ds->rd_latency_histogram
        = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_READ]);
    ds->wr_latency_histogram
        = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_WRITE]);
    ds->flush_latency_histogram
        = bdrv_latency_histogram_stats(&hgram[BLOCK_ACCT_FLUSH]);
}

static BlockStats *bdrv_query_bds_stats(BlockDriverState *bs,
                                        bool blk_level)
{
    BdrvChild *parent_child;
    BlockDriverState *filter_or_cow_bs;
    BlockStats *s = NULL;

    s = g_malloc0(sizeof(*s));
    s->stats = g_malloc0(sizeof(*s->stats));

    if (!bs) {
        return s;
    }

    /* Skip automatically inserted nodes that the user isn't aware of in
     * a BlockBackend-level command. Stay at the exact node for a node-level
     * command. */
    if (blk_level) {
        bs = bdrv_skip_implicit_filters(bs);
    }

    if (bdrv_get_node_name(bs)[0]) {
        s->node_name = g_strdup(bdrv_get_node_name(bs));
    }

    s->stats->wr_highest_offset = stat64_get(&bs->wr_highest_offset);

    s->driver_specific = bdrv_get_specific_stats(bs);

    parent_child = bdrv_primary_child(bs);
    if (!parent_child ||
        !(parent_child->role & (BDRV_CHILD_DATA | BDRV_CHILD_FILTERED)))
    {
        BdrvChild *c;

        /*
         * Look for a unique data-storing child.  We do not need to look for
         * filtered children, as there would be only one and it would have been
         * the primary child.
         */
        parent_child = NULL;
        QLIST_FOREACH(c, &bs->children, next) {
            if (c->role & BDRV_CHILD_DATA) {
                if (parent_child) {
                    /*
                     * There are multiple data-storing children and we cannot
                     * choose between them.
                     */
                    parent_child = NULL;
                    break;
                }
                parent_child = c;
            }
        }
    }
    if (parent_child) {
        s->parent = bdrv_query_bds_stats(parent_child->bs, blk_level);
    }

    filter_or_cow_bs = bdrv_filter_or_cow_bs(bs);
    if (blk_level && filter_or_cow_bs) {
        /*
         * Put any filtered or COW child here (for backwards
         * compatibility to when we put bs0->backing here, which might
         * be either)
         */
        s->backing = bdrv_query_bds_stats(filter_or_cow_bs, blk_level);
    }

    return s;
}

BlockInfoList *qmp_query_block(Error **errp)
{
    BlockInfoList *head = NULL, **p_next = &head;
    BlockBackend *blk;
    Error *local_err = NULL;

    for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
        BlockInfoList *info;

        if (!*blk_name(blk) && !blk_get_attached_dev(blk)) {
            continue;
        }

        info = g_malloc0(sizeof(*info));
        bdrv_query_info(blk, &info->value, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            g_free(info);
            qapi_free_BlockInfoList(head);
            return NULL;
        }

        *p_next = info;
        p_next = &info->next;
    }

    return head;
}

BlockStatsList *qmp_query_blockstats(bool has_query_nodes,
                                     bool query_nodes,
                                     Error **errp)
{
    BlockStatsList *head = NULL, **tail = &head;
    BlockBackend *blk;
    BlockDriverState *bs;

    /* Just to be safe if query_nodes is not always initialized */
    if (has_query_nodes && query_nodes) {
        for (bs = bdrv_next_node(NULL); bs; bs = bdrv_next_node(bs)) {
            AioContext *ctx = bdrv_get_aio_context(bs);

            aio_context_acquire(ctx);
            QAPI_LIST_APPEND(tail, bdrv_query_bds_stats(bs, false));
            aio_context_release(ctx);
        }
    } else {
        for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
            AioContext *ctx = blk_get_aio_context(blk);
            BlockStats *s;
            char *qdev;

            if (!*blk_name(blk) && !blk_get_attached_dev(blk)) {
                continue;
            }

            aio_context_acquire(ctx);
            s = bdrv_query_bds_stats(blk_bs(blk), true);
            s->device = g_strdup(blk_name(blk));

            qdev = blk_get_attached_dev_id(blk);
            if (qdev && *qdev) {
                s->qdev = qdev;
            } else {
                g_free(qdev);
            }

            bdrv_query_blk_stats(s->stats, blk);
            aio_context_release(ctx);

            QAPI_LIST_APPEND(tail, s);
        }
    }

    return head;
}

void bdrv_snapshot_dump(QEMUSnapshotInfo *sn)
{
    char clock_buf[128];
    char icount_buf[128] = {0};
    int64_t secs;
    char *sizing = NULL;

    if (!sn) {
        qemu_printf("%-10s%-17s%8s%20s%13s%11s",
                    "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK", "ICOUNT");
    } else {
        g_autoptr(GDateTime) date = g_date_time_new_from_unix_local(sn->date_sec);
        g_autofree char *date_buf = g_date_time_format(date, "%Y-%m-%d %H:%M:%S");

        secs = sn->vm_clock_nsec / 1000000000;
        snprintf(clock_buf, sizeof(clock_buf),
                 "%02d:%02d:%02d.%03d",
                 (int)(secs / 3600),
                 (int)((secs / 60) % 60),
                 (int)(secs % 60),
                 (int)((sn->vm_clock_nsec / 1000000) % 1000));
        sizing = size_to_str(sn->vm_state_size);
        if (sn->icount != -1ULL) {
            snprintf(icount_buf, sizeof(icount_buf),
                "%"PRId64, sn->icount);
        }
        qemu_printf("%-9s %-16s %8s%20s%13s%11s",
                    sn->id_str, sn->name,
                    sizing,
                    date_buf,
                    clock_buf,
                    icount_buf);
    }
    g_free(sizing);
}

static void dump_qdict(int indentation, QDict *dict);
static void dump_qlist(int indentation, QList *list);

static void dump_qobject(int comp_indent, QObject *obj)
{
    switch (qobject_type(obj)) {
        case QTYPE_QNUM: {
            QNum *value = qobject_to(QNum, obj);
            char *tmp = qnum_to_string(value);
            qemu_printf("%s", tmp);
            g_free(tmp);
            break;
        }
        case QTYPE_QSTRING: {
            QString *value = qobject_to(QString, obj);
            qemu_printf("%s", qstring_get_str(value));
            break;
        }
        case QTYPE_QDICT: {
            QDict *value = qobject_to(QDict, obj);
            dump_qdict(comp_indent, value);
            break;
        }
        case QTYPE_QLIST: {
            QList *value = qobject_to(QList, obj);
            dump_qlist(comp_indent, value);
            break;
        }
        case QTYPE_QBOOL: {
            QBool *value = qobject_to(QBool, obj);
            qemu_printf("%s", qbool_get_bool(value) ? "true" : "false");
            break;
        }
        default:
            abort();
    }
}

static void dump_qlist(int indentation, QList *list)
{
    const QListEntry *entry;
    int i = 0;

    for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) {
        QType type = qobject_type(entry->value);
        bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
        qemu_printf("%*s[%i]:%c", indentation * 4, "", i,
                    composite ? '\n' : ' ');
        dump_qobject(indentation + 1, entry->value);
        if (!composite) {
            qemu_printf("\n");
        }
    }
}

static void dump_qdict(int indentation, QDict *dict)
{
    const QDictEntry *entry;

    for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) {
        QType type = qobject_type(entry->value);
        bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST);
        char *key = g_malloc(strlen(entry->key) + 1);
        int i;

        /* replace dashes with spaces in key (variable) names */
        for (i = 0; entry->key[i]; i++) {
            key[i] = entry->key[i] == '-' ? ' ' : entry->key[i];
        }
        key[i] = 0;
        qemu_printf("%*s%s:%c", indentation * 4, "", key,
                    composite ? '\n' : ' ');
        dump_qobject(indentation + 1, entry->value);
        if (!composite) {
            qemu_printf("\n");
        }
        g_free(key);
    }
}

/*
 * Return whether dumping the given QObject with dump_qobject() would
 * yield an empty dump, i.e. not print anything.
 */
static bool qobject_is_empty_dump(const QObject *obj)
{
    switch (qobject_type(obj)) {
    case QTYPE_QNUM:
    case QTYPE_QSTRING:
    case QTYPE_QBOOL:
        return false;

    case QTYPE_QDICT:
        return qdict_size(qobject_to(QDict, obj)) == 0;

    case QTYPE_QLIST:
        return qlist_empty(qobject_to(QList, obj));

    default:
        abort();
    }
}

/**
 * Dumps the given ImageInfoSpecific object in a human-readable form,
 * prepending an optional prefix if the dump is not empty.
 */
void bdrv_image_info_specific_dump(ImageInfoSpecific *info_spec,
                                   const char *prefix,
                                   int indentation)
{
    QObject *obj, *data;
    Visitor *v = qobject_output_visitor_new(&obj);

    visit_type_ImageInfoSpecific(v, NULL, &info_spec, &error_abort);
    visit_complete(v, &obj);
    data = qdict_get(qobject_to(QDict, obj), "data");
    if (!qobject_is_empty_dump(data)) {
        if (prefix) {
            qemu_printf("%*s%s", indentation * 4, "", prefix);
        }
        dump_qobject(indentation + 1, data);
    }
    qobject_unref(obj);
    visit_free(v);
}

/**
 * Print the given @info object in human-readable form.  Every field is indented
 * using the given @indentation (four spaces per indentation level).
 *
 * When using this to print a whole block graph, @protocol can be set to true to
 * signify that the given information is associated with a protocol node, i.e.
 * just data storage for an image, such that the data it presents is not really
 * a full VM disk.  If so, several fields change name: For example, "virtual
 * size" is printed as "file length".
 * (Consider a qcow2 image, which is represented by a qcow2 node and a file
 * node.  Printing a "virtual size" for the file node does not make sense,
 * because without the qcow2 node, it is not really a guest disk, so it does not
 * have a "virtual size".  Therefore, we call it "file length" instead.)
 *
 * @protocol is ignored when @indentation is 0, because we take that to mean
 * that the associated node is the root node in the queried block graph, and
 * thus is always to be interpreted as a standalone guest disk.
 */
void bdrv_node_info_dump(BlockNodeInfo *info, int indentation, bool protocol)
{
    char *size_buf, *dsize_buf;
    g_autofree char *ind_s = g_strdup_printf("%*s", indentation * 4, "");

    if (indentation == 0) {
        /* Top level, consider this a normal image */
        protocol = false;
    }

    if (!info->has_actual_size) {
        dsize_buf = g_strdup("unavailable");
    } else {
        dsize_buf = size_to_str(info->actual_size);
    }
    size_buf = size_to_str(info->virtual_size);
    qemu_printf("%s%s: %s\n"
                "%s%s: %s\n"
                "%s%s: %s (%" PRId64 " bytes)\n"
                "%sdisk size: %s\n",
                ind_s, protocol ? "filename" : "image", info->filename,
                ind_s, protocol ? "protocol type" : "file format",
                info->format,
                ind_s, protocol ? "file length" : "virtual size",
                size_buf, info->virtual_size,
                ind_s, dsize_buf);
    g_free(size_buf);
    g_free(dsize_buf);

    if (info->has_encrypted && info->encrypted) {
        qemu_printf("%sencrypted: yes\n", ind_s);
    }

    if (info->has_cluster_size) {
        qemu_printf("%scluster_size: %" PRId64 "\n",
                    ind_s, info->cluster_size);
    }

    if (info->has_dirty_flag && info->dirty_flag) {
        qemu_printf("%scleanly shut down: no\n", ind_s);
    }

    if (info->backing_filename) {
        qemu_printf("%sbacking file: %s", ind_s, info->backing_filename);
        if (!info->full_backing_filename) {
            qemu_printf(" (cannot determine actual path)");
        } else if (strcmp(info->backing_filename,
                          info->full_backing_filename) != 0) {
            qemu_printf(" (actual path: %s)", info->full_backing_filename);
        }
        qemu_printf("\n");
        if (info->backing_filename_format) {
            qemu_printf("%sbacking file format: %s\n",
                        ind_s, info->backing_filename_format);
        }
    }

    if (info->has_snapshots) {
        SnapshotInfoList *elem;

        qemu_printf("%sSnapshot list:\n", ind_s);
        qemu_printf("%s", ind_s);
        bdrv_snapshot_dump(NULL);
        qemu_printf("\n");

        /* Ideally bdrv_snapshot_dump() would operate on SnapshotInfoList but
         * we convert to the block layer's native QEMUSnapshotInfo for now.
         */
        for (elem = info->snapshots; elem; elem = elem->next) {
            QEMUSnapshotInfo sn = {
                .vm_state_size = elem->value->vm_state_size,
                .date_sec = elem->value->date_sec,
                .date_nsec = elem->value->date_nsec,
                .vm_clock_nsec = elem->value->vm_clock_sec * 1000000000ULL +
                                 elem->value->vm_clock_nsec,
                .icount = elem->value->has_icount ?
                          elem->value->icount : -1ULL,
            };

            pstrcpy(sn.id_str, sizeof(sn.id_str), elem->value->id);
            pstrcpy(sn.name, sizeof(sn.name), elem->value->name);
            qemu_printf("%s", ind_s);
            bdrv_snapshot_dump(&sn);
            qemu_printf("\n");
        }
    }

    if (info->format_specific) {
        bdrv_image_info_specific_dump(info->format_specific,
                                      "Format specific information:\n",
                                      indentation);
    }
}
