diff mbox

[2/2] qapi: convert device_del

Message ID 1332967854-29106-3-git-send-email-lcapitulino@redhat.com
State New
Headers show

Commit Message

Luiz Capitulino March 28, 2012, 8:50 p.m. UTC
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
---
 hmp-commands.hx   |    3 +--
 hmp.c             |    9 +++++++++
 hmp.h             |    1 +
 hw/qdev-monitor.c |   15 +++++++--------
 qapi-schema.json  |   20 ++++++++++++++++++++
 qmp-commands.hx   |    5 +----
 6 files changed, 39 insertions(+), 14 deletions(-)

Comments

Stefan Hajnoczi March 29, 2012, 7:08 a.m. UTC | #1
On Wed, Mar 28, 2012 at 05:50:54PM -0300, Luiz Capitulino wrote:
>      ret = qdev_unplug(dev, &local_err);
>      if (error_is_set(&local_err)) {
> -        qerror_report_err(local_err);
> -        error_free(local_err);
> +        error_propagate(errp, local_err);
> +    } else if (ret) {
> +        error_set(errp, QERR_UNDEFINED_ERROR);

Can we make qdev_unplug() void?  I can find no case in QEMU where we
return != 0 without setting error.  If we fix the function prototype
this invalid state can be eliminated forever.

(Other functions that take Error **errp are usually void.)

> diff --git a/qapi-schema.json b/qapi-schema.json
> index 0d11d6e..ace55f3 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -1701,3 +1701,23 @@
>  # Since: 1.1
>  ##
>  { 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }
> +
> +##
> +# @device_del:
> +#
> +# Remove a device from a guest
> +#
> +# @id: the name of the device
> +#
> +# Returns: Nothing on success
> +#          If @id is not a valid device, DeviceNotFound
> +#          If the device does not support unplug, BusNoHotplug
> +#
> +# Notes: When this command completes, the device may not be removed from the
> +#        guest.  Hot removal is an operation that requires guest cooperation.
> +#        This command merely requests that the guest begin the hot removal
> +#        process.

I have not peeked at the implementation in QEMU or libvirt, but is there
a QMP event for actual removal or would the user need to poll?  This bit
of information would be useful in the documentation.

Stefan
Luiz Capitulino March 29, 2012, 1:17 p.m. UTC | #2
On Thu, 29 Mar 2012 08:08:51 +0100
Stefan Hajnoczi <stefanha@gmail.com> wrote:

> On Wed, Mar 28, 2012 at 05:50:54PM -0300, Luiz Capitulino wrote:
> >      ret = qdev_unplug(dev, &local_err);
> >      if (error_is_set(&local_err)) {
> > -        qerror_report_err(local_err);
> > -        error_free(local_err);
> > +        error_propagate(errp, local_err);
> > +    } else if (ret) {
> > +        error_set(errp, QERR_UNDEFINED_ERROR);
> 
> Can we make qdev_unplug() void?  I can find no case in QEMU where we
> return != 0 without setting error.  If we fix the function prototype
> this invalid state can be eliminated forever.

Good point, I'll change it.

> 
> (Other functions that take Error **errp are usually void.)
> 
> > diff --git a/qapi-schema.json b/qapi-schema.json
> > index 0d11d6e..ace55f3 100644
> > --- a/qapi-schema.json
> > +++ b/qapi-schema.json
> > @@ -1701,3 +1701,23 @@
> >  # Since: 1.1
> >  ##
> >  { 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }
> > +
> > +##
> > +# @device_del:
> > +#
> > +# Remove a device from a guest
> > +#
> > +# @id: the name of the device
> > +#
> > +# Returns: Nothing on success
> > +#          If @id is not a valid device, DeviceNotFound
> > +#          If the device does not support unplug, BusNoHotplug
> > +#
> > +# Notes: When this command completes, the device may not be removed from the
> > +#        guest.  Hot removal is an operation that requires guest cooperation.
> > +#        This command merely requests that the guest begin the hot removal
> > +#        process.
> 
> I have not peeked at the implementation in QEMU or libvirt, but is there
> a QMP event for actual removal or would the user need to poll?  This bit
> of information would be useful in the documentation.

There's no event, I'll document it. Is there any preferred method for
polling? query-pci?
Stefan Hajnoczi March 29, 2012, 1:39 p.m. UTC | #3
On Thu, Mar 29, 2012 at 2:17 PM, Luiz Capitulino <lcapitulino@redhat.com> wrote:
> On Thu, 29 Mar 2012 08:08:51 +0100
> Stefan Hajnoczi <stefanha@gmail.com> wrote:
>
>> On Wed, Mar 28, 2012 at 05:50:54PM -0300, Luiz Capitulino wrote:
>> >      ret = qdev_unplug(dev, &local_err);
>> >      if (error_is_set(&local_err)) {
>> > -        qerror_report_err(local_err);
>> > -        error_free(local_err);
>> > +        error_propagate(errp, local_err);
>> > +    } else if (ret) {
>> > +        error_set(errp, QERR_UNDEFINED_ERROR);
>>
>> Can we make qdev_unplug() void?  I can find no case in QEMU where we
>> return != 0 without setting error.  If we fix the function prototype
>> this invalid state can be eliminated forever.
>
> Good point, I'll change it.
>
>>
>> (Other functions that take Error **errp are usually void.)
>>
>> > diff --git a/qapi-schema.json b/qapi-schema.json
>> > index 0d11d6e..ace55f3 100644
>> > --- a/qapi-schema.json
>> > +++ b/qapi-schema.json
>> > @@ -1701,3 +1701,23 @@
>> >  # Since: 1.1
>> >  ##
>> >  { 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }
>> > +
>> > +##
>> > +# @device_del:
>> > +#
>> > +# Remove a device from a guest
>> > +#
>> > +# @id: the name of the device
>> > +#
>> > +# Returns: Nothing on success
>> > +#          If @id is not a valid device, DeviceNotFound
>> > +#          If the device does not support unplug, BusNoHotplug
>> > +#
>> > +# Notes: When this command completes, the device may not be removed from the
>> > +#        guest.  Hot removal is an operation that requires guest cooperation.
>> > +#        This command merely requests that the guest begin the hot removal
>> > +#        process.
>>
>> I have not peeked at the implementation in QEMU or libvirt, but is there
>> a QMP event for actual removal or would the user need to poll?  This bit
>> of information would be useful in the documentation.
>
> There's no event, I'll document it. Is there any preferred method for
> polling? query-pci?

I took a quick peek at libvirt and am none the wiser.  If we don't
know what the recommended approach is then let's leave it.

Stefan
diff mbox

Patch

diff --git a/hmp-commands.hx b/hmp-commands.hx
index bd35a3e..a6f5a84 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -622,8 +622,7 @@  ETEXI
         .args_type  = "id:s",
         .params     = "device",
         .help       = "remove device",
-        .user_print = monitor_user_noop,
-        .mhandler.cmd_new = do_device_del,
+        .mhandler.cmd = hmp_device_del,
     },
 
 STEXI
diff --git a/hmp.c b/hmp.c
index 9cf2d13..f3e5163 100644
--- a/hmp.c
+++ b/hmp.c
@@ -934,3 +934,12 @@  void hmp_migrate(Monitor *mon, const QDict *qdict)
         qemu_mod_timer(status->timer, qemu_get_clock_ms(rt_clock));
     }
 }
+
+void hmp_device_del(Monitor *mon, const QDict *qdict)
+{
+    const char *id = qdict_get_str(qdict, "id");
+    Error *err = NULL;
+
+    qmp_device_del(id, &err);
+    hmp_handle_error(mon, &err);
+}
diff --git a/hmp.h b/hmp.h
index 8807853..443b812 100644
--- a/hmp.h
+++ b/hmp.h
@@ -60,5 +60,6 @@  void hmp_block_stream(Monitor *mon, const QDict *qdict);
 void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
 void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
 void hmp_migrate(Monitor *mon, const QDict *qdict);
+void hmp_device_del(Monitor *mon, const QDict *qdict);
 
 #endif
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 58fa943..761ba90 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -19,6 +19,7 @@ 
 
 #include "qdev.h"
 #include "monitor.h"
+#include "qmp-commands.h"
 
 /*
  * Aliases were a bad idea from the start.  Let's keep them
@@ -574,26 +575,24 @@  int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
     return 0;
 }
 
-int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
+void qmp_device_del(const char *id, Error **errp)
 {
-    const char *id = qdict_get_str(qdict, "id");
     DeviceState *dev;
     Error *local_err = NULL;
     int ret;
 
     dev = qdev_find_recursive(sysbus_get_default(), id);
     if (NULL == dev) {
-        qerror_report(QERR_DEVICE_NOT_FOUND, id);
-        return -1;
+        error_set(errp, QERR_DEVICE_NOT_FOUND, id);
+        return;
     }
 
     ret = qdev_unplug(dev, &local_err);
     if (error_is_set(&local_err)) {
-        qerror_report_err(local_err);
-        error_free(local_err);
+        error_propagate(errp, local_err);
+    } else if (ret) {
+        error_set(errp, QERR_UNDEFINED_ERROR);
     }
-
-    return ret;
 }
 
 void qdev_machine_init(void)
diff --git a/qapi-schema.json b/qapi-schema.json
index 0d11d6e..ace55f3 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1701,3 +1701,23 @@ 
 # Since: 1.1
 ##
 { 'command': 'xen-save-devices-state', 'data': {'filename': 'str'} }
+
+##
+# @device_del:
+#
+# Remove a device from a guest
+#
+# @id: the name of the device
+#
+# Returns: Nothing on success
+#          If @id is not a valid device, DeviceNotFound
+#          If the device does not support unplug, BusNoHotplug
+#
+# Notes: When this command completes, the device may not be removed from the
+#        guest.  Hot removal is an operation that requires guest cooperation.
+#        This command merely requests that the guest begin the hot removal
+#        process.
+#
+# Since: 0.14.0
+##
+{ 'command': 'device_del', 'data': {'id': 'str'} }
diff --git a/qmp-commands.hx b/qmp-commands.hx
index c626ba8..c878b54 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -314,10 +314,7 @@  EQMP
     {
         .name       = "device_del",
         .args_type  = "id:s",
-        .params     = "device",
-        .help       = "remove device",
-        .user_print = monitor_user_noop,
-        .mhandler.cmd_new = do_device_del,
+        .mhandler.cmd_new = qmp_marshal_input_device_del,
     },
 
 SQMP