Commit ac1307ab authored by Fam Zheng's avatar Fam Zheng Committed by Kevin Wolf

qemu-img: Improve error messages

Previously, when there is a user error in argv parsing, qemu-img prints
help text and exits.

Add an error_exit function to print a helpful error message and a hint
to run 'qemu-img --help' for more information.

As a bonus, "qemu-img <cmd> --help" now has a more reasonable exit code
0.

In the future the help text should be split by sub command, and only
print the information for the specified command.
Signed-off-by: default avatarFam Zheng <famz@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent 90d9d301
...@@ -57,8 +57,22 @@ static void format_print(void *opaque, const char *name) ...@@ -57,8 +57,22 @@ static void format_print(void *opaque, const char *name)
printf(" %s", name); printf(" %s", name);
} }
static void QEMU_NORETURN GCC_FMT_ATTR(1, 2) error_exit(const char *fmt, ...)
{
va_list ap;
error_printf("qemu-img: ");
va_start(ap, fmt);
error_vprintf(fmt, ap);
va_end(ap);
error_printf("\nTry 'qemu-img --help' for more information\n");
exit(EXIT_FAILURE);
}
/* Please keep in synch with qemu-img.texi */ /* Please keep in synch with qemu-img.texi */
static void help(void) static void QEMU_NORETURN help(void)
{ {
const char *help_msg = const char *help_msg =
"qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n" "qemu-img version " QEMU_VERSION ", Copyright (c) 2004-2008 Fabrice Bellard\n"
...@@ -129,7 +143,7 @@ static void help(void) ...@@ -129,7 +143,7 @@ static void help(void)
printf("%s\nSupported formats:", help_msg); printf("%s\nSupported formats:", help_msg);
bdrv_iterate_format(format_print, NULL); bdrv_iterate_format(format_print, NULL);
printf("\n"); printf("\n");
exit(1); exit(EXIT_SUCCESS);
} }
static int GCC_FMT_ATTR(2, 3) qprintf(bool quiet, const char *fmt, ...) static int GCC_FMT_ATTR(2, 3) qprintf(bool quiet, const char *fmt, ...)
...@@ -399,7 +413,7 @@ static int img_create(int argc, char **argv) ...@@ -399,7 +413,7 @@ static int img_create(int argc, char **argv)
} }
if (optind >= argc) { if (optind >= argc) {
help(); error_exit("Expecting image file name");
} }
optind++; optind++;
...@@ -422,7 +436,7 @@ static int img_create(int argc, char **argv) ...@@ -422,7 +436,7 @@ static int img_create(int argc, char **argv)
img_size = (uint64_t)sval; img_size = (uint64_t)sval;
} }
if (optind != argc) { if (optind != argc) {
help(); error_exit("Unexpected argument: %s", argv[optind]);
} }
bdrv_img_create(filename, fmt, base_filename, base_fmt, bdrv_img_create(filename, fmt, base_filename, base_fmt,
...@@ -591,7 +605,8 @@ static int img_check(int argc, char **argv) ...@@ -591,7 +605,8 @@ static int img_check(int argc, char **argv)
} else if (!strcmp(optarg, "all")) { } else if (!strcmp(optarg, "all")) {
fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS; fix = BDRV_FIX_LEAKS | BDRV_FIX_ERRORS;
} else { } else {
help(); error_exit("Unknown option value for -r "
"(expecting 'leaks' or 'all'): %s", optarg);
} }
break; break;
case OPTION_OUTPUT: case OPTION_OUTPUT:
...@@ -603,7 +618,7 @@ static int img_check(int argc, char **argv) ...@@ -603,7 +618,7 @@ static int img_check(int argc, char **argv)
} }
} }
if (optind != argc - 1) { if (optind != argc - 1) {
help(); error_exit("Expecting one image file name");
} }
filename = argv[optind++]; filename = argv[optind++];
...@@ -714,7 +729,7 @@ static int img_commit(int argc, char **argv) ...@@ -714,7 +729,7 @@ static int img_commit(int argc, char **argv)
} }
} }
if (optind != argc - 1) { if (optind != argc - 1) {
help(); error_exit("Expecting one image file name");
} }
filename = argv[optind++]; filename = argv[optind++];
...@@ -960,7 +975,7 @@ static int img_compare(int argc, char **argv) ...@@ -960,7 +975,7 @@ static int img_compare(int argc, char **argv)
if (optind != argc - 2) { if (optind != argc - 2) {
help(); error_exit("Expecting two image file names");
} }
filename1 = argv[optind++]; filename1 = argv[optind++];
filename2 = argv[optind++]; filename2 = argv[optind++];
...@@ -1276,7 +1291,7 @@ static int img_convert(int argc, char **argv) ...@@ -1276,7 +1291,7 @@ static int img_convert(int argc, char **argv)
} }
if (bs_n < 1) { if (bs_n < 1) {
help(); error_exit("Must specify image file name");
} }
...@@ -1886,7 +1901,7 @@ static int img_info(int argc, char **argv) ...@@ -1886,7 +1901,7 @@ static int img_info(int argc, char **argv)
} }
} }
if (optind != argc - 1) { if (optind != argc - 1) {
help(); error_exit("Expecting one image file name");
} }
filename = argv[optind++]; filename = argv[optind++];
...@@ -2050,10 +2065,10 @@ static int img_map(int argc, char **argv) ...@@ -2050,10 +2065,10 @@ static int img_map(int argc, char **argv)
break; break;
} }
} }
if (optind >= argc) { if (optind != argc - 1) {
help(); error_exit("Expecting one image file name");
} }
filename = argv[optind++]; filename = argv[optind];
if (output && !strcmp(output, "json")) { if (output && !strcmp(output, "json")) {
output_format = OFORMAT_JSON; output_format = OFORMAT_JSON;
...@@ -2142,7 +2157,7 @@ static int img_snapshot(int argc, char **argv) ...@@ -2142,7 +2157,7 @@ static int img_snapshot(int argc, char **argv)
return 0; return 0;
case 'l': case 'l':
if (action) { if (action) {
help(); error_exit("Cannot mix '-l', '-a', '-c', '-d'");
return 0; return 0;
} }
action = SNAPSHOT_LIST; action = SNAPSHOT_LIST;
...@@ -2150,7 +2165,7 @@ static int img_snapshot(int argc, char **argv) ...@@ -2150,7 +2165,7 @@ static int img_snapshot(int argc, char **argv)
break; break;
case 'a': case 'a':
if (action) { if (action) {
help(); error_exit("Cannot mix '-l', '-a', '-c', '-d'");
return 0; return 0;
} }
action = SNAPSHOT_APPLY; action = SNAPSHOT_APPLY;
...@@ -2158,7 +2173,7 @@ static int img_snapshot(int argc, char **argv) ...@@ -2158,7 +2173,7 @@ static int img_snapshot(int argc, char **argv)
break; break;
case 'c': case 'c':
if (action) { if (action) {
help(); error_exit("Cannot mix '-l', '-a', '-c', '-d'");
return 0; return 0;
} }
action = SNAPSHOT_CREATE; action = SNAPSHOT_CREATE;
...@@ -2166,7 +2181,7 @@ static int img_snapshot(int argc, char **argv) ...@@ -2166,7 +2181,7 @@ static int img_snapshot(int argc, char **argv)
break; break;
case 'd': case 'd':
if (action) { if (action) {
help(); error_exit("Cannot mix '-l', '-a', '-c', '-d'");
return 0; return 0;
} }
action = SNAPSHOT_DELETE; action = SNAPSHOT_DELETE;
...@@ -2179,7 +2194,7 @@ static int img_snapshot(int argc, char **argv) ...@@ -2179,7 +2194,7 @@ static int img_snapshot(int argc, char **argv)
} }
if (optind != argc - 1) { if (optind != argc - 1) {
help(); error_exit("Expecting one image file name");
} }
filename = argv[optind++]; filename = argv[optind++];
...@@ -2292,8 +2307,11 @@ static int img_rebase(int argc, char **argv) ...@@ -2292,8 +2307,11 @@ static int img_rebase(int argc, char **argv)
progress = 0; progress = 0;
} }
if ((optind != argc - 1) || (!unsafe && !out_baseimg)) { if (optind != argc - 1) {
help(); error_exit("Expecting one image file name");
}
if (!unsafe && !out_baseimg) {
error_exit("Must specify backing file (-b) or use unsafe mode (-u)");
} }
filename = argv[optind++]; filename = argv[optind++];
...@@ -2553,7 +2571,7 @@ static int img_resize(int argc, char **argv) ...@@ -2553,7 +2571,7 @@ static int img_resize(int argc, char **argv)
/* Remove size from argv manually so that negative numbers are not treated /* Remove size from argv manually so that negative numbers are not treated
* as options by getopt. */ * as options by getopt. */
if (argc < 3) { if (argc < 3) {
help(); error_exit("Not enough arguments");
return 1; return 1;
} }
...@@ -2580,7 +2598,7 @@ static int img_resize(int argc, char **argv) ...@@ -2580,7 +2598,7 @@ static int img_resize(int argc, char **argv)
} }
} }
if (optind != argc - 1) { if (optind != argc - 1) {
help(); error_exit("Expecting one image file name");
} }
filename = argv[optind++]; filename = argv[optind++];
...@@ -2697,7 +2715,7 @@ static int img_amend(int argc, char **argv) ...@@ -2697,7 +2715,7 @@ static int img_amend(int argc, char **argv)
} }
if (!options) { if (!options) {
help(); error_exit("Must specify options (-o)");
} }
filename = (optind == argc - 1) ? argv[argc - 1] : NULL; filename = (optind == argc - 1) ? argv[argc - 1] : NULL;
...@@ -2709,7 +2727,7 @@ static int img_amend(int argc, char **argv) ...@@ -2709,7 +2727,7 @@ static int img_amend(int argc, char **argv)
} }
if (optind != argc - 1) { if (optind != argc - 1) {
help(); error_exit("Expecting one image file name");
} }
bs = bdrv_new_open("image", filename, fmt, bs = bdrv_new_open("image", filename, fmt,
...@@ -2781,8 +2799,9 @@ int main(int argc, char **argv) ...@@ -2781,8 +2799,9 @@ int main(int argc, char **argv)
qemu_init_main_loop(); qemu_init_main_loop();
bdrv_init(); bdrv_init();
if (argc < 2) if (argc < 2) {
help(); error_exit("Not enough arguments");
}
cmdname = argv[1]; cmdname = argv[1];
argc--; argv++; argc--; argv++;
...@@ -2794,6 +2813,5 @@ int main(int argc, char **argv) ...@@ -2794,6 +2813,5 @@ int main(int argc, char **argv)
} }
/* not found */ /* not found */
help(); error_exit("Command not found: %s", cmdname);
return 0;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment