Revision c054b3fd qemu-img.c

b/qemu-img.c
21 21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 22
 * THE SOFTWARE.
23 23
 */
24
#include "qapi-visit.h"
25
#include "qapi/qmp-output-visitor.h"
26
#include "qjson.h"
24 27
#include "qemu-common.h"
25 28
#include "qemu-option.h"
26 29
#include "qemu-error.h"
27 30
#include "osdep.h"
28 31
#include "sysemu.h"
29 32
#include "block_int.h"
33
#include <getopt.h>
30 34
#include <stdio.h>
31 35

  
32 36
#ifdef _WIN32
......
84 88
           "  '-p' show progress of command (only certain commands)\n"
85 89
           "  '-S' indicates the consecutive number of bytes that must contain only zeros\n"
86 90
           "       for qemu-img to create a sparse image during conversion\n"
91
           "  '--output' takes the format in which the output must be done (human or json)\n"
87 92
           "\n"
88 93
           "Parameters to check subcommand:\n"
89 94
           "  '-r' tries to repair any inconsistencies that are found during the check.\n"
......
1102 1107
    g_free(sn_tab);
1103 1108
}
1104 1109

  
1105
static int img_info(int argc, char **argv)
1110
static void collect_snapshots(BlockDriverState *bs , ImageInfo *info)
1111
{
1112
    int i, sn_count;
1113
    QEMUSnapshotInfo *sn_tab = NULL;
1114
    SnapshotInfoList *info_list, *cur_item = NULL;
1115
    sn_count = bdrv_snapshot_list(bs, &sn_tab);
1116

  
1117
    for (i = 0; i < sn_count; i++) {
1118
        info->has_snapshots = true;
1119
        info_list = g_new0(SnapshotInfoList, 1);
1120

  
1121
        info_list->value                = g_new0(SnapshotInfo, 1);
1122
        info_list->value->id            = g_strdup(sn_tab[i].id_str);
1123
        info_list->value->name          = g_strdup(sn_tab[i].name);
1124
        info_list->value->vm_state_size = sn_tab[i].vm_state_size;
1125
        info_list->value->date_sec      = sn_tab[i].date_sec;
1126
        info_list->value->date_nsec     = sn_tab[i].date_nsec;
1127
        info_list->value->vm_clock_sec  = sn_tab[i].vm_clock_nsec / 1000000000;
1128
        info_list->value->vm_clock_nsec = sn_tab[i].vm_clock_nsec % 1000000000;
1129

  
1130
        /* XXX: waiting for the qapi to support qemu-queue.h types */
1131
        if (!cur_item) {
1132
            info->snapshots = cur_item = info_list;
1133
        } else {
1134
            cur_item->next = info_list;
1135
            cur_item = info_list;
1136
        }
1137

  
1138
    }
1139

  
1140
    g_free(sn_tab);
1141
}
1142

  
1143
static void dump_json_image_info(ImageInfo *info)
1144
{
1145
    Error *errp = NULL;
1146
    QString *str;
1147
    QmpOutputVisitor *ov = qmp_output_visitor_new();
1148
    QObject *obj;
1149
    visit_type_ImageInfo(qmp_output_get_visitor(ov),
1150
                         &info, NULL, &errp);
1151
    obj = qmp_output_get_qobject(ov);
1152
    str = qobject_to_json_pretty(obj);
1153
    assert(str != NULL);
1154
    printf("%s\n", qstring_get_str(str));
1155
    qobject_decref(obj);
1156
    qmp_output_visitor_cleanup(ov);
1157
    QDECREF(str);
1158
}
1159

  
1160
static void collect_image_info(BlockDriverState *bs,
1161
                   ImageInfo *info,
1162
                   const char *filename,
1163
                   const char *fmt)
1106 1164
{
1107
    int c;
1108
    const char *filename, *fmt;
1109
    BlockDriverState *bs;
1110
    char size_buf[128], dsize_buf[128];
1111 1165
    uint64_t total_sectors;
1112
    int64_t allocated_size;
1113 1166
    char backing_filename[1024];
1114 1167
    char backing_filename2[1024];
1115 1168
    BlockDriverInfo bdi;
1116 1169

  
1170
    bdrv_get_geometry(bs, &total_sectors);
1171

  
1172
    info->filename        = g_strdup(filename);
1173
    info->format          = g_strdup(bdrv_get_format_name(bs));
1174
    info->virtual_size    = total_sectors * 512;
1175
    info->actual_size     = bdrv_get_allocated_file_size(bs);
1176
    info->has_actual_size = info->actual_size >= 0;
1177
    if (bdrv_is_encrypted(bs)) {
1178
        info->encrypted = true;
1179
        info->has_encrypted = true;
1180
    }
1181
    if (bdrv_get_info(bs, &bdi) >= 0) {
1182
        if (bdi.cluster_size != 0) {
1183
            info->cluster_size = bdi.cluster_size;
1184
            info->has_cluster_size = true;
1185
        }
1186
        info->dirty_flag = bdi.is_dirty;
1187
        info->has_dirty_flag = true;
1188
    }
1189
    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1190
    if (backing_filename[0] != '\0') {
1191
        info->backing_filename = g_strdup(backing_filename);
1192
        info->has_backing_filename = true;
1193
        bdrv_get_full_backing_filename(bs, backing_filename2,
1194
                                       sizeof(backing_filename2));
1195

  
1196
        if (strcmp(backing_filename, backing_filename2) != 0) {
1197
            info->full_backing_filename =
1198
                        g_strdup(backing_filename2);
1199
            info->has_full_backing_filename = true;
1200
        }
1201

  
1202
        if (bs->backing_format[0]) {
1203
            info->backing_filename_format = g_strdup(bs->backing_format);
1204
            info->has_backing_filename_format = true;
1205
        }
1206
    }
1207
}
1208

  
1209
static void dump_human_image_info(ImageInfo *info)
1210
{
1211
    char size_buf[128], dsize_buf[128];
1212
    if (!info->has_actual_size) {
1213
        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1214
    } else {
1215
        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1216
                                info->actual_size);
1217
    }
1218
    get_human_readable_size(size_buf, sizeof(size_buf), info->virtual_size);
1219
    printf("image: %s\n"
1220
           "file format: %s\n"
1221
           "virtual size: %s (%" PRId64 " bytes)\n"
1222
           "disk size: %s\n",
1223
           info->filename, info->format, size_buf,
1224
           info->virtual_size,
1225
           dsize_buf);
1226

  
1227
    if (info->has_encrypted && info->encrypted) {
1228
        printf("encrypted: yes\n");
1229
    }
1230

  
1231
    if (info->has_cluster_size) {
1232
        printf("cluster_size: %" PRId64 "\n", info->cluster_size);
1233
    }
1234

  
1235
    if (info->has_dirty_flag && info->dirty_flag) {
1236
        printf("cleanly shut down: no\n");
1237
    }
1238

  
1239
    if (info->has_backing_filename) {
1240
        printf("backing file: %s", info->backing_filename);
1241
        if (info->has_full_backing_filename) {
1242
            printf(" (actual path: %s)", info->full_backing_filename);
1243
        }
1244
        putchar('\n');
1245
        if (info->has_backing_filename_format) {
1246
            printf("backing file format: %s\n", info->backing_filename_format);
1247
        }
1248
    }
1249
}
1250

  
1251
enum {OPTION_OUTPUT = 256};
1252

  
1253
typedef enum OutputFormat {
1254
    OFORMAT_JSON,
1255
    OFORMAT_HUMAN,
1256
} OutputFormat;
1257

  
1258
static int img_info(int argc, char **argv)
1259
{
1260
    int c;
1261
    OutputFormat output_format = OFORMAT_HUMAN;
1262
    const char *filename, *fmt, *output;
1263
    BlockDriverState *bs;
1264
    ImageInfo *info;
1265

  
1117 1266
    fmt = NULL;
1267
    output = NULL;
1118 1268
    for(;;) {
1119
        c = getopt(argc, argv, "f:h");
1269
        int option_index = 0;
1270
        static const struct option long_options[] = {
1271
            {"help", no_argument, 0, 'h'},
1272
            {"format", required_argument, 0, 'f'},
1273
            {"output", required_argument, 0, OPTION_OUTPUT},
1274
            {0, 0, 0, 0}
1275
        };
1276
        c = getopt_long(argc, argv, "f:h",
1277
                        long_options, &option_index);
1120 1278
        if (c == -1) {
1121 1279
            break;
1122 1280
        }
......
1128 1286
        case 'f':
1129 1287
            fmt = optarg;
1130 1288
            break;
1289
        case OPTION_OUTPUT:
1290
            output = optarg;
1291
            break;
1131 1292
        }
1132 1293
    }
1133 1294
    if (optind >= argc) {
......
1135 1296
    }
1136 1297
    filename = argv[optind++];
1137 1298

  
1299
    if (output && !strcmp(output, "json")) {
1300
        output_format = OFORMAT_JSON;
1301
    } else if (output && !strcmp(output, "human")) {
1302
        output_format = OFORMAT_HUMAN;
1303
    } else if (output) {
1304
        error_report("--output must be used with human or json as argument.");
1305
        return 1;
1306
    }
1307

  
1138 1308
    bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_NO_BACKING);
1139 1309
    if (!bs) {
1140 1310
        return 1;
1141 1311
    }
1142
    bdrv_get_geometry(bs, &total_sectors);
1143
    get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
1144
    allocated_size = bdrv_get_allocated_file_size(bs);
1145
    if (allocated_size < 0) {
1146
        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1147
    } else {
1148
        get_human_readable_size(dsize_buf, sizeof(dsize_buf),
1149
                                allocated_size);
1150
    }
1151
    printf("image: %s\n"
1152
           "file format: %s\n"
1153
           "virtual size: %s (%" PRId64 " bytes)\n"
1154
           "disk size: %s\n",
1155
           filename, bdrv_get_format_name(bs), size_buf,
1156
           (total_sectors * 512),
1157
           dsize_buf);
1158
    if (bdrv_is_encrypted(bs)) {
1159
        printf("encrypted: yes\n");
1160
    }
1161
    if (bdrv_get_info(bs, &bdi) >= 0) {
1162
        if (bdi.cluster_size != 0) {
1163
            printf("cluster_size: %d\n", bdi.cluster_size);
1164
        }
1165
        if (bdi.is_dirty) {
1166
            printf("cleanly shut down: no\n");
1167
        }
1168
    }
1169
    bdrv_get_backing_filename(bs, backing_filename, sizeof(backing_filename));
1170
    if (backing_filename[0] != '\0') {
1171
        bdrv_get_full_backing_filename(bs, backing_filename2,
1172
                                       sizeof(backing_filename2));
1173
        printf("backing file: %s", backing_filename);
1174
        if (strcmp(backing_filename, backing_filename2) != 0) {
1175
            printf(" (actual path: %s)", backing_filename2);
1176
        }
1177
        putchar('\n');
1312

  
1313
    info = g_new0(ImageInfo, 1);
1314
    collect_image_info(bs, info, filename, fmt);
1315

  
1316
    switch (output_format) {
1317
    case OFORMAT_HUMAN:
1318
        dump_human_image_info(info);
1319
        dump_snapshots(bs);
1320
        break;
1321
    case OFORMAT_JSON:
1322
        collect_snapshots(bs, info);
1323
        dump_json_image_info(info);
1324
        break;
1178 1325
    }
1179
    dump_snapshots(bs);
1326

  
1327
    qapi_free_ImageInfo(info);
1180 1328
    bdrv_delete(bs);
1181 1329
    return 0;
1182 1330
}

Also available in: Unified diff