From patchwork Mon Sep 23 12:09:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 277163 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id EF6182C0112 for ; Mon, 23 Sep 2013 22:11:50 +1000 (EST) Received: from localhost ([::1]:40256 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VO4zU-0001Y9-Ar for incoming@patchwork.ozlabs.org; Mon, 23 Sep 2013 08:11:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41575) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VO4xQ-0007Mw-0B for qemu-devel@nongnu.org; Mon, 23 Sep 2013 08:09:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VO4xH-0006UA-Et for qemu-devel@nongnu.org; Mon, 23 Sep 2013 08:09:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:30168) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VO4xH-0006U4-7B for qemu-devel@nongnu.org; Mon, 23 Sep 2013 08:09:31 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r8NC9UTj003453 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 23 Sep 2013 08:09:30 -0400 Received: from localhost (dhcp-200-247.str.redhat.com [10.33.200.247]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r8NC9TqM023335 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Mon, 23 Sep 2013 08:09:30 -0400 From: Max Reitz To: qemu-devel@nongnu.org Date: Mon, 23 Sep 2013 14:09:19 +0200 Message-Id: <1379938162-14005-4-git-send-email-mreitz@redhat.com> In-Reply-To: <1379938162-14005-1-git-send-email-mreitz@redhat.com> References: <1379938162-14005-1-git-send-email-mreitz@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Kevin Wolf , Fam Zheng , Stefan Hajnoczi , Max Reitz Subject: [Qemu-devel] [PATCH v5 3/6] block/qapi: Human-readable ImageInfoSpecific dump X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add a function for generically dumping the ImageInfoSpecific information in a human-readable format to block/qapi.c. Use this function in bdrv_image_info_dump and qemu-io-cmds.c:info_f to allow qemu-img info resp. qemu-io -c info to print that format specific information. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qapi.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/block/qapi.h | 2 + qemu-io-cmds.c | 9 ++++ 3 files changed, 132 insertions(+) diff --git a/block/qapi.c b/block/qapi.c index ab1dd24..e7d1591 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -25,6 +25,9 @@ #include "block/qapi.h" #include "block/block_int.h" #include "qmp-commands.h" +#include "qapi-visit.h" +#include "qapi/qmp-output-visitor.h" +#include "qapi/qmp/types.h" /* * Returns 0 on success, with *p_list either set to describe snapshot @@ -426,6 +429,119 @@ void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f, } } +static void dump_qdict(fprintf_function func_fprintf, void *f, int indentation, + QDict *dict); +static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation, + QList *list); + +static void dump_qobject(fprintf_function func_fprintf, void *f, + int comp_indent, QObject *obj) +{ + switch (qobject_type(obj)) { + case QTYPE_QINT: { + QInt *value = qobject_to_qint(obj); + func_fprintf(f, "%" PRId64, qint_get_int(value)); + break; + } + case QTYPE_QSTRING: { + QString *value = qobject_to_qstring(obj); + func_fprintf(f, "%s", qstring_get_str(value)); + break; + } + case QTYPE_QDICT: { + QDict *value = qobject_to_qdict(obj); + dump_qdict(func_fprintf, f, comp_indent, value); + break; + } + case QTYPE_QLIST: { + QList *value = qobject_to_qlist(obj); + dump_qlist(func_fprintf, f, comp_indent, value); + break; + } + case QTYPE_QFLOAT: { + QFloat *value = qobject_to_qfloat(obj); + func_fprintf(f, "%g", qfloat_get_double(value)); + break; + } + case QTYPE_QBOOL: { + QBool *value = qobject_to_qbool(obj); + func_fprintf(f, "%s", qbool_get_int(value) ? "true" : "false"); + break; + } + case QTYPE_QERROR: { + QString *value = qerror_human((QError *)obj); + func_fprintf(f, "%s", qstring_get_str(value)); + break; + } + case QTYPE_NONE: + break; + case QTYPE_MAX: + default: + abort(); + } +} + +static void dump_qlist(fprintf_function func_fprintf, void *f, int indentation, + QList *list) +{ + const QListEntry *entry; + int i = 0; + + for (entry = qlist_first(list); entry; entry = qlist_next(entry), i++) { + qtype_code type = qobject_type(entry->value); + bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST); + const char *format = composite ? "%*s[%i]:\n" : "%*s[%i]: "; + + func_fprintf(f, format, indentation * 4, "", i); + dump_qobject(func_fprintf, f, indentation + 1, entry->value); + if (!composite) { + func_fprintf(f, "\n"); + } + } +} + +static void dump_qdict(fprintf_function func_fprintf, void *f, int indentation, + QDict *dict) +{ + const QDictEntry *entry; + + for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) { + qtype_code type = qobject_type(entry->value); + bool composite = (type == QTYPE_QDICT || type == QTYPE_QLIST); + const char *format = composite ? "%*s%s:\n" : "%*s%s: "; + char key[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; + + func_fprintf(f, format, indentation * 4, "", key); + dump_qobject(func_fprintf, f, indentation + 1, entry->value); + if (!composite) { + func_fprintf(f, "\n"); + } + } +} + +void bdrv_image_info_specific_dump(fprintf_function func_fprintf, void *f, + ImageInfoSpecific *info_spec) +{ + Error *local_err = NULL; + QmpOutputVisitor *ov = qmp_output_visitor_new(); + QObject *obj, *data; + + visit_type_ImageInfoSpecific(qmp_output_get_visitor(ov), &info_spec, NULL, + &local_err); + obj = qmp_output_get_qobject(ov); + assert(qobject_type(obj) == QTYPE_QDICT); + data = qdict_get(qobject_to_qdict(obj), "data"); + dump_qobject(func_fprintf, f, 0, data); + qmp_output_visitor_cleanup(ov); +} + void bdrv_image_info_dump(fprintf_function func_fprintf, void *f, ImageInfo *info) { @@ -496,4 +612,9 @@ void bdrv_image_info_dump(fprintf_function func_fprintf, void *f, func_fprintf(f, "\n"); } } + + if (info->has_format_specific) { + func_fprintf(f, "Format specific information:\n"); + bdrv_image_info_specific_dump(func_fprintf, f, info->format_specific); + } } diff --git a/include/block/qapi.h b/include/block/qapi.h index 0496cc9..9518ee4 100644 --- a/include/block/qapi.h +++ b/include/block/qapi.h @@ -42,6 +42,8 @@ BlockStats *bdrv_query_stats(const BlockDriverState *bs); void bdrv_snapshot_dump(fprintf_function func_fprintf, void *f, QEMUSnapshotInfo *sn); +void bdrv_image_info_specific_dump(fprintf_function func_fprintf, void *f, + ImageInfoSpecific *info_spec); void bdrv_image_info_dump(fprintf_function func_fprintf, void *f, ImageInfo *info); #endif diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c index 8565d49..667f4e4 100644 --- a/qemu-io-cmds.c +++ b/qemu-io-cmds.c @@ -10,6 +10,7 @@ #include "qemu-io.h" #include "block/block_int.h" +#include "block/qapi.h" #include "qemu/main-loop.h" #define CMD_NOFILE_OK 0x01 @@ -1678,6 +1679,7 @@ static const cmdinfo_t length_cmd = { static int info_f(BlockDriverState *bs, int argc, char **argv) { BlockDriverInfo bdi; + ImageInfoSpecific *spec_info; char s1[64], s2[64]; int ret; @@ -1699,6 +1701,13 @@ static int info_f(BlockDriverState *bs, int argc, char **argv) printf("cluster size: %s\n", s1); printf("vm state offset: %s\n", s2); + spec_info = bdrv_get_specific_info(bs); + if (spec_info) { + printf("Format specific information:\n"); + bdrv_image_info_specific_dump(fprintf, stdout, spec_info); + qapi_free_ImageInfoSpecific(spec_info); + } + return 0; }