diff mbox

[RESEND,48/50] hmp: Add read-only option to change command

Message ID 1422387983-32153-49-git-send-email-mreitz@redhat.com
State New
Headers show

Commit Message

Max Reitz Jan. 27, 2015, 7:46 p.m. UTC
Expose the new read-only option of 'blockdev-change-medium' for the
'change' HMP command.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 hmp-commands.hx | 20 +++++++++++++++++---
 hmp.c           | 21 ++++++++++++++++++++-
 2 files changed, 37 insertions(+), 4 deletions(-)

Comments

Eric Blake Jan. 28, 2015, 9:22 p.m. UTC | #1
On 01/27/2015 12:46 PM, Max Reitz wrote:
> Expose the new read-only option of 'blockdev-change-medium' for the
> 'change' HMP command.
> 
> Signed-off-by: Max Reitz <mreitz@redhat.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> ---
>  hmp-commands.hx | 20 +++++++++++++++++---
>  hmp.c           | 21 ++++++++++++++++++++-
>  2 files changed, 37 insertions(+), 4 deletions(-)
> 

Already reviewed...

>  
> +@var{read-only} may be used to change the read-only status of the device. It
> +accepts the following values:
> +
> +@table @var
> +@item retain
> +Retains the current status; this is the default.
> +
> +@item ro
> +Makes the device read-only.
> +
> +@item rw
> +Makes the device writable.

Hmm.  I suggested in 47/50 to rename the QMP enum values to something
longer, which would affect this on a rebase.  On the other hand, it
would be nice to make the HMP counterpart support BOTH spellings for
convenience ('read-write' for legibility, 'rw' for brevity in typing);
and I have no clue if tab completion starts to play a role either.  Up
to you if you want to add complexity or leave things simple and stupid
(the choices we make in HMP for user-friendliness have no bearing on
what libvirt will want to do, so I really have no strong preference).

...so my review still stands if nothing changes, and is probably worth
dropping if you respin to add user-friendly complexity.


>      const char *arg = qdict_get_try_str(qdict, "arg");
> +    const char *read_only = qdict_get_try_str(qdict, "read-only");
> +    BlockdevChangeReadOnlyMode read_only_mode = 0;
>      Error *err = NULL;
>  
>      if (strcmp(device, "vnc") == 0) {
> +        if (read_only) {
> +            monitor_printf(mon, "Parameter 'read-only' is invalid for VNC");

Hmm. In HMP, you don't type the parameter name (it is implicit based on
the rules for converting positional HMP arguments into dictionary
entries for use in the rest of the code).  In particular, that means
that if I type 'change vnc password rw', that means that 'rw' will be in
the "read-only" parameter position, even though it has nothing to do
with read-only.  [hmm - how did 'change vnc password XXX' work anyways,
since the .params for 'change' didn't allow a third argument before your
patch?]

At any rate, the idea I mentioned in the QMP patch about naming the
parameter 'read-mode' instead of 'read-only' might make for nicer error
messages.
Max Reitz Jan. 28, 2015, 9:26 p.m. UTC | #2
On 2015-01-28 at 16:22, Eric Blake wrote:
> On 01/27/2015 12:46 PM, Max Reitz wrote:
>> Expose the new read-only option of 'blockdev-change-medium' for the
>> 'change' HMP command.
>>
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> Reviewed-by: Eric Blake <eblake@redhat.com>
>> ---
>>   hmp-commands.hx | 20 +++++++++++++++++---
>>   hmp.c           | 21 ++++++++++++++++++++-
>>   2 files changed, 37 insertions(+), 4 deletions(-)
>>
> Already reviewed...
>
>>   
>> +@var{read-only} may be used to change the read-only status of the device. It
>> +accepts the following values:
>> +
>> +@table @var
>> +@item retain
>> +Retains the current status; this is the default.
>> +
>> +@item ro
>> +Makes the device read-only.
>> +
>> +@item rw
>> +Makes the device writable.
> Hmm.  I suggested in 47/50 to rename the QMP enum values to something
> longer, which would affect this on a rebase.  On the other hand, it
> would be nice to make the HMP counterpart support BOTH spellings for
> convenience ('read-write' for legibility, 'rw' for brevity in typing);
> and I have no clue if tab completion starts to play a role either.  Up
> to you if you want to add complexity or leave things simple and stupid
> (the choices we make in HMP for user-friendliness have no bearing on
> what libvirt will want to do, so I really have no strong preference).
>
> ...so my review still stands if nothing changes, and is probably worth
> dropping if you respin to add user-friendly complexity.

I probably won't care for brevity too much. Again, if we want to allow 
shortcuts later on, it won't break compatibility so we don't really need 
to worry about it now (although I guess if we don't add it now, we won't 
add it ever).

>>       const char *arg = qdict_get_try_str(qdict, "arg");
>> +    const char *read_only = qdict_get_try_str(qdict, "read-only");
>> +    BlockdevChangeReadOnlyMode read_only_mode = 0;
>>       Error *err = NULL;
>>   
>>       if (strcmp(device, "vnc") == 0) {
>> +        if (read_only) {
>> +            monitor_printf(mon, "Parameter 'read-only' is invalid for VNC");
> Hmm. In HMP, you don't type the parameter name (it is implicit based on
> the rules for converting positional HMP arguments into dictionary
> entries for use in the rest of the code).  In particular, that means
> that if I type 'change vnc password rw', that means that 'rw' will be in
> the "read-only" parameter position, even though it has nothing to do
> with read-only.  [hmm - how did 'change vnc password XXX' work anyways,
> since the .params for 'change' didn't allow a third argument before your
> patch?]

Well, "help change" will tell you that that parameter is named 
"read-only", so I think mentioning the parameter name (instead of 
"garbage at the end of line" or something like that) is fine.

Max

> At any rate, the idea I mentioned in the QMP patch about naming the
> parameter 'read-mode' instead of 'read-only' might make for nicer error
> messages.
diff mbox

Patch

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e37bc8b..70cb7d7 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -196,8 +196,8 @@  ETEXI
 
     {
         .name       = "change",
-        .args_type  = "device:B,target:F,arg:s?",
-        .params     = "device filename [format]",
+        .args_type  = "device:B,target:F,arg:s?,read-only:s?",
+        .params     = "device filename [format [read-only]]",
         .help       = "change a removable medium, optional format",
         .mhandler.cmd = hmp_change,
     },
@@ -209,7 +209,7 @@  STEXI
 Change the configuration of a device.
 
 @table @option
-@item change @var{diskdevice} @var{filename} [@var{format}]
+@item change @var{diskdevice} @var{filename} [@var{format} [@var{read-only}]]
 Change the medium for a removable disk device to point to @var{filename}. eg
 
 @example
@@ -218,6 +218,20 @@  Change the medium for a removable disk device to point to @var{filename}. eg
 
 @var{format} is optional.
 
+@var{read-only} may be used to change the read-only status of the device. It
+accepts the following values:
+
+@table @var
+@item retain
+Retains the current status; this is the default.
+
+@item ro
+Makes the device read-only.
+
+@item rw
+Makes the device writable.
+@end table
+
 @item change vnc @var{display},@var{options}
 Change the configuration of the VNC server. The valid syntax for @var{display}
 and @var{options} are described at @ref{sec_invocation}. eg
diff --git a/hmp.c b/hmp.c
index dbf0947..8e75771 100644
--- a/hmp.c
+++ b/hmp.c
@@ -24,6 +24,7 @@ 
 #include "monitor/monitor.h"
 #include "qapi/opts-visitor.h"
 #include "qapi/string-output-visitor.h"
+#include "qapi/util.h"
 #include "qapi-visit.h"
 #include "ui/console.h"
 #include "block/qapi.h"
@@ -1178,9 +1179,15 @@  void hmp_change(Monitor *mon, const QDict *qdict)
     const char *device = qdict_get_str(qdict, "device");
     const char *target = qdict_get_str(qdict, "target");
     const char *arg = qdict_get_try_str(qdict, "arg");
+    const char *read_only = qdict_get_try_str(qdict, "read-only");
+    BlockdevChangeReadOnlyMode read_only_mode = 0;
     Error *err = NULL;
 
     if (strcmp(device, "vnc") == 0) {
+        if (read_only) {
+            monitor_printf(mon, "Parameter 'read-only' is invalid for VNC");
+            return;
+        }
         if (strcmp(target, "passwd") == 0 ||
             strcmp(target, "password") == 0) {
             if (!arg) {
@@ -1190,7 +1197,19 @@  void hmp_change(Monitor *mon, const QDict *qdict)
         }
         qmp_change("vnc", target, !!arg, arg, &err);
     } else {
-        qmp_blockdev_change_medium(device, target, !!arg, arg, false, 0, &err);
+        if (read_only) {
+            read_only_mode =
+                qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup,
+                                read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE_MAX,
+                                BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, &err);
+            if (err) {
+                hmp_handle_error(mon, &err);
+                return;
+            }
+        }
+
+        qmp_blockdev_change_medium(device, target, !!arg, arg,
+                                   !!read_only, read_only_mode, &err);
         if (err &&
             error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
             error_free(err);