qemu-img: Add json output option to the info command.
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": 637102488,
            "name": "vm-20120821145509",
            "date-sec": 1345553709,
            "date-nsec": 220289000,
            "vm-clock-sec": 20,
            "id": "1",
            "vm-state-size": 96522745
        },
        {
            "vm-clock-nsec": 28210866,
            "name": "vm-20120821154059",
            "date-sec": 1345556459,
            "date-nsec": 171392000,
            "vm-clock-sec": 46,
            "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 <benoit@irqsave.net>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
			
			
This commit is contained in:
		
							parent
							
								
									c249ee6825
								
							
						
					
					
						commit
						c054b3fd78
					
				
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							@ -157,7 +157,8 @@ tools-obj-y = $(oslib-obj-y) $(trace-obj-y) qemu-tool.o qemu-timer.o \
 | 
				
			|||||||
	iohandler.o cutils.o iov.o async.o
 | 
						iohandler.o cutils.o iov.o async.o
 | 
				
			||||||
tools-obj-$(CONFIG_POSIX) += compatfd.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-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)
 | 
					qemu-io$(EXESUF): qemu-io.o cmd.o $(tools-obj-y) $(block-obj-y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -34,9 +34,9 @@ STEXI
 | 
				
			|||||||
ETEXI
 | 
					ETEXI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF("info", img_info,
 | 
					DEF("info", img_info,
 | 
				
			||||||
    "info [-f fmt] filename")
 | 
					    "info [-f fmt] [--output=ofmt] filename")
 | 
				
			||||||
STEXI
 | 
					STEXI
 | 
				
			||||||
@item info [-f @var{fmt}] @var{filename}
 | 
					@item info [-f @var{fmt}] [--output=@var{ofmt}] @var{filename}
 | 
				
			||||||
ETEXI
 | 
					ETEXI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF("snapshot", img_snapshot,
 | 
					DEF("snapshot", img_snapshot,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										236
									
								
								qemu-img.c
									
									
									
									
									
								
							
							
						
						
									
										236
									
								
								qemu-img.c
									
									
									
									
									
								
							@ -21,12 +21,16 @@
 | 
				
			|||||||
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
					 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
				
			||||||
 * THE SOFTWARE.
 | 
					 * THE SOFTWARE.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#include "qapi-visit.h"
 | 
				
			||||||
 | 
					#include "qapi/qmp-output-visitor.h"
 | 
				
			||||||
 | 
					#include "qjson.h"
 | 
				
			||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "qemu-option.h"
 | 
					#include "qemu-option.h"
 | 
				
			||||||
#include "qemu-error.h"
 | 
					#include "qemu-error.h"
 | 
				
			||||||
#include "osdep.h"
 | 
					#include "osdep.h"
 | 
				
			||||||
#include "sysemu.h"
 | 
					#include "sysemu.h"
 | 
				
			||||||
#include "block_int.h"
 | 
					#include "block_int.h"
 | 
				
			||||||
 | 
					#include <getopt.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
@ -84,6 +88,7 @@ static void help(void)
 | 
				
			|||||||
           "  '-p' show progress of command (only certain commands)\n"
 | 
					           "  '-p' show progress of command (only certain commands)\n"
 | 
				
			||||||
           "  '-S' indicates the consecutive number of bytes that must contain only zeros\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"
 | 
					           "       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"
 | 
					           "\n"
 | 
				
			||||||
           "Parameters to check subcommand:\n"
 | 
					           "Parameters to check subcommand:\n"
 | 
				
			||||||
           "  '-r' tries to repair any inconsistencies that are found during the check.\n"
 | 
					           "  '-r' tries to repair any inconsistencies that are found during the check.\n"
 | 
				
			||||||
@ -1102,21 +1107,174 @@ static void dump_snapshots(BlockDriverState *bs)
 | 
				
			|||||||
    g_free(sn_tab);
 | 
					    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 *info_list, *cur_item = NULL;
 | 
				
			||||||
 | 
					    sn_count = bdrv_snapshot_list(bs, &sn_tab);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (i = 0; i < sn_count; i++) {
 | 
				
			||||||
 | 
					        info->has_snapshots = true;
 | 
				
			||||||
 | 
					        info_list = g_new0(SnapshotInfoList, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        info_list->value                = g_new0(SnapshotInfo, 1);
 | 
				
			||||||
 | 
					        info_list->value->id            = g_strdup(sn_tab[i].id_str);
 | 
				
			||||||
 | 
					        info_list->value->name          = g_strdup(sn_tab[i].name);
 | 
				
			||||||
 | 
					        info_list->value->vm_state_size = sn_tab[i].vm_state_size;
 | 
				
			||||||
 | 
					        info_list->value->date_sec      = sn_tab[i].date_sec;
 | 
				
			||||||
 | 
					        info_list->value->date_nsec     = sn_tab[i].date_nsec;
 | 
				
			||||||
 | 
					        info_list->value->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
 | 
				
			||||||
 | 
					        info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* XXX: waiting for the qapi to support qemu-queue.h types */
 | 
				
			||||||
 | 
					        if (!cur_item) {
 | 
				
			||||||
 | 
					            info->snapshots = cur_item = info_list;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            cur_item->next = info_list;
 | 
				
			||||||
 | 
					            cur_item = 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_image_info(BlockDriverState *bs,
 | 
				
			||||||
 | 
					                   ImageInfo *info,
 | 
				
			||||||
 | 
					                   const char *filename,
 | 
				
			||||||
 | 
					                   const char *fmt)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int c;
 | 
					 | 
				
			||||||
    const char *filename, *fmt;
 | 
					 | 
				
			||||||
    BlockDriverState *bs;
 | 
					 | 
				
			||||||
    char size_buf[128], dsize_buf[128];
 | 
					 | 
				
			||||||
    uint64_t total_sectors;
 | 
					    uint64_t total_sectors;
 | 
				
			||||||
    int64_t allocated_size;
 | 
					 | 
				
			||||||
    char backing_filename[1024];
 | 
					    char backing_filename[1024];
 | 
				
			||||||
    char backing_filename2[1024];
 | 
					    char backing_filename2[1024];
 | 
				
			||||||
    BlockDriverInfo bdi;
 | 
					    BlockDriverInfo bdi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bdrv_get_geometry(bs, &total_sectors);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    info->filename        = g_strdup(filename);
 | 
				
			||||||
 | 
					    info->format          = g_strdup(bdrv_get_format_name(bs));
 | 
				
			||||||
 | 
					    info->virtual_size    = total_sectors * 512;
 | 
				
			||||||
 | 
					    info->actual_size     = bdrv_get_allocated_file_size(bs);
 | 
				
			||||||
 | 
					    info->has_actual_size = info->actual_size >= 0;
 | 
				
			||||||
 | 
					    if (bdrv_is_encrypted(bs)) {
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
 | 
				
			||||||
 | 
					    if (backing_filename[0] != '\0') {
 | 
				
			||||||
 | 
					        info->backing_filename = g_strdup(backing_filename);
 | 
				
			||||||
 | 
					        info->has_backing_filename = true;
 | 
				
			||||||
 | 
					        bdrv_get_full_backing_filename(bs, backing_filename2,
 | 
				
			||||||
 | 
					                                       sizeof(backing_filename2));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (strcmp(backing_filename, backing_filename2) != 0) {
 | 
				
			||||||
 | 
					            info->full_backing_filename =
 | 
				
			||||||
 | 
					                        g_strdup(backing_filename2);
 | 
				
			||||||
 | 
					            info->has_full_backing_filename = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (bs->backing_format[0]) {
 | 
				
			||||||
 | 
					            info->backing_filename_format = g_strdup(bs->backing_format);
 | 
				
			||||||
 | 
					            info->has_backing_filename_format = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void dump_human_image_info(ImageInfo *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    char size_buf[128], dsize_buf[128];
 | 
				
			||||||
 | 
					    if (!info->has_actual_size) {
 | 
				
			||||||
 | 
					        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
 | 
				
			||||||
 | 
					                                info->actual_size);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
 | 
				
			||||||
 | 
					    printf("image: %s\n"
 | 
				
			||||||
 | 
					           "file format: %s\n"
 | 
				
			||||||
 | 
					           "virtual size: %s (%" PRId64 " bytes)\n"
 | 
				
			||||||
 | 
					           "disk size: %s\n",
 | 
				
			||||||
 | 
					           info->filename, info->format, size_buf,
 | 
				
			||||||
 | 
					           info->virtual_size,
 | 
				
			||||||
 | 
					           dsize_buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (info->has_encrypted && info->encrypted) {
 | 
				
			||||||
 | 
					        printf("encrypted: yes\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (info->has_cluster_size) {
 | 
				
			||||||
 | 
					        printf("cluster_size: %" PRId64 "\n", info->cluster_size);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (info->has_dirty_flag && info->dirty_flag) {
 | 
				
			||||||
 | 
					        printf("cleanly shut down: no\n");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (info->has_backing_filename) {
 | 
				
			||||||
 | 
					        printf("backing file: %s", info->backing_filename);
 | 
				
			||||||
 | 
					        if (info->has_full_backing_filename) {
 | 
				
			||||||
 | 
					            printf(" (actual path: %s)", info->full_backing_filename);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        putchar('\n');
 | 
				
			||||||
 | 
					        if (info->has_backing_filename_format) {
 | 
				
			||||||
 | 
					            printf("backing file format: %s\n", info->backing_filename_format);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {OPTION_OUTPUT = 256};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum OutputFormat {
 | 
				
			||||||
 | 
					    OFORMAT_JSON,
 | 
				
			||||||
 | 
					    OFORMAT_HUMAN,
 | 
				
			||||||
 | 
					} OutputFormat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int img_info(int argc, char **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int c;
 | 
				
			||||||
 | 
					    OutputFormat output_format = OFORMAT_HUMAN;
 | 
				
			||||||
 | 
					    const char *filename, *fmt, *output;
 | 
				
			||||||
 | 
					    BlockDriverState *bs;
 | 
				
			||||||
 | 
					    ImageInfo *info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fmt = NULL;
 | 
					    fmt = NULL;
 | 
				
			||||||
 | 
					    output = NULL;
 | 
				
			||||||
    for(;;) {
 | 
					    for(;;) {
 | 
				
			||||||
        c = getopt(argc, argv, "f:h");
 | 
					        int option_index = 0;
 | 
				
			||||||
 | 
					        static const struct option long_options[] = {
 | 
				
			||||||
 | 
					            {"help", no_argument, 0, 'h'},
 | 
				
			||||||
 | 
					            {"format", required_argument, 0, 'f'},
 | 
				
			||||||
 | 
					            {"output", required_argument, 0, OPTION_OUTPUT},
 | 
				
			||||||
 | 
					            {0, 0, 0, 0}
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        c = getopt_long(argc, argv, "f:h",
 | 
				
			||||||
 | 
					                        long_options, &option_index);
 | 
				
			||||||
        if (c == -1) {
 | 
					        if (c == -1) {
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -1128,6 +1286,9 @@ static int img_info(int argc, char **argv)
 | 
				
			|||||||
        case 'f':
 | 
					        case 'f':
 | 
				
			||||||
            fmt = optarg;
 | 
					            fmt = optarg;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        case OPTION_OUTPUT:
 | 
				
			||||||
 | 
					            output = optarg;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (optind >= argc) {
 | 
					    if (optind >= argc) {
 | 
				
			||||||
@ -1135,48 +1296,35 @@ static int img_info(int argc, char **argv)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    filename = argv[optind++];
 | 
					    filename = argv[optind++];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (output && !strcmp(output, "json")) {
 | 
				
			||||||
 | 
					        output_format = OFORMAT_JSON;
 | 
				
			||||||
 | 
					    } else if (output && !strcmp(output, "human")) {
 | 
				
			||||||
 | 
					        output_format = OFORMAT_HUMAN;
 | 
				
			||||||
 | 
					    } else if (output) {
 | 
				
			||||||
 | 
					        error_report("--output must be used with human or json as argument.");
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
 | 
					    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
 | 
				
			||||||
    if (!bs) {
 | 
					    if (!bs) {
 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    bdrv_get_geometry(bs, &total_sectors);
 | 
					
 | 
				
			||||||
    get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
 | 
					    info = g_new0(ImageInfo, 1);
 | 
				
			||||||
    allocated_size = bdrv_get_allocated_file_size(bs);
 | 
					    collect_image_info(bs, info, filename, fmt);
 | 
				
			||||||
    if (allocated_size < 0) {
 | 
					
 | 
				
			||||||
        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
 | 
					    switch (output_format) {
 | 
				
			||||||
    } else {
 | 
					    case OFORMAT_HUMAN:
 | 
				
			||||||
        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
 | 
					        dump_human_image_info(info);
 | 
				
			||||||
                                allocated_size);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    printf("image: %s\n"
 | 
					 | 
				
			||||||
           "file format: %s\n"
 | 
					 | 
				
			||||||
           "virtual size: %s (%" PRId64 " bytes)\n"
 | 
					 | 
				
			||||||
           "disk size: %s\n",
 | 
					 | 
				
			||||||
           filename, bdrv_get_format_name(bs), size_buf,
 | 
					 | 
				
			||||||
           (total_sectors * 512),
 | 
					 | 
				
			||||||
           dsize_buf);
 | 
					 | 
				
			||||||
    if (bdrv_is_encrypted(bs)) {
 | 
					 | 
				
			||||||
        printf("encrypted: yes\n");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (bdrv_get_info(bs, &bdi) >= 0) {
 | 
					 | 
				
			||||||
        if (bdi.cluster_size != 0) {
 | 
					 | 
				
			||||||
            printf("cluster_size: %d\n", bdi.cluster_size);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (bdi.is_dirty) {
 | 
					 | 
				
			||||||
            printf("cleanly shut down: no\n");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    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');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
        dump_snapshots(bs);
 | 
					        dump_snapshots(bs);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    case OFORMAT_JSON:
 | 
				
			||||||
 | 
					        collect_snapshots(bs, info);
 | 
				
			||||||
 | 
					        dump_json_image_info(info);
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qapi_free_ImageInfo(info);
 | 
				
			||||||
    bdrv_delete(bs);
 | 
					    bdrv_delete(bs);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -129,12 +129,13 @@ created as a copy on write image of the specified base image; the
 | 
				
			|||||||
@var{backing_file} should have the same content as the input's base image,
 | 
					@var{backing_file} should have the same content as the input's base image,
 | 
				
			||||||
however the path, image format, etc may differ.
 | 
					however the path, image format, etc may differ.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@item info [-f @var{fmt}] @var{filename}
 | 
					@item info [-f @var{fmt}] [--output=@var{ofmt}] @var{filename}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Give information about the disk image @var{filename}. Use it in
 | 
					Give information about the disk image @var{filename}. Use it in
 | 
				
			||||||
particular to know the size reserved on disk which can be different
 | 
					particular to know the size reserved on disk which can be different
 | 
				
			||||||
from the displayed size. If VM snapshots are stored in the disk image,
 | 
					from the displayed size. If VM snapshots are stored in the disk image,
 | 
				
			||||||
they are displayed too.
 | 
					they are displayed too. The command can output in the format @var{ofmt}
 | 
				
			||||||
 | 
					which is either @code{human} or @code{json}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@item snapshot [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot} ] @var{filename}
 | 
					@item snapshot [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot} ] @var{filename}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user