]> Git Repo - qemu.git/blobdiff - qemu-img.c
target-arm/arm-powerctl: wake up sleeping CPUs
[qemu.git] / qemu-img.c
index 5bdac8ddb7f3663c3e063c3c5c592736e65f6513..afcd51ff1895859a13cf756741038e117fbe834b 100644 (file)
@@ -25,7 +25,7 @@
 #include "qemu-version.h"
 #include "qapi/error.h"
 #include "qapi-visit.h"
-#include "qapi/qmp-output-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qjson.h"
 #include "qemu/cutils.h"
@@ -44,7 +44,7 @@
 #include <getopt.h>
 
 #define QEMU_IMG_VERSION "qemu-img version " QEMU_VERSION QEMU_PKGVERSION \
-                          "" QEMU_COPYRIGHT "\n"
+                          "\n" QEMU_COPYRIGHT "\n"
 
 typedef struct img_cmd_t {
     const char *name;
@@ -173,7 +173,8 @@ static void QEMU_NORETURN help(void)
            "(default: 512)\n"
            "  'count=N' copy only N input blocks\n"
            "  'if=FILE' read from FILE\n"
-           "  'of=FILE' write to FILE\n";
+           "  'of=FILE' write to FILE\n"
+           "  'skip=N' skip N bs-sized blocks at the start of input\n";
 
     printf("%s\nSupported formats:", help_msg);
     bdrv_iterate_format(format_print, NULL);
@@ -499,7 +500,7 @@ static void dump_json_image_check(ImageCheck *check, bool quiet)
 {
     QString *str;
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
+    Visitor *v = qobject_output_visitor_new(&obj);
 
     visit_type_ImageCheck(v, NULL, &check, &error_abort);
     visit_complete(v, &obj);
@@ -2192,7 +2193,7 @@ static void dump_json_image_info_list(ImageInfoList *list)
 {
     QString *str;
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
+    Visitor *v = qobject_output_visitor_new(&obj);
 
     visit_type_ImageInfoList(v, NULL, &list, &error_abort);
     visit_complete(v, &obj);
@@ -2208,7 +2209,7 @@ static void dump_json_image_info(ImageInfo *info)
 {
     QString *str;
     QObject *obj;
-    Visitor *v = qmp_output_visitor_new(&obj);
+    Visitor *v = qobject_output_visitor_new(&obj);
 
     visit_type_ImageInfo(v, NULL, &info, &error_abort);
     visit_complete(v, &obj);
@@ -2955,6 +2956,7 @@ static int img_rebase(int argc, char **argv)
             error_reportf_err(local_err,
                               "Could not open old backing file '%s': ",
                               backing_name);
+            ret = -1;
             goto out;
         }
 
@@ -2972,6 +2974,7 @@ static int img_rebase(int argc, char **argv)
                 error_reportf_err(local_err,
                                   "Could not open new backing file '%s': ",
                                   out_baseimg);
+                ret = -1;
                 goto out;
             }
         }
@@ -3807,6 +3810,7 @@ out:
 #define C_COUNT   02
 #define C_IF      04
 #define C_OF      010
+#define C_SKIP    020
 
 struct DdInfo {
     unsigned int flags;
@@ -3817,6 +3821,7 @@ struct DdIo {
     int bsz;    /* Block size */
     char *filename;
     uint8_t *buf;
+    int64_t offset;
 };
 
 struct DdOpts {
@@ -3877,6 +3882,22 @@ static int img_dd_of(const char *arg,
     return 0;
 }
 
+static int img_dd_skip(const char *arg,
+                       struct DdIo *in, struct DdIo *out,
+                       struct DdInfo *dd)
+{
+    char *end;
+
+    in->offset = qemu_strtosz_suffix(arg, &end, QEMU_STRTOSZ_DEFSUFFIX_B);
+
+    if (in->offset < 0 || *end) {
+        error_report("invalid number: '%s'", arg);
+        return 1;
+    }
+
+    return 0;
+}
+
 static int img_dd(int argc, char **argv)
 {
     int ret = 0;
@@ -3900,12 +3921,14 @@ static int img_dd(int argc, char **argv)
     struct DdIo in = {
         .bsz = 512, /* Block size is by default 512 bytes */
         .filename = NULL,
-        .buf = NULL
+        .buf = NULL,
+        .offset = 0
     };
     struct DdIo out = {
         .bsz = 512,
         .filename = NULL,
-        .buf = NULL
+        .buf = NULL,
+        .offset = 0
     };
 
     const struct DdOpts options[] = {
@@ -3913,6 +3936,7 @@ static int img_dd(int argc, char **argv)
         { "count", img_dd_count, C_COUNT },
         { "if", img_dd_if, C_IF },
         { "of", img_dd_of, C_OF },
+        { "skip", img_dd_skip, C_SKIP },
         { NULL, NULL, 0 }
     };
     const struct option long_options[] = {
@@ -4032,7 +4056,14 @@ static int img_dd(int argc, char **argv)
         size = dd.count * in.bsz;
     }
 
-    qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, &error_abort);
+    /* Overflow means the specified offset is beyond input image's size */
+    if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
+                              size < in.bsz * in.offset)) {
+        qemu_opt_set_number(opts, BLOCK_OPT_SIZE, 0, &error_abort);
+    } else {
+        qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
+                            size - in.bsz * in.offset, &error_abort);
+    }
 
     ret = bdrv_create(drv, out.filename, opts, &local_err);
     if (ret < 0) {
@@ -4051,9 +4082,20 @@ static int img_dd(int argc, char **argv)
         goto out;
     }
 
+    if (dd.flags & C_SKIP && (in.offset > INT64_MAX / in.bsz ||
+                              size < in.offset * in.bsz)) {
+        /* We give a warning if the skip option is bigger than the input
+         * size and create an empty output disk image (i.e. like dd(1)).
+         */
+        error_report("%s: cannot skip to specified offset", in.filename);
+        in_pos = size;
+    } else {
+        in_pos = in.offset * in.bsz;
+    }
+
     in.buf = g_new(uint8_t, in.bsz);
 
-    for (in_pos = 0, out_pos = 0; in_pos < size; block_count++) {
+    for (out_pos = 0; in_pos < size; block_count++) {
         int in_ret, out_ret;
 
         if (in_pos + in.bsz > size) {
@@ -4125,6 +4167,7 @@ int main(int argc, char **argv)
     signal(SIGPIPE, SIG_IGN);
 #endif
 
+    module_call_init(MODULE_INIT_TRACE);
     error_set_progname(argv[0]);
     qemu_init_exec_dir(argv[0]);
 
This page took 0.028443 seconds and 4 git commands to generate.