[Qemu-devel] [PATCH V4 2/2] qemu-img: Add json output option to the info command.

2012-08-22 Thread Benoît Canet
This option --output=[human|json] make qemu-img info output on
human or JSON representation at the choice of the user.

example:
{
snapshots: [
{
vm-clock-nsec: 20637102488,
name: vm-20120821145509,
date-sec: 1345553709,
date-nsec: 220289000,
id: 1,
vm-state-size: 96522745
},
{
vm-clock-nsec: 46028210866,
name: vm-20120821154059,
date-sec: 1345556459,
date-nsec: 171392000,
id: 2,
vm-state-size: 101208714
}
],
virtual-size: 1073741824,
filename: snap.qcow2,
cluster-size: 65536,
format: qcow2,
actual-size: 985587712,
dirty-flag: false
}

Signed-off-by: Benoit Canet ben...@irqsave.net
---
 Makefile   |3 +-
 qemu-img.c |  252 +---
 2 files changed, 210 insertions(+), 45 deletions(-)

diff --git a/Makefile b/Makefile
index ab82ef3..9ba064b 100644
--- a/Makefile
+++ b/Makefile
@@ -160,7 +160,8 @@ tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o 
qemu-timer.o \
iohandler.o cutils.o iov.o async.o
 tools-obj-$(CONFIG_POSIX) += compatfd.o
 
-qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y)
+qemu-img$(EXESUF): qemu-img.o $(tools-obj-y) $(block-obj-y) $(qapi-obj-y) \
+  qapi-visit.o qapi-types.o
 qemu-nbd$(EXESUF): qemu-nbd.o $(tools-obj-y) $(block-obj-y)
 qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y)
 
diff --git a/qemu-img.c b/qemu-img.c
index 80cfb9b..1591898 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -21,12 +21,16 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  * THE SOFTWARE.
  */
+#include qapi-visit.h
+#include qapi/qmp-output-visitor.h
+#include qjson.h
 #include qemu-common.h
 #include qemu-option.h
 #include qemu-error.h
 #include osdep.h
 #include sysemu.h
 #include block_int.h
+#include getopt.h
 #include stdio.h
 
 #ifdef _WIN32
@@ -84,6 +88,7 @@ static void help(void)
  '-p' show progress of command (only certain commands)\n
  '-S' indicates the consecutive number of bytes that must contain 
only zeros\n
   for qemu-img to create a sparse image during conversion\n
+ '--output' takes the format in which the output must be done 
(human or json)\n
\n
Parameters to check subcommand:\n
  '-r' tries to repair any inconsistencies that are found during 
the check.\n
@@ -1083,7 +1088,6 @@ out:
 return 0;
 }
 
-
 static void dump_snapshots(BlockDriverState *bs)
 {
 QEMUSnapshotInfo *sn_tab, *sn;
@@ -1102,21 +1106,188 @@ static void dump_snapshots(BlockDriverState *bs)
 g_free(sn_tab);
 }
 
-static int img_info(int argc, char **argv)
+static void collect_snapshots(BlockDriverState *bs , ImageInfo *info)
+{
+int i, sn_count;
+QEMUSnapshotInfo *sn_tab = NULL;
+SnapshotInfoList *sn_info_list, *cur_item = NULL;
+sn_count = bdrv_snapshot_list(bs, sn_tab);
+
+for (i = 0; i  sn_count; i++) {
+info-has_snapshots = true;
+sn_info_list = g_new0(SnapshotInfoList, 1);
+
+sn_info_list-value= g_new0(SnapshotInfo, 1);
+sn_info_list-value-id= g_strdup(sn_tab[i].id_str);
+sn_info_list-value-name  = g_strdup(sn_tab[i].name);
+sn_info_list-value-vm_state_size = sn_tab[i].vm_state_size;
+sn_info_list-value-date_sec  = sn_tab[i].date_sec;
+sn_info_list-value-date_nsec = sn_tab[i].date_nsec;
+sn_info_list-value-vm_clock_nsec = sn_tab[i].vm_clock_nsec;
+
+/* XXX: waiting for the qapi to support GSList */
+if (!cur_item) {
+info-snapshots = cur_item = sn_info_list;
+} else {
+cur_item-next = sn_info_list;
+cur_item = sn_info_list;
+}
+
+}
+
+g_free(sn_tab);
+}
+
+static void dump_json_image_info(ImageInfo *info)
+{
+Error *errp = NULL;
+QString *str;
+QmpOutputVisitor *ov = qmp_output_visitor_new();
+QObject *obj;
+visit_type_ImageInfo(qmp_output_get_visitor(ov),
+ info, NULL, errp);
+obj = qmp_output_get_qobject(ov);
+str = qobject_to_json_pretty(obj);
+assert(str != NULL);
+printf(%s\n, qstring_get_str(str));
+qobject_decref(obj);
+qmp_output_visitor_cleanup(ov);
+QDECREF(str);
+}
+
+static void collect_backing_file_format(ImageInfo *info, char *filename)
+{
+BlockDriverState *bs = NULL;
+bs = bdrv_new_open(filename, NULL,
+   BDRV_O_FLAGS | BDRV_O_NO_BACKING);
+if (!bs) {
+return;
+}
+info-backing_filename_format =
+g_strdup(bdrv_get_format_name(bs));
+bdrv_delete(bs);
+info-has_backing_filename_format = true;
+}
+
+static void collect_image_info(BlockDriverState *bs,
+   ImageInfo *info,
+  

Re: [Qemu-devel] [PATCH V4 2/2] qemu-img: Add json output option to the info command.

2012-08-22 Thread Eric Blake
On 08/22/2012 06:45 AM, Benoît Canet wrote:
 This option --output=[human|json] make qemu-img info output on
 human or JSON representation at the choice of the user.
 

 @@ -1083,7 +1088,6 @@ out:
  return 0;
  }
  
 -
  static void dump_snapshots(BlockDriverState *bs)
  {

Spurious whitespace change.

 +static int img_info(int argc, char **argv)
 +{
 +int c;
 +bool human = false, json = false;
 +const char *filename, *fmt, *output;
 +BlockDriverState *bs;
 +ImageInfo *info;
  
  fmt = NULL;
 +output = NULL;
  for(;;) {
 -c = getopt(argc, argv, f:h);
 +int option_index = 0;
 +static struct option long_options[] = {
 +{help, no_argument, 0, 'h'},
 +{format, required_argument, 0, 'f'},
 +{output, required_argument, 0, 'm'},

I would define a constant, such as 'enum {OPTION_FORMAT=256};', so that
you don't risk future confusion...

 +{0, 0, 0, 0}
 +};
 +c = getopt_long(argc, argv, f:h,

...if we later do add an 'm' short option.

 +long_options, option_index);
  if (c == -1) {
  break;
  }
 @@ -1128,6 +1299,9 @@ static int img_info(int argc, char **argv)
  case 'f':
  fmt = optarg;
  break;
 +case 'm':

Given the above, this would reuse your new named value.

 @@ -1135,52 +1309,42 @@ static int img_info(int argc, char **argv)
  }
  filename = argv[optind++];
  
 +if (output  !strncmp(output, json, strlen(json))) {

Why strncmp?  It ignores trailing garbage (as in --output=jsonoops).
Stick to strcmp.

 +json = true;
 +} else if (output  !strncmp(output, human, strlen(human))) {

And again.

 +human = true;
 +} else {
 +fprintf(stderr,
 +Error: --output must be used with human or json as 
 argument.\n);
 +return 1;
 +}

If we get here, and --output=... was not given, then both human and json
are false.  That's a problem, since...

 +
 +if (human) {
 +dump_human_image_info(info);
 +dump_snapshots(bs);
  }
 -bdrv_get_backing_filename(bs, backing_filename, 
 sizeof(backing_filename));
 -if (backing_filename[0] != '\0') {
 -bdrv_get_full_backing_filename(bs, backing_filename2,
 -   sizeof(backing_filename2));
 -printf(backing file: %s, backing_filename);
 -if (strcmp(backing_filename, backing_filename2) != 0) {
 -printf( (actual path: %s), backing_filename2);
 -}
 -putchar('\n');
 +
 +if (json) {
 +collect_snapshots(bs, info);
 +dump_json_image_info(info);
  }
 -dump_snapshots(bs);
 +
 +qapi_free_ImageInfo(info);

...you will end up with no output.  You want to default to human output
for back-compat to older usage.

-- 
Eric Blake   ebl...@redhat.com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature