> On Jul 30, 2018, at 3:48 PM, Eric Blake <ebl...@redhat.com> wrote: > > On 07/30/2018 02:14 PM, John Arbuckle wrote: >> Changes qemu-img so if the user runs it without any >> arguments, it will walk the user thru making an image >> file. > > Please remember to cc qemu-devel on ALL patches, as suggested by > ./scripts/getmaintainer.pl.
Sorry about that. I did remember a few minutes after sending the patch and sent it. > >> Signed-off-by: John Arbuckle <programmingk...@gmail.com> >> --- >> qemu-img.c | 31 +++++++++++++++++++++++++++++-- >> 1 file changed, 29 insertions(+), 2 deletions(-) > > Missing documentation patches (at a minimum, 'man qemu-img' should be updated > to mention this new mode of operation). I'm also going to be a stickler and > require an addition to tests/qemu-iotests to ensure this new feature gets > coverage and doesn't regress (at least, if others are even in favor of the > idea. Personally, I'm 60-40 against the bloat, as telling the user to read > --help is sufficient in my mind). After talking to Max Reitz about this issue I'm not even sure I should continue with this plan. Another idea I have is to improve the documentation to qemu-img. Right now it looks very hard to look at. I'm thinking a few examples might make things easier for the user. > >> diff --git a/qemu-img.c b/qemu-img.c >> index 9b7506b8ae..aa3df3b431 100644 >> --- a/qemu-img.c >> +++ b/qemu-img.c >> @@ -4873,6 +4873,32 @@ out: >> return ret; >> } >> +/* Guides the user on making an image file */ >> +static int interactive_mode() >> +{ >> + char format[100]; >> + char size[100]; >> + char name[1000]; > > Eww. Fixed size buffers for user-provided input are evil. getline() is your > friend. > >> + >> + printf("\nInteractive mode (Enter Control-C to cancel)\n"); >> + printf("Please select a format (qcow, qcow2, raw, vdi, vhdx, vmdk, >> vpc): "); > > Incomplete. Better to generate the list dynamically by iterating over the > QAPI enum than it is to hard-code an incomplete list - particularly since > distros can white- or black-list particular drivers. > >> + scanf("%100s", format); > > Eww. Repeating the limit of your fixed size buffer, without checking that you > actually read a complete line, or that the scanf actually succeeded in > reading. That's dangerous if a later programmer changes one but not both of > the two lines that are supposed to be using the same fixed size. Even if we > accept the direction that this patch is heading in, it would need to be done > using more robust code. > >> + printf("Please enter a size (e.g. 100M, 10G): "); >> + scanf("%100s", size); >> + printf("Please enter a name: "); >> + scanf("%1000s", name); > > A limit of 1000 has no bearing on actual file name lengths; a more typical > limit of NAME_MAX and/or PATH_MAX may come into play first (as low as 256 on > many systems, but on some systems, that value is intentionally undefined > because there is no inherent limit). Again, you should be using getline() > and malloc'ing your result rather than using arbitrary (and probably > wrong-size) fixed-size buffers. > >> + >> + const char *arguments[] = {"create", "-f", format, name, size}; > > Although this is valid C99, qemu tends to prefer that you declare all > variables at the start of the scope rather than after statements. > > You did not do ANY error checking that you actually parsed arguments from the > user; that in turn could result in passing bogus arguments on to img_create() > that could not normally happen via command line usage. I was going to do error handling until I realized img_create() is very good at telling the user what is wrong. Anything I would add would be redundant to what img_create() does. > > Why are you hard-coding a create, rather than going FULLY interactive and > asking the user which sub-command (create, compare, ...) that they want to > use? I was only thinking about what I use qemu-img for. You do have a good point. A fully interactive qemu-img command would be better. > Note that if we do want the level of interactivity to encompass the choice > of subcommand, that you still need to make things programmatic, not > hard-coded. Also, John Snow had started some work on making qemu-img.c and > associated documentation saner, including making subcommands more uniform; > you may want to rebase your work on top of his cleanups, if there is even > demand for this. > >> + int arg_count = 5; >> + int return_value; >> + return_value = img_create(arg_count, (char **)arguments); > > Can we come up with a way to not have to cast away the const, if we are > locally supplying the arguments? > >> + if (return_value == 0) { >> + printf("Done creating image file\n"); >> + } >> + >> + return return_value; >> +} >> + >> static const img_cmd_t img_cmds[] = { >> #define DEF(option, callback, arg_string) \ >> { option, callback }, >> @@ -4912,8 +4938,9 @@ int main(int argc, char **argv) >> module_call_init(MODULE_INIT_QOM); >> bdrv_init(); >> - if (argc < 2) { >> - error_exit("Not enough arguments"); >> + >> + if (argc == 1) { /* If no arguments passed to qemu-img */ >> + return interactive_mode(); > > This is placed early-enough in main() that you never use interactive mode if > the user passed options but no subcommand (such as 'qemu-img -T foo'), is > that intentional? Yes. > Conversely, your patch does not help if a user calls 'qemu-img create' > without options, while it can be argued that if we want (partial) > interactivity, why not be nice to the user and provide it at any step of the > way rather than just when no subcommand name was given. I figure a user wants interactive help, or not at all. Your idea is interesting. > > -- > Eric Blake, Principal Software Engineer > Red Hat, Inc. +1-919-301-3266 > Virtualization: qemu.org | libvirt.org Thank you for looking at my patch.