Re: [Qemu-devel] [PATCH v1 3/3] monitor: add del completion for peripheral device

2014-09-29 Thread Hani Benhabiles
On Fri, Sep 26, 2014 at 01:29:41PM -0400, Luiz Capitulino wrote:
> On Fri, 26 Sep 2014 13:25:45 -0400
> Luiz Capitulino  wrote:
> 
> > On Thu, 18 Sep 2014 15:53:21 +0800
> > Zhu Guihua  wrote:
> > 
> > > Add peripheral_device_del_completion() to let peripheral device del 
> > > completion
> > > be possible.
> > > 
> > > Signed-off-by: Zhu Guihua 
> > > ---
> > >  monitor.c | 24 
> > >  1 file changed, 24 insertions(+)
> > > 
> > > diff --git a/monitor.c b/monitor.c
> > > index 667efb7..c0e00e4 100644
> > > --- a/monitor.c
> > > +++ b/monitor.c
> > > @@ -4351,6 +4351,29 @@ static void 
> > > device_del_bus_completion(ReadLineState *rs,  BusState *bus,
> > >  }
> > >  }
> > >  
> > > +static void peripheral_device_del_completion(ReadLineState *rs,
> > > + const char *str, size_t len)
> > > +{
> > > +Object *peripheral;
> > > +DeviceState *dev = NULL;
> > > +ObjectProperty *prop;
> > > +
> > > +peripheral = object_resolve_path("/machine/peripheral/", NULL);
> > > +
> > > +if (peripheral == NULL) {
> > > +return;
> > > +}
> > > +
> > > +QTAILQ_FOREACH(prop, &peripheral->properties, node) {
> > > +if (object_property_is_child(prop)) {
> > > +dev = DEVICE(object_property_get_opaque(prop, NULL));
> > > +if (dev->id && !strncmp(str, dev->id, len)) {
> > > +readline_add_completion(rs, dev->id);
> > > +}
> > > +}
> > > +}
> > > +}
> > > +
> > >  void chardev_remove_completion(ReadLineState *rs, int nb_args, const 
> > > char *str)
> > >  {
> > >  size_t len;
> > > @@ -4424,6 +4447,7 @@ void device_del_completion(ReadLineState *rs, int 
> > > nb_args, const char *str)
> > >  len = strlen(str);
> > >  readline_set_completion_index(rs, len);
> > >  device_del_bus_completion(rs, sysbus_get_default(), str, len);
> > > +peripheral_device_del_completion(rs, str, len);
> > >  }
> > 
> > The series intro email mentions device_del, but this is added to
> > chardev-remove. Is there a reason for this?
> 
> Turns out this is not added to chardev_remove_completion(), looked too
> quickly. In any case, would be nice to have Hani's review.

Hi,

I'm wrestling with my ISP at the moment. Will get back to these as soon as
possible

Thanks.

> 
> > 
> > Hani, could you please review this series?
> > 
> > >  
> > >  void object_del_completion(ReadLineState *rs, int nb_args, const char 
> > > *str)
> > 
> 



Re: [Qemu-devel] NBD TLS support in QEMU

2014-09-05 Thread Hani Benhabiles
On Wed, Sep 03, 2014 at 05:44:17PM +0100, Stefan Hajnoczi wrote:
> Hi,
> QEMU offers both NBD client and server functionality.  The NBD protocol
> runs unencrypted, which is a problem when the client and server
> communicate over an untrusted network.
> 
> The particular use case that prompted this mail is storage migration in
> OpenStack.  The goal is to encrypt the NBD connection between source and
> destination hosts during storage migration.
> 
> I think we can integrate TLS into the NBD protocol as an optional flag.
> A quick web search does not reveal existing open source SSL/TLS NBD
> implementations.  I do see a VMware NBDSSL protocol but there is no
> specification so I guess it is proprietary.

Not sold on this because:
- It requires (unnecessary) changes to the NBD specification.
- It would still be vulnerable to a protocol downgrade attack: ie. An attacker
  could strip the TLS flag from the server's response resulting in either:
  * Connection fallback to cleartext, if both ends don't force TLS.
  * Loss of backward compatibility, if one of the ends forces TLS, making the
reason for which such a flag is added moot IIUC.

IMO, it is more fool proof add some --use-tls flag to the client and server
implementations to wrap the data in TLS, just like HTTPS does for instance.

Also, so mean of verification is required (otherwise, back to point 0 being
vulnerable to sslstrip style attacks) either that the server's cert is signed
with a certain (self-generated) CA certificate or that it matches a certain
fingerprint. Doing it similarly on the server-side would allow hitting a 2nd
bird (authentication.)

>
> The NBD protocol starts with a negotiation phase.  This would be the
> appropriate place to indicate that TLS will be used.  After client and
> server complete TLS setup the connection can continue as normal.
> 
> Besides QEMU, the userspace NBD tools (http://nbd.sf.net/) can also be
> extended to support TLS.  In this case the kernel needs a localhost
> socket and userspace handles TLS.
> 
> Thoughts?
> 
> Stefan





[Qemu-devel] [PATCH] monitor: Remove hardcoded watchdog event names

2014-07-29 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 monitor.c | 11 +--
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/monitor.c b/monitor.c
index 5bc70a6..7465775 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4520,16 +4520,15 @@ void netdev_del_completion(ReadLineState *rs, int 
nb_args, const char *str)
 
 void watchdog_action_completion(ReadLineState *rs, int nb_args, const char 
*str)
 {
+int i;
+
 if (nb_args != 2) {
 return;
 }
 readline_set_completion_index(rs, strlen(str));
-add_completion_option(rs, str, "reset");
-add_completion_option(rs, str, "shutdown");
-add_completion_option(rs, str, "poweroff");
-add_completion_option(rs, str, "pause");
-add_completion_option(rs, str, "debug");
-add_completion_option(rs, str, "none");
+for (i = 0; WatchdogExpirationAction_lookup[i]; i++) {
+add_completion_option(rs, str, WatchdogExpirationAction_lookup[i]);
+}
 }
 
 void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
-- 
1.8.3.2




Re: [Qemu-devel] [PULL 0/5] NBD changes for 2014-06-27

2014-06-29 Thread Hani Benhabiles
On Sun, Jun 29, 2014 at 12:45:27PM +0100, Peter Maydell wrote:
> On 27 June 2014 15:11, Paolo Bonzini  wrote:
> > The following changes since commit d4cba13bdf251baeedb36b87c1e9f6766773e380:
> >
> >   tcg/ppc: Fix failure in tcg_out_mem_long (2014-06-27 13:23:41 +0100)
> >
> > are available in the git repository at:
> >
> >   git://github.com/bonzini/qemu.git nbd-next
> >
> > for you to fetch changes up to 34bf23a5e0e878e3cd650c47d670b881f9f61475:
> >
> >   nbd: Handle NBD_OPT_LIST option. (2014-06-27 16:06:48 +0200)
> >
> > Three bugfixes, and a new feature.
> 
> Hi. I'm afraid this doesn't build on win32:

Hi Peter,

Should be fixed with s/SHUT_RDWR/2/

That is how shutdown() is called elsewhere in nbd.c and block/nbd-client.c

> /home/petmay01/linaro/qemu-for-merges/blockdev-nbd.c: In function 
> ‘nbd_accept’:
> /home/petmay01/linaro/qemu-for-merges/blockdev-nbd.c:31: error:
> ‘SHUT_RDWR’ undeclared (first use in this function)
> /home/petmay01/linaro/qemu-for-merges/blockdev-nbd.c:31: error: (Each
> undeclared identifier is reported only once
> /home/petmay01/linaro/qemu-for-merges/blockdev-nbd.c:31: error: for
> each function it appears in.)
> make: *** [blockdev-nbd.o] Error 1
> 
> thanks
> -- PMM
> 



[Qemu-devel] [PATCHv2] usb: Fix usb-bt-dongle initialization.

2014-06-17 Thread Hani Benhabiles
Due to an incomplete initialization, adding a usb-bt-dongle device through HMP
or QMP will cause a segmentation fault.

Signed-off-by: Hani Benhabiles 
Suggested-by: Paolo Bonzini 
---

Compared to v1:
* Remove duplicate code from usb_bt_init() and inline usb_create_simple() call.
* usb_bt_initfn() check for s->hci.

 hw/usb/dev-bluetooth.c | 24 
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
index a9661d2..a76e581 100644
--- a/hw/usb/dev-bluetooth.c
+++ b/hw/usb/dev-bluetooth.c
@@ -19,6 +19,7 @@
  */
 
 #include "qemu-common.h"
+#include "qemu/error-report.h"
 #include "hw/usb.h"
 #include "hw/usb/desc.h"
 #include "sysemu/bt.h"
@@ -506,6 +507,14 @@ static int usb_bt_initfn(USBDevice *dev)
 
 usb_desc_create_serial(dev);
 usb_desc_init(dev);
+s->dev.opaque = s;
+if (!s->hci) {
+s->hci = bt_new_hci(qemu_find_bt_vlan(0));
+}
+s->hci->opaque = s;
+s->hci->evt_recv = usb_bt_out_hci_packet_event;
+s->hci->acl_recv = usb_bt_out_hci_packet_acl;
+usb_bt_handle_reset(&s->dev);
 s->intr = usb_ep_get(dev, USB_TOKEN_IN, USB_EVT_EP);
 
 return 0;
@@ -516,6 +525,7 @@ static USBDevice *usb_bt_init(USBBus *bus, const char 
*cmdline)
 USBDevice *dev;
 struct USBBtState *s;
 HCIInfo *hci;
+const char *name = "usb-bt-dongle";
 
 if (*cmdline) {
 hci = hci_init(cmdline);
@@ -525,19 +535,17 @@ static USBDevice *usb_bt_init(USBBus *bus, const char 
*cmdline)
 
 if (!hci)
 return NULL;
-dev = usb_create_simple(bus, "usb-bt-dongle");
+dev = usb_create(bus, name);
 if (!dev) {
+error_report("Failed to create USB device '%s'", name);
 return NULL;
 }
 s = DO_UPCAST(struct USBBtState, dev, dev);
-s->dev.opaque = s;
-
 s->hci = hci;
-s->hci->opaque = s;
-s->hci->evt_recv = usb_bt_out_hci_packet_event;
-s->hci->acl_recv = usb_bt_out_hci_packet_acl;
-
-usb_bt_handle_reset(&s->dev);
+if (qdev_init(&dev->qdev) < 0) {
+error_report("Failed to initialize USB device '%s'", name);
+return NULL;
+}
 
 return dev;
 }
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH] usb: Fix usb-bt-dongle segfault.

2014-06-17 Thread Hani Benhabiles
On Mon, Jun 16, 2014 at 11:00:42AM +0200, Paolo Bonzini wrote:
> Il 15/06/2014 23:37, Hani Benhabiles ha scritto:
> >>>diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
> >>>index a9661d2..6d02343 100644
> >>>--- a/hw/usb/dev-bluetooth.c
> >>>+++ b/hw/usb/dev-bluetooth.c
> >>>@@ -506,6 +506,12 @@ static int usb_bt_initfn(USBDevice *dev)
> >>>
> >>>usb_desc_create_serial(dev);
> >>>usb_desc_init(dev);
> >>>+s->dev.opaque = s;
> >>>+s->hci = bt_new_hci(qemu_find_bt_vlan(0));
> >>>+s->hci->opaque = s;
> >>>+s->hci->evt_recv = usb_bt_out_hci_packet_event;
> >>>+s->hci->acl_recv = usb_bt_out_hci_packet_acl;
> >>>+usb_bt_handle_reset(&s->dev);
> >>
> >>
> >>All lines but the s->hci assignment should be removed from usb_bt_init too.
> >>
> >>As to s->hci, I suggest inlining usb_create_simple into usb_bt_init, and
> >>initializing s->hci there before doing the qdev_init() call.
> >>
> >>Then here you can wrap the assignment under "if (!s->hci)".
> >
> >I am afraid I don't quite understand what you want to achieve with this and 
> >why.
> >
> >Could you please explain how is usb_bt_init() relevant to this case ?
> 
> usb_bt_init() ends up calling usb_bt_initfn(), via usb_create_simple. So if
> you add code to usb_bt_initfn() you can remove the corresponding lines in
> usb_bt_init().

Thanks for the clarification. I forgot about -usbdevice bt, will send v2 
shortly.



Re: [Qemu-devel] [PATCH] usb: Fix usb-bt-dongle segfault.

2014-06-15 Thread Hani Benhabiles
On Wed, Jun 11, 2014 at 08:58:08PM +0200, Paolo Bonzini wrote:
> Il 11/06/2014 19:25, Hani Benhabiles ha scritto:
> >Due to an incomplete initialization, adding a usb-bt-dongle device through 
> >HMP
> >or QMP will cause a segmentation fault.
> >
> >Signed-off-by: Hani Benhabiles 
> >---
> >
> >Not sure about the exact policy of qemu-stable. CC'ing it as this bug 
> >results in
> >a segfault.
> >
> > hw/usb/dev-bluetooth.c | 6 ++
> > 1 file changed, 6 insertions(+)
> >
> >diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
> >index a9661d2..6d02343 100644
> >--- a/hw/usb/dev-bluetooth.c
> >+++ b/hw/usb/dev-bluetooth.c
> >@@ -506,6 +506,12 @@ static int usb_bt_initfn(USBDevice *dev)
> >
> > usb_desc_create_serial(dev);
> > usb_desc_init(dev);
> >+s->dev.opaque = s;
> >+s->hci = bt_new_hci(qemu_find_bt_vlan(0));
> >+s->hci->opaque = s;
> >+s->hci->evt_recv = usb_bt_out_hci_packet_event;
> >+s->hci->acl_recv = usb_bt_out_hci_packet_acl;
> >+usb_bt_handle_reset(&s->dev);
> 
> 
> All lines but the s->hci assignment should be removed from usb_bt_init too.
> 
> As to s->hci, I suggest inlining usb_create_simple into usb_bt_init, and
> initializing s->hci there before doing the qdev_init() call.
> 
> Then here you can wrap the assignment under "if (!s->hci)".

I am afraid I don't quite understand what you want to achieve with this and why.

Could you please explain how is usb_bt_init() relevant to this case ?

Thanks

> 
> Thanks for TLC of this little-used piece of code.
> 
> Paolo
> 
> > s->intr = usb_ep_get(dev, USB_TOKEN_IN, USB_EVT_EP);
> >
> > return 0;
> >
> 



Re: [Qemu-devel] [PATCH] watchdog: Export watchdog actions list.

2014-06-15 Thread Hani Benhabiles
On Sun, Jun 15, 2014 at 03:57:46PM +0200, Paolo Bonzini wrote:
> Il 15/06/2014 12:03, Hani Benhabiles ha scritto:
> >Also, use it instead of using hard-coded values.
> >
> >Signed-off-by: Hani Benhabiles 
> >---
> >Should have been part of the last monitor completion series, but better late
> >then never. :)
> >
> > hw/watchdog/watchdog.c| 35 +++
> > include/sysemu/watchdog.h |  6 ++
> > monitor.c | 19 ---
> > 3 files changed, 37 insertions(+), 23 deletions(-)
> >
> >diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
> >index f28161b..3bea6fe 100644
> >--- a/hw/watchdog/watchdog.c
> >+++ b/hw/watchdog/watchdog.c
> >@@ -39,6 +39,16 @@
> > static int watchdog_action = WDT_RESET;
> > static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
> >
> >+struct watchdog_action watchdog_actions[] = {
> >+{ "reset",  WDT_RESET },
> >+{ "shutdown", WDT_SHUTDOWN },
> >+{ "poweroff", WDT_POWEROFF },
> >+{ "pause", WDT_PAUSE },
> >+{ "debug", WDT_DEBUG },
> >+{ "none", WDT_NONE },
> >+{ NULL, 0 },
> >+};
> 
> The QAPI event series instead used a QAPI enum and renamed this to something
> like WATCHDOG_ACTION_{RESET,SHUTDOWN,...} at the same time.
> 
> I guess we can wait for those patches to go in.

Sounds alright to me. Will wait for them.

> 
> Paolo
> 
> > void watchdog_add_model(WatchdogTimerModel *model)
> > {
> > QLIST_INSERT_HEAD(&watchdog_list, model, entry);
> >@@ -83,22 +93,15 @@ int select_watchdog(const char *p)
> >
> > int select_watchdog_action(const char *p)
> > {
> >-if (strcasecmp(p, "reset") == 0)
> >-watchdog_action = WDT_RESET;
> >-else if (strcasecmp(p, "shutdown") == 0)
> >-watchdog_action = WDT_SHUTDOWN;
> >-else if (strcasecmp(p, "poweroff") == 0)
> >-watchdog_action = WDT_POWEROFF;
> >-else if (strcasecmp(p, "pause") == 0)
> >-watchdog_action = WDT_PAUSE;
> >-else if (strcasecmp(p, "debug") == 0)
> >-watchdog_action = WDT_DEBUG;
> >-else if (strcasecmp(p, "none") == 0)
> >-watchdog_action = WDT_NONE;
> >-else
> >-return -1;
> >-
> >-return 0;
> >+int i;
> >+
> >+for (i = 0; watchdog_actions[i].name; i++) {
> >+if (!strcasecmp(p, watchdog_actions[i].name)) {
> >+watchdog_action = watchdog_actions[i].action;
> >+return 0;
> >+}
> >+}
> >+return -1;
> > }
> >
> > static void watchdog_mon_event(const char *action)
> >diff --git a/include/sysemu/watchdog.h b/include/sysemu/watchdog.h
> >index 3e9a970..2bfe2fc 100644
> >--- a/include/sysemu/watchdog.h
> >+++ b/include/sysemu/watchdog.h
> >@@ -34,6 +34,12 @@ struct WatchdogTimerModel {
> > };
> > typedef struct WatchdogTimerModel WatchdogTimerModel;
> >
> >+struct watchdog_action {
> >+const char *name;
> >+int action;
> >+};
> >+extern struct watchdog_action watchdog_actions[];
> >+
> > /* in hw/watchdog.c */
> > int select_watchdog(const char *p);
> > int select_watchdog_action(const char *action);
> >diff --git a/monitor.c b/monitor.c
> >index ee9390f..57d23c6 100644
> >--- a/monitor.c
> >+++ b/monitor.c
> >@@ -4562,16 +4562,21 @@ void netdev_del_completion(ReadLineState *rs, int 
> >nb_args, const char *str)
> >
> > void watchdog_action_completion(ReadLineState *rs, int nb_args, const char 
> > *str)
> > {
> >+int i;
> >+size_t len;
> >+
> > if (nb_args != 2) {
> > return;
> > }
> >-readline_set_completion_index(rs, strlen(str));
> >-add_completion_option(rs, str, "reset");
> >-add_completion_option(rs, str, "shutdown");
> >-add_completion_option(rs, str, "poweroff");
> >-add_completion_option(rs, str, "pause");
> >-add_completion_option(rs, str, "debug");
> >-add_completion_option(rs, str, "none");
> >+len = strlen(str);
> >+readline_set_completion_index(rs, len);
> >+for (i = 0; watchdog_actions[i].name; i++) {
> >+const char *name = watchdog_actions[i].name;
> >+
> >+if (!strncmp(str, name, len)) {
> >+readline_add_completion(rs, name);
> >+}
> >+}
> > }
> >
> > void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
> >
> 



[Qemu-devel] [PATCH] watchdog: Export watchdog actions list.

2014-06-15 Thread Hani Benhabiles
Also, use it instead of using hard-coded values.

Signed-off-by: Hani Benhabiles 
---
Should have been part of the last monitor completion series, but better late
then never. :)

 hw/watchdog/watchdog.c| 35 +++
 include/sysemu/watchdog.h |  6 ++
 monitor.c | 19 ---
 3 files changed, 37 insertions(+), 23 deletions(-)

diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index f28161b..3bea6fe 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -39,6 +39,16 @@
 static int watchdog_action = WDT_RESET;
 static QLIST_HEAD(watchdog_list, WatchdogTimerModel) watchdog_list;
 
+struct watchdog_action watchdog_actions[] = {
+{ "reset",  WDT_RESET },
+{ "shutdown", WDT_SHUTDOWN },
+{ "poweroff", WDT_POWEROFF },
+{ "pause", WDT_PAUSE },
+{ "debug", WDT_DEBUG },
+{ "none", WDT_NONE },
+{ NULL, 0 },
+};
+
 void watchdog_add_model(WatchdogTimerModel *model)
 {
 QLIST_INSERT_HEAD(&watchdog_list, model, entry);
@@ -83,22 +93,15 @@ int select_watchdog(const char *p)
 
 int select_watchdog_action(const char *p)
 {
-if (strcasecmp(p, "reset") == 0)
-watchdog_action = WDT_RESET;
-else if (strcasecmp(p, "shutdown") == 0)
-watchdog_action = WDT_SHUTDOWN;
-else if (strcasecmp(p, "poweroff") == 0)
-watchdog_action = WDT_POWEROFF;
-else if (strcasecmp(p, "pause") == 0)
-watchdog_action = WDT_PAUSE;
-else if (strcasecmp(p, "debug") == 0)
-watchdog_action = WDT_DEBUG;
-else if (strcasecmp(p, "none") == 0)
-watchdog_action = WDT_NONE;
-else
-return -1;
-
-return 0;
+int i;
+
+for (i = 0; watchdog_actions[i].name; i++) {
+if (!strcasecmp(p, watchdog_actions[i].name)) {
+watchdog_action = watchdog_actions[i].action;
+return 0;
+}
+}
+return -1;
 }
 
 static void watchdog_mon_event(const char *action)
diff --git a/include/sysemu/watchdog.h b/include/sysemu/watchdog.h
index 3e9a970..2bfe2fc 100644
--- a/include/sysemu/watchdog.h
+++ b/include/sysemu/watchdog.h
@@ -34,6 +34,12 @@ struct WatchdogTimerModel {
 };
 typedef struct WatchdogTimerModel WatchdogTimerModel;
 
+struct watchdog_action {
+const char *name;
+int action;
+};
+extern struct watchdog_action watchdog_actions[];
+
 /* in hw/watchdog.c */
 int select_watchdog(const char *p);
 int select_watchdog_action(const char *action);
diff --git a/monitor.c b/monitor.c
index ee9390f..57d23c6 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4562,16 +4562,21 @@ void netdev_del_completion(ReadLineState *rs, int 
nb_args, const char *str)
 
 void watchdog_action_completion(ReadLineState *rs, int nb_args, const char 
*str)
 {
+int i;
+size_t len;
+
 if (nb_args != 2) {
 return;
 }
-readline_set_completion_index(rs, strlen(str));
-add_completion_option(rs, str, "reset");
-add_completion_option(rs, str, "shutdown");
-add_completion_option(rs, str, "poweroff");
-add_completion_option(rs, str, "pause");
-add_completion_option(rs, str, "debug");
-add_completion_option(rs, str, "none");
+len = strlen(str);
+readline_set_completion_index(rs, len);
+for (i = 0; watchdog_actions[i].name; i++) {
+const char *name = watchdog_actions[i].name;
+
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
 }
 
 void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
-- 
1.8.3.2




[Qemu-devel] [PATCH] usb: Fix usb-bt-dongle segfault.

2014-06-11 Thread Hani Benhabiles
Due to an incomplete initialization, adding a usb-bt-dongle device through HMP
or QMP will cause a segmentation fault.

Signed-off-by: Hani Benhabiles 
---

Not sure about the exact policy of qemu-stable. CC'ing it as this bug results in
a segfault.

 hw/usb/dev-bluetooth.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/hw/usb/dev-bluetooth.c b/hw/usb/dev-bluetooth.c
index a9661d2..6d02343 100644
--- a/hw/usb/dev-bluetooth.c
+++ b/hw/usb/dev-bluetooth.c
@@ -506,6 +506,12 @@ static int usb_bt_initfn(USBDevice *dev)
 
 usb_desc_create_serial(dev);
 usb_desc_init(dev);
+s->dev.opaque = s;
+s->hci = bt_new_hci(qemu_find_bt_vlan(0));
+s->hci->opaque = s;
+s->hci->evt_recv = usb_bt_out_hci_packet_event;
+s->hci->acl_recv = usb_bt_out_hci_packet_acl;
+usb_bt_handle_reset(&s->dev);
 s->intr = usb_ep_get(dev, USB_TOKEN_IN, USB_EVT_EP);
 
 return 0;
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH] readline: Clear screen on form feed.

2014-06-09 Thread Hani Benhabiles
On Mon, Jun 09, 2014 at 04:32:32PM -0400, Luiz Capitulino wrote:
> On Sun,  1 Jun 2014 12:53:35 +0100
> Hani Benhabiles  wrote:
> 
> > Signed-off-by: Hani Benhabiles 
> > ---
> >  util/readline.c | 9 +
> >  1 file changed, 9 insertions(+)
> > 
> > diff --git a/util/readline.c b/util/readline.c
> > index 8baec55..08d07e3 100644
> > --- a/util/readline.c
> > +++ b/util/readline.c
> > @@ -345,6 +345,12 @@ static void readline_completion(ReadLineState *rs)
> >  }
> >  }
> >  
> > +static void readline_clear_screen(ReadLineState *rs)
> > +{
> > +rs->printf_func(rs->opaque, "\033[2J\033[1;1H");
> 
> That's a smart way of doing it and I can't suggest anything better. But
> what happens on Windows?

Sorry, I have no experience with Windows and I can't give a definite answer 
about it.

But as Michael pointed out, readline is already using similar escape sequences.

> 
> > +readline_show_prompt(rs);
> > +}
> > +
> >  /* return true if command handled */
> >  void readline_handle_byte(ReadLineState *rs, int ch)
> >  {
> > @@ -363,6 +369,9 @@ void readline_handle_byte(ReadLineState *rs, int ch)
> >  case 9:
> >  readline_completion(rs);
> >  break;
> > +case 12:
> > +readline_clear_screen(rs);
> > +break;
> >  case 10:
> >  case 13:
> >  rs->cmd_buf[rs->cmd_buf_size] = '\0';
> 



[Qemu-devel] [PATCH 1/2] nbd: Handle fixed new-style clients.

2014-06-06 Thread Hani Benhabiles
When this flag is set, the server tells the client that it can send another
option if the server received a request with an option that it doesn't
understand instead of directly closing the connection.

Also add link to the most up-to-date documentation.

Signed-off-by: Hani Benhabiles 
---
 include/block/nbd.h |   9 
 nbd.c   | 143 
 2 files changed, 109 insertions(+), 43 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 79502a0..561b70c 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -45,6 +45,15 @@ struct nbd_reply {
 #define NBD_FLAG_ROTATIONAL (1 << 4)/* Use elevator algorithm - 
rotational media */
 #define NBD_FLAG_SEND_TRIM  (1 << 5)/* Send TRIM (discard) */
 
+/* New-style global flags. */
+#define NBD_FLAG_FIXED_NEWSTYLE (1 << 0)/* Fixed newstyle protocol. */
+
+/* New-style client flags. */
+#define NBD_FLAG_C_FIXED_NEWSTYLE   (1 << 0)/* Fixed newstyle protocol. */
+
+/* Reply types. */
+#define NBD_REP_ERR_UNSUP   ((1 << 31) | 1) /* Unknown option. */
+
 #define NBD_CMD_MASK_COMMAND   0x
 #define NBD_CMD_FLAG_FUA   (1 << 16)
 
diff --git a/nbd.c b/nbd.c
index e0d032c..7cee1ef 100644
--- a/nbd.c
+++ b/nbd.c
@@ -56,7 +56,11 @@
 __FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
 } while(0)
 
-/* This is all part of the "official" NBD API */
+/* This is all part of the "official" NBD API.
+ *
+ * The most up-to-date documentation is available at:
+ * https://github.com/yoe/nbd/blob/master/doc/proto.txt
+ */
 
 #define NBD_REQUEST_SIZE(4 + 4 + 8 + 8 + 4)
 #define NBD_REPLY_SIZE  (4 + 4 + 8)
@@ -64,6 +68,7 @@
 #define NBD_REPLY_MAGIC 0x67446698
 #define NBD_OPTS_MAGIC  0x49484156454F5054LL
 #define NBD_CLIENT_MAGIC0x420281861253LL
+#define NBD_REP_MAGIC   0x3e889045565a9LL
 
 #define NBD_SET_SOCK_IO(0xab, 0)
 #define NBD_SET_BLKSIZE _IO(0xab, 1)
@@ -77,7 +82,8 @@
 #define NBD_SET_TIMEOUT _IO(0xab, 9)
 #define NBD_SET_FLAGS   _IO(0xab, 10)
 
-#define NBD_OPT_EXPORT_NAME (1 << 0)
+#define NBD_OPT_EXPORT_NAME (1)
+#define NBD_OPT_ABORT   (2)
 
 /* Definitions for opaque data types */
 
@@ -215,53 +221,44 @@ static ssize_t write_sync(int fd, void *buffer, size_t 
size)
 
 */
 
-static int nbd_receive_options(NBDClient *client)
+static int nbd_send_rep(int csock, uint32_t type, uint32_t opt)
 {
-int csock = client->sock;
-char name[256];
-uint32_t tmp, length;
 uint64_t magic;
-int rc;
+uint32_t len;
 
-/* Client sends:
-[ 0 ..   3]   reserved (0)
-[ 4 ..  11]   NBD_OPTS_MAGIC
-[12 ..  15]   NBD_OPT_EXPORT_NAME
-[16 ..  19]   length
-[20 ..  xx]   export name (length bytes)
- */
-
-rc = -EINVAL;
-if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
-LOG("read failed");
-goto fail;
+magic = cpu_to_be64(NBD_REP_MAGIC);
+if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+LOG("write failed (rep magic)");
+return -EINVAL;
 }
-TRACE("Checking reserved");
-if (tmp != 0) {
-LOG("Bad reserved received");
-goto fail;
+opt = cpu_to_be32(opt);
+if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
+LOG("write failed (rep opt)");
+return -EINVAL;
 }
-
-if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
-LOG("read failed");
-goto fail;
+type = cpu_to_be32(type);
+if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
+LOG("write failed (rep type)");
+return -EINVAL;
 }
-TRACE("Checking reserved");
-if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
-LOG("Bad magic received");
-goto fail;
+len = cpu_to_be32(0);
+if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
+LOG("write failed (rep data length)");
+return -EINVAL;
 }
+return 0;
+}
 
-if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
-LOG("read failed");
-goto fail;
-}
-TRACE("Checking option");
-if (tmp != be32_to_cpu(NBD_OPT_EXPORT_NAME)) {
-LOG("Bad option received");
-goto fail;
-}
+static int nbd_handle_export_name(NBDClient *client)
+{
+int rc = -EINVAL, csock = client->sock;
+char name[256];
+uint32_t length;
 
+/* Client sends:
+[16 ..  19]   length
+[20 ..  xx]   export name (length bytes)
+ */
 if (read_sync(csock, &length, sizeof(length)) != sizeof(length)) {
 LOG("read failed");
 goto fail;
@@ -28

[Qemu-devel] [PATCH 0/2] nbd: Add exports listing support

2014-06-06 Thread Hani Benhabiles
Compared to v2:
* 1/2: Handle options in loop. Handle NBD_OPT_ABORT. Add link to documentation.
  Improve commit message.
* 2/2: Fix return value in NBD_OPT_LIST case. Rename nbd_send_list() function to
  nbd_handle_list().
* Remove patch 3/3 from v2. Applied separately by Paolo.

Hani Benhabiles (2):
  nbd: Handle fixed new-style clients.
  nbd: Handle NBD_OPT_LIST option.

 include/block/nbd.h |  11 +++
 nbd.c   | 200 +---
 2 files changed, 170 insertions(+), 41 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [PATCH 2/2] nbd: Handle NBD_OPT_LIST option.

2014-06-06 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 include/block/nbd.h |  2 ++
 nbd.c   | 61 +
 2 files changed, 63 insertions(+)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 561b70c..fd7e057 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -52,6 +52,8 @@ struct nbd_reply {
 #define NBD_FLAG_C_FIXED_NEWSTYLE   (1 << 0)/* Fixed newstyle protocol. */
 
 /* Reply types. */
+#define NBD_REP_ACK (1) /* Data sending finished. */
+#define NBD_REP_SERVER  (2) /* Export description. */
 #define NBD_REP_ERR_UNSUP   ((1 << 31) | 1) /* Unknown option. */
 
 #define NBD_CMD_MASK_COMMAND   0x
diff --git a/nbd.c b/nbd.c
index 7cee1ef..5d524b8 100644
--- a/nbd.c
+++ b/nbd.c
@@ -84,6 +84,7 @@
 
 #define NBD_OPT_EXPORT_NAME (1)
 #define NBD_OPT_ABORT   (2)
+#define NBD_OPT_LIST(3)
 
 /* Definitions for opaque data types */
 
@@ -249,6 +250,60 @@ static int nbd_send_rep(int csock, uint32_t type, uint32_t 
opt)
 return 0;
 }
 
+static int nbd_send_rep_list(int csock, NBDExport *exp)
+{
+uint64_t magic, name_len;
+uint32_t opt, type, len;
+
+name_len = strlen(exp->name);
+magic = cpu_to_be64(NBD_REP_MAGIC);
+if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+LOG("write failed (magic)");
+return -EINVAL;
+ }
+opt = cpu_to_be32(NBD_OPT_LIST);
+if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
+LOG("write failed (opt)");
+return -EINVAL;
+}
+type = cpu_to_be32(NBD_REP_SERVER);
+if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
+LOG("write failed (reply type)");
+return -EINVAL;
+}
+len = cpu_to_be32(name_len + sizeof(len));
+if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
+LOG("write failed (length)");
+return -EINVAL;
+}
+len = cpu_to_be32(name_len);
+if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
+LOG("write failed (length)");
+return -EINVAL;
+}
+if (write_sync(csock, exp->name, name_len) != name_len) {
+LOG("write failed (buffer)");
+return -EINVAL;
+}
+return 0;
+}
+
+static int nbd_handle_list(NBDClient *client)
+{
+int csock;
+NBDExport *exp;
+
+csock = client->sock;
+/* For each export, send a NBD_REP_SERVER reply. */
+QTAILQ_FOREACH(exp, &exports, next) {
+if (nbd_send_rep_list(csock, exp)) {
+return -EINVAL;
+}
+}
+/* Finish with a NBD_REP_ACK. */
+return nbd_send_rep(csock, NBD_REP_ACK, NBD_OPT_LIST);
+}
+
 static int nbd_handle_export_name(NBDClient *client)
 {
 int rc = -EINVAL, csock = client->sock;
@@ -330,6 +385,12 @@ static int nbd_receive_options(NBDClient *client)
 
 TRACE("Checking option");
 switch (be32_to_cpu(tmp)) {
+case NBD_OPT_LIST:
+if (nbd_handle_list(client) < 0) {
+return -EINVAL;
+}
+return 1;
+
 case NBD_OPT_ABORT:
 return 1;
 
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH 3/3] nbd: Shutdown socket before closing.

2014-06-05 Thread Hani Benhabiles
On Thu, Jun 05, 2014 at 03:55:40AM +0200, Paolo Bonzini wrote:
> Il 05/06/2014 00:33, Hani Benhabiles ha scritto:
> >> IIUC, what this does is ensure that the other side gets a FIN before it 
> >> gets
> >> a RST.  Is this correct?
> >
> >Yes. Without shutdown(), this could be reproduced (unreliably) on multiple
> >tries. This is done in nbd_client_close() too, for the same reasons AFAICT.
> 
> Actually, nbd_client_close() is different because it's an abortive close of
> the socket.  nbd_client_close() doesn't care about FIN vs. RST, it does the
> shutdown to force all the requests to fail (with either an error for writes,
> or a short read if they're receiving).  This will cause a flurry of
> nbd_client_put() calls soon after nbd_clint_close() returns, until the last
> reference is dropped and the socket is closed.
> 

I see, thanks for the explanation.

> I'll apply the patch.

Will you apply it directly or should I resend it in v3 ?



Re: [Qemu-devel] [PATCH 2/3] nbd: Add exports listing support.

2014-06-04 Thread Hani Benhabiles
On Tue, Jun 03, 2014 at 01:36:35PM +0200, Paolo Bonzini wrote:
> Il 31/05/2014 23:39, Hani Benhabiles ha scritto:
> >This is added by handling the NBD_OPT_LIST and NBD_OPT_ABORT options.
> >
> >NBD_REP_ERR_UNSUP is also sent for unknown NBD option values.
> >
> >Signed-off-by: Hani Benhabiles 
> >---
> > include/block/nbd.h |   5 ++
> > nbd.c   | 197 
> > +---
> > 2 files changed, 162 insertions(+), 40 deletions(-)
> >
> >diff --git a/include/block/nbd.h b/include/block/nbd.h
> >index 95d52ab..fd7e057 100644
> >--- a/include/block/nbd.h
> >+++ b/include/block/nbd.h
> >@@ -51,6 +51,11 @@ struct nbd_reply {
> > /* New-style client flags. */
> > #define NBD_FLAG_C_FIXED_NEWSTYLE   (1 << 0)/* Fixed newstyle protocol. 
> > */
> >
> >+/* Reply types. */
> >+#define NBD_REP_ACK (1) /* Data sending finished. */
> >+#define NBD_REP_SERVER  (2) /* Export description. */
> >+#define NBD_REP_ERR_UNSUP   ((1 << 31) | 1) /* Unknown option. */
> >+
> > #define NBD_CMD_MASK_COMMAND0x
> > #define NBD_CMD_FLAG_FUA(1 << 16)
> >
> >diff --git a/nbd.c b/nbd.c
> >index aa2e552..012e5da 100644
> >--- a/nbd.c
> >+++ b/nbd.c
> >@@ -64,6 +64,7 @@
> > #define NBD_REPLY_MAGIC 0x67446698
> > #define NBD_OPTS_MAGIC  0x49484156454F5054LL
> > #define NBD_CLIENT_MAGIC0x420281861253LL
> >+#define NBD_REP_MAGIC   0x3e889045565a9LL
> >
> > #define NBD_SET_SOCK_IO(0xab, 0)
> > #define NBD_SET_BLKSIZE _IO(0xab, 1)
> >@@ -77,7 +78,9 @@
> > #define NBD_SET_TIMEOUT _IO(0xab, 9)
> > #define NBD_SET_FLAGS   _IO(0xab, 10)
> >
> >-#define NBD_OPT_EXPORT_NAME (1 << 0)
> >+#define NBD_OPT_EXPORT_NAME (1)
> >+#define NBD_OPT_ABORT   (2)
> >+#define NBD_OPT_LIST(3)
> >
> > /* Definitions for opaque data types */
> >
> >@@ -215,54 +218,98 @@ static ssize_t write_sync(int fd, void *buffer, size_t 
> >size)
> >
> > */
> >
> >-static int nbd_receive_options(NBDClient *client)
> >+static int nbd_send_rep(int csock, uint32_t type, uint32_t opt)
> > {
> >-int csock = client->sock;
> >-char name[256];
> >-uint32_t tmp, length;
> > uint64_t magic;
> >-int rc;
> >-
> >-/* Client sends:
> >-[ 0 ..   3]   client flags
> >-[ 4 ..  11]   NBD_OPTS_MAGIC
> >-[12 ..  15]   NBD_OPT_EXPORT_NAME
> >-[16 ..  19]   length
> >-[20 ..  xx]   export name (length bytes)
> >- */
> >+uint32_t len;
> >
> >-rc = -EINVAL;
> >-if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
> >-LOG("read failed");
> >-goto fail;
> >+magic = cpu_to_be64(NBD_REP_MAGIC);
> >+if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
> >+LOG("write failed (rep magic)");
> >+return -EINVAL;
> > }
> >-TRACE("Checking client flags");
> >-tmp = be32_to_cpu(tmp);
> >-if (tmp != 0 && tmp != NBD_FLAG_C_FIXED_NEWSTYLE) {
> >-LOG("Bad client flags received");
> >-goto fail;
> >+opt = cpu_to_be32(opt);
> >+if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
> >+LOG("write failed (rep opt)");
> >+return -EINVAL;
> > }
> >-
> >-if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
> >-LOG("read failed");
> >-goto fail;
> >+type = cpu_to_be32(type);
> >+if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
> >+LOG("write failed (rep type)");
> >+return -EINVAL;
> > }
> >-TRACE("Checking opts magic");
> >-if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
> >-LOG("Bad magic received");
> >-goto fail;
> >+len = cpu_to_be32(0);
> >+if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
> >+LOG("write failed (rep data length)");
> >+return -EINVAL;
> > }
> >+return 0;
> >+}
> >
> >-if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
> >-LOG("read failed");
> >-goto fail;
> >+static 

Re: [Qemu-devel] [PATCH 3/3] nbd: Shutdown socket before closing.

2014-06-04 Thread Hani Benhabiles
On Tue, Jun 03, 2014 at 01:33:41PM +0200, Paolo Bonzini wrote:
> Il 31/05/2014 23:39, Hani Benhabiles ha scritto:
> >This forces finishing data sending to client before closing the socket like 
> >in
> >exports listing or replying with NBD_REP_ERR_UNSUP cases.
> >
> >Signed-off-by: Hani Benhabiles 
> >---
> > blockdev-nbd.c | 1 +
> > qemu-nbd.c | 1 +
> > 2 files changed, 2 insertions(+)
> >
> >diff --git a/blockdev-nbd.c b/blockdev-nbd.c
> >index b60b66d..e609f66 100644
> >--- a/blockdev-nbd.c
> >+++ b/blockdev-nbd.c
> >@@ -28,6 +28,7 @@ static void nbd_accept(void *opaque)
> >
> > int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
> > if (fd >= 0 && !nbd_client_new(NULL, fd, nbd_client_put)) {
> >+shutdown(fd, SHUT_RDWR);
> > close(fd);
> > }
> > }
> >diff --git a/qemu-nbd.c b/qemu-nbd.c
> >index ba60436..bf42861 100644
> >--- a/qemu-nbd.c
> >+++ b/qemu-nbd.c
> >@@ -372,6 +372,7 @@ static void nbd_accept(void *opaque)
> > if (nbd_client_new(exp, fd, nbd_client_closed)) {
> > nb_fds++;
> > } else {
> >+shutdown(fd, SHUT_RDWR);
> > close(fd);
> > }
> > }
> >
> 
> IIUC, what this does is ensure that the other side gets a FIN before it gets
> a RST.  Is this correct?

Yes. Without shutdown(), this could be reproduced (unreliably) on multiple
tries. This is done in nbd_client_close() too, for the same reasons AFAICT.



Re: [Qemu-devel] [PATCH 1/3] nbd: Handle fixed new-style clients.

2014-06-02 Thread Hani Benhabiles
On Mon, Jun 02, 2014 at 02:32:06PM +0200, Stefan Hajnoczi wrote:
> On Sat, May 31, 2014 at 10:39:40PM +0100, Hani Benhabiles wrote:
> > Signed-off-by: Hani Benhabiles 
> > ---
> >  include/block/nbd.h |  6 ++
> >  nbd.c   | 12 +++-
> >  2 files changed, 13 insertions(+), 5 deletions(-)
> 
> No explanation or link to specification for this new flag field?  What's
> different about a new-style client?

With this flag is set, the server tells the client that it can send another
option if the server got a request with an option it doesn't understand (instead
of the server closing the connection.) Thus, the while(1) loop in 2/3.

The kernel in Documentation/blockdev/nbd.txt points to the NBD project for
documentation. The proto documentation is in [1]. Shouldn't Qemu also do the
same ?

[1] https://github.com/yoe/nbd/blob/master/doc/proto.txt



Re: [Qemu-devel] [PATCH] readline: Clear screen on form feed.

2014-06-02 Thread Hani Benhabiles
On Mon, Jun 02, 2014 at 02:20:36PM +0200, Stefan Hajnoczi wrote:
> On Sun, Jun 01, 2014 at 12:53:35PM +0100, Hani Benhabiles wrote:
> > Signed-off-by: Hani Benhabiles 
> > ---
> >  util/readline.c | 9 +
> >  1 file changed, 9 insertions(+)
> 
> Please only CC me on patches for areas of the code that I maintain or
> you feel I am an expert in.  That includes block, net, and tracing.
> Monitor and terminal escape sequences isn't my forte :-).

Sure, np. Just used get_maintainer.pl output.



[Qemu-devel] [PATCH] readline: Clear screen on form feed.

2014-06-01 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 util/readline.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/util/readline.c b/util/readline.c
index 8baec55..08d07e3 100644
--- a/util/readline.c
+++ b/util/readline.c
@@ -345,6 +345,12 @@ static void readline_completion(ReadLineState *rs)
 }
 }
 
+static void readline_clear_screen(ReadLineState *rs)
+{
+rs->printf_func(rs->opaque, "\033[2J\033[1;1H");
+readline_show_prompt(rs);
+}
+
 /* return true if command handled */
 void readline_handle_byte(ReadLineState *rs, int ch)
 {
@@ -363,6 +369,9 @@ void readline_handle_byte(ReadLineState *rs, int ch)
 case 9:
 readline_completion(rs);
 break;
+case 12:
+readline_clear_screen(rs);
+break;
 case 10:
 case 13:
 rs->cmd_buf[rs->cmd_buf_size] = '\0';
-- 
1.8.3.2




[Qemu-devel] [PATCH 2/3] nbd: Add exports listing support.

2014-05-31 Thread Hani Benhabiles
This is added by handling the NBD_OPT_LIST and NBD_OPT_ABORT options.

NBD_REP_ERR_UNSUP is also sent for unknown NBD option values.

Signed-off-by: Hani Benhabiles 
---
 include/block/nbd.h |   5 ++
 nbd.c   | 197 +---
 2 files changed, 162 insertions(+), 40 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 95d52ab..fd7e057 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -51,6 +51,11 @@ struct nbd_reply {
 /* New-style client flags. */
 #define NBD_FLAG_C_FIXED_NEWSTYLE   (1 << 0)/* Fixed newstyle protocol. */
 
+/* Reply types. */
+#define NBD_REP_ACK (1) /* Data sending finished. */
+#define NBD_REP_SERVER  (2) /* Export description. */
+#define NBD_REP_ERR_UNSUP   ((1 << 31) | 1) /* Unknown option. */
+
 #define NBD_CMD_MASK_COMMAND   0x
 #define NBD_CMD_FLAG_FUA   (1 << 16)
 
diff --git a/nbd.c b/nbd.c
index aa2e552..012e5da 100644
--- a/nbd.c
+++ b/nbd.c
@@ -64,6 +64,7 @@
 #define NBD_REPLY_MAGIC 0x67446698
 #define NBD_OPTS_MAGIC  0x49484156454F5054LL
 #define NBD_CLIENT_MAGIC0x420281861253LL
+#define NBD_REP_MAGIC   0x3e889045565a9LL
 
 #define NBD_SET_SOCK_IO(0xab, 0)
 #define NBD_SET_BLKSIZE _IO(0xab, 1)
@@ -77,7 +78,9 @@
 #define NBD_SET_TIMEOUT _IO(0xab, 9)
 #define NBD_SET_FLAGS   _IO(0xab, 10)
 
-#define NBD_OPT_EXPORT_NAME (1 << 0)
+#define NBD_OPT_EXPORT_NAME (1)
+#define NBD_OPT_ABORT   (2)
+#define NBD_OPT_LIST(3)
 
 /* Definitions for opaque data types */
 
@@ -215,54 +218,98 @@ static ssize_t write_sync(int fd, void *buffer, size_t 
size)
 
 */
 
-static int nbd_receive_options(NBDClient *client)
+static int nbd_send_rep(int csock, uint32_t type, uint32_t opt)
 {
-int csock = client->sock;
-char name[256];
-uint32_t tmp, length;
 uint64_t magic;
-int rc;
-
-/* Client sends:
-[ 0 ..   3]   client flags
-[ 4 ..  11]   NBD_OPTS_MAGIC
-[12 ..  15]   NBD_OPT_EXPORT_NAME
-[16 ..  19]   length
-[20 ..  xx]   export name (length bytes)
- */
+uint32_t len;
 
-rc = -EINVAL;
-if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
-LOG("read failed");
-goto fail;
+magic = cpu_to_be64(NBD_REP_MAGIC);
+if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+LOG("write failed (rep magic)");
+return -EINVAL;
 }
-TRACE("Checking client flags");
-tmp = be32_to_cpu(tmp);
-if (tmp != 0 && tmp != NBD_FLAG_C_FIXED_NEWSTYLE) {
-LOG("Bad client flags received");
-goto fail;
+opt = cpu_to_be32(opt);
+if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
+LOG("write failed (rep opt)");
+return -EINVAL;
 }
-
-if (read_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
-LOG("read failed");
-goto fail;
+type = cpu_to_be32(type);
+if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
+LOG("write failed (rep type)");
+return -EINVAL;
 }
-TRACE("Checking opts magic");
-if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
-LOG("Bad magic received");
-goto fail;
+len = cpu_to_be32(0);
+if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
+LOG("write failed (rep data length)");
+return -EINVAL;
 }
+return 0;
+}
 
-if (read_sync(csock, &tmp, sizeof(tmp)) != sizeof(tmp)) {
-LOG("read failed");
-goto fail;
+static int nbd_send_rep_list(int csock, NBDExport *exp)
+{
+uint64_t magic, name_len;
+uint32_t opt, type, len;
+
+name_len = strlen(exp->name);
+magic = cpu_to_be64(NBD_REP_MAGIC);
+if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+LOG("write failed (magic)");
+return -EINVAL;
 }
-TRACE("Checking option");
-if (tmp != be32_to_cpu(NBD_OPT_EXPORT_NAME)) {
-LOG("Bad option received");
-goto fail;
+opt = cpu_to_be32(NBD_OPT_LIST);
+if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
+LOG("write failed (opt)");
+return -EINVAL;
+}
+type = cpu_to_be32(NBD_REP_SERVER);
+if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
+LOG("write failed (reply type)");
+return -EINVAL;
+}
+len = cpu_to_be32(name_len + sizeof(len));
+if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
+LOG("write failed (length)");
+return -EINVAL;
+}
+len = cpu_to_be32(name_len);
+if (write_sync(csock, &len, sizeof(len)

[Qemu-devel] [PATCH 3/3] nbd: Shutdown socket before closing.

2014-05-31 Thread Hani Benhabiles
This forces finishing data sending to client before closing the socket like in
exports listing or replying with NBD_REP_ERR_UNSUP cases.

Signed-off-by: Hani Benhabiles 
---
 blockdev-nbd.c | 1 +
 qemu-nbd.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index b60b66d..e609f66 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -28,6 +28,7 @@ static void nbd_accept(void *opaque)
 
 int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
 if (fd >= 0 && !nbd_client_new(NULL, fd, nbd_client_put)) {
+shutdown(fd, SHUT_RDWR);
 close(fd);
 }
 }
diff --git a/qemu-nbd.c b/qemu-nbd.c
index ba60436..bf42861 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -372,6 +372,7 @@ static void nbd_accept(void *opaque)
 if (nbd_client_new(exp, fd, nbd_client_closed)) {
 nb_fds++;
 } else {
+shutdown(fd, SHUT_RDWR);
 close(fd);
 }
 }
-- 
1.8.3.2




[Qemu-devel] [PATCH 0/3] nbd: Add exports listing option

2014-05-31 Thread Hani Benhabiles
Compared to v1:
* 2/3: Handle options in a loop. Handle NBD_OPT_ABORT and send NBD_REP_ERR_UNSUP
   accordingly.
* 3/3: New patch.

Hani Benhabiles (3):
  nbd: Handle fixed new-style clients.
  nbd: Add exports listing support.
  nbd: Shutdown socket before closing.

 blockdev-nbd.c  |   1 +
 include/block/nbd.h |  11 +++
 nbd.c   | 197 +---
 qemu-nbd.c  |   1 +
 4 files changed, 171 insertions(+), 39 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [PATCH 1/3] nbd: Handle fixed new-style clients.

2014-05-31 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 include/block/nbd.h |  6 ++
 nbd.c   | 12 +++-
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 79502a0..95d52ab 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -45,6 +45,12 @@ struct nbd_reply {
 #define NBD_FLAG_ROTATIONAL (1 << 4)/* Use elevator algorithm - 
rotational media */
 #define NBD_FLAG_SEND_TRIM  (1 << 5)/* Send TRIM (discard) */
 
+/* New-style global flags. */
+#define NBD_FLAG_FIXED_NEWSTYLE (1 << 0)/* Fixed newstyle protocol. */
+
+/* New-style client flags. */
+#define NBD_FLAG_C_FIXED_NEWSTYLE   (1 << 0)/* Fixed newstyle protocol. */
+
 #define NBD_CMD_MASK_COMMAND   0x
 #define NBD_CMD_FLAG_FUA   (1 << 16)
 
diff --git a/nbd.c b/nbd.c
index e0d032c..aa2e552 100644
--- a/nbd.c
+++ b/nbd.c
@@ -224,7 +224,7 @@ static int nbd_receive_options(NBDClient *client)
 int rc;
 
 /* Client sends:
-[ 0 ..   3]   reserved (0)
+[ 0 ..   3]   client flags
 [ 4 ..  11]   NBD_OPTS_MAGIC
 [12 ..  15]   NBD_OPT_EXPORT_NAME
 [16 ..  19]   length
@@ -236,9 +236,10 @@ static int nbd_receive_options(NBDClient *client)
 LOG("read failed");
 goto fail;
 }
-TRACE("Checking reserved");
-if (tmp != 0) {
-LOG("Bad reserved received");
+TRACE("Checking client flags");
+tmp = be32_to_cpu(tmp);
+if (tmp != 0 && tmp != NBD_FLAG_C_FIXED_NEWSTYLE) {
+LOG("Bad client flags received");
 goto fail;
 }
 
@@ -246,7 +247,7 @@ static int nbd_receive_options(NBDClient *client)
 LOG("read failed");
 goto fail;
 }
-TRACE("Checking reserved");
+TRACE("Checking opts magic");
 if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
 LOG("Bad magic received");
 goto fail;
@@ -333,6 +334,7 @@ static int nbd_send_negotiate(NBDClient *client)
 cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);
 } else {
 cpu_to_be64w((uint64_t*)(buf + 8), NBD_OPTS_MAGIC);
+cpu_to_be16w((uint16_t *)(buf + 16), NBD_FLAG_FIXED_NEWSTYLE);
 }
 
 if (client->exp) {
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH 1/2] nbd: Handle fixed new-style clients.

2014-05-27 Thread Hani Benhabiles
On Tue, May 27, 2014 at 04:46:46PM +0200, Paolo Bonzini wrote:
> Il 25/05/2014 11:50, Hani Benhabiles ha scritto:
> >@@ -236,9 +236,10 @@ static int nbd_receive_options(NBDClient *client)
> > LOG("read failed");
> > goto fail;
> > }
> >-TRACE("Checking reserved");
> >-if (tmp != 0) {
> >-LOG("Bad reserved received");
> >+TRACE("Checking client flags");
> >+tmp = be32_to_cpu(tmp);
> >+if (tmp != 0 && tmp != NBD_FLAG_C_FIXED_NEWSTYLE) {
> >+LOG("Bad client flags received");
> > goto fail;
> > }
> >
> >@@ -246,7 +247,7 @@ static int nbd_receive_options(NBDClient *client)
> > LOG("read failed");
> > goto fail;
> > }
> >-TRACE("Checking reserved");
> >+TRACE("Checking opts magic");
> > if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
> > LOG("Bad magic received");
> > goto fail;
> 
> Here, if the client used "fixed new-style negotiation" you should reply with
> NBD_REP_ERR_UNSUP.  You also need to turn this into a while loop. With these
> changes here, the logic in patch 2 should be okay.

Hmm, seems that both the nbd-server implementation and the accompanying 
documentation
use NBD_REP_ERR_UNSUP only when the NBD_OPT_* asked for by the client is
unknown, not when the magic value is not NBD_OPTS_MAGIC. So what you are
suggesting should actually happen a little below in the code.

Thanks for the review. Will respin to add that and the loop behaviour.



[Qemu-devel] [PATCHv2 1/8] monitor: Add ringbuf_write and ringbuf_read argument completion.

2014-05-27 Thread Hani Benhabiles
Export chr_is_ringbuf() function. Also remove left-over function prototypes
while at it.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx   |  2 ++
 hmp.h |  2 ++
 include/sysemu/char.h |  3 +--
 monitor.c | 39 +++
 qemu-char.c   |  2 +-
 5 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 2e462c0..dcec5ef 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -852,6 +852,7 @@ ETEXI
 .params = "device data",
 .help   = "Write to a ring buffer character device",
 .mhandler.cmd = hmp_ringbuf_write,
+.command_completion = ringbuf_write_completion,
 },
 
 STEXI
@@ -868,6 +869,7 @@ ETEXI
 .params = "device size",
 .help   = "Read from a ring buffer character device",
 .mhandler.cmd = hmp_ringbuf_read,
+.command_completion = ringbuf_write_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index aba59e9..212e5d2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -103,5 +103,7 @@ void chardev_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
+void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index b81a6ff..7f5eeb3 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -286,9 +286,8 @@ void qemu_chr_add_handlers(CharDriverState *s,
 void qemu_chr_be_generic_open(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
 int qemu_chr_add_client(CharDriverState *s, int fd);
-void qemu_chr_info_print(Monitor *mon, const QObject *ret_data);
-void qemu_chr_info(Monitor *mon, QObject **ret_data);
 CharDriverState *qemu_chr_find(const char *name);
+bool chr_is_ringbuf(const CharDriverState *chr);
 
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 
diff --git a/monitor.c b/monitor.c
index 593679a..93eb6d8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4411,6 +4411,45 @@ void chardev_remove_completion(ReadLineState *rs, int 
nb_args, const char *str)
 qapi_free_ChardevInfoList(start);
 }
 
+static void ringbuf_completion(ReadLineState *rs, const char *str)
+{
+size_t len;
+ChardevInfoList *list, *start;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+
+start = list = qmp_query_chardev(NULL);
+while (list) {
+ChardevInfo *chr_info = list->value;
+
+if (!strncmp(chr_info->label, str, len)) {
+CharDriverState *chr = qemu_chr_find(chr_info->label);
+if (chr && chr_is_ringbuf(chr)) {
+readline_add_completion(rs, chr_info->label);
+}
+}
+list = list->next;
+}
+qapi_free_ChardevInfoList(start);
+}
+
+void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args != 2) {
+return;
+}
+ringbuf_completion(rs, str);
+}
+
+void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args != 2) {
+return;
+}
+ringbuf_completion(rs, str);
+}
+
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 size_t len;
diff --git a/qemu-char.c b/qemu-char.c
index 17b476e..4c04bbc 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2849,7 +2849,7 @@ fail:
 return NULL;
 }
 
-static bool chr_is_ringbuf(const CharDriverState *chr)
+bool chr_is_ringbuf(const CharDriverState *chr)
 {
 return chr->chr_write == ringbuf_chr_write;
 }
-- 
1.8.3.2




[Qemu-devel] [PATCHv2 2/8] monitor: Add watchdog_action argument completion.

2014-05-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  2 ++
 monitor.c   | 14 ++
 3 files changed, 17 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index dcec5ef..45e1763 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1359,6 +1359,7 @@ ETEXI
 .params = "[reset|shutdown|poweroff|pause|debug|none]",
 .help   = "change watchdog action",
 .mhandler.cmd = do_watchdog_action,
+.command_completion = watchdog_action_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 212e5d2..a70804d 100644
--- a/hmp.h
+++ b/hmp.h
@@ -105,5 +105,7 @@ void netdev_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
 void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
+void watchdog_action_completion(ReadLineState *rs, int nb_args,
+const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 93eb6d8..fb300c2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4558,6 +4558,20 @@ void netdev_del_completion(ReadLineState *rs, int 
nb_args, const char *str)
 }
 }
 
+void watchdog_action_completion(ReadLineState *rs, int nb_args, const char 
*str)
+{
+if (nb_args != 2) {
+return;
+}
+readline_set_completion_index(rs, strlen(str));
+add_completion_option(rs, str, "reset");
+add_completion_option(rs, str, "shutdown");
+add_completion_option(rs, str, "poweroff");
+add_completion_option(rs, str, "pause");
+add_completion_option(rs, str, "debug");
+add_completion_option(rs, str, "none");
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCHv2 7/8] monitor: Add host_net_remove arguments completion.

2014-05-27 Thread Hani Benhabiles
Relies on readline unique completion strings patch to make the added vlan/hub
completion values unique, instead of using something like a hash table.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  2 ++
 monitor.c   | 38 ++
 3 files changed, 41 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index aab9cf5..f99da0e 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1227,6 +1227,7 @@ ETEXI
 .params = "vlan_id name",
 .help   = "remove host VLAN client",
 .mhandler.cmd = net_host_device_remove,
+.command_completion = host_net_remove_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 22ee836..a53ad51 100644
--- a/hmp.h
+++ b/hmp.h
@@ -110,5 +110,7 @@ void watchdog_action_completion(ReadLineState *rs, int 
nb_args,
 void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
const char *str);
 void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void host_net_remove_completion(ReadLineState *rs, int nb_args,
+const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index f45e0f3..1226bc9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4609,6 +4609,44 @@ void host_net_add_completion(ReadLineState *rs, int 
nb_args, const char *str)
 }
 }
 
+void host_net_remove_completion(ReadLineState *rs, int nb_args, const char 
*str)
+{
+NetClientState *ncs[255];
+int count, i, len;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+if (nb_args == 2) {
+count = qemu_find_net_clients_except(NULL, ncs,
+ NET_CLIENT_OPTIONS_KIND_NONE, 
255);
+for (i = 0; i < count; i++) {
+int id;
+char name[16];
+
+if (net_hub_id_for_client(ncs[i], &id)) {
+continue;
+}
+snprintf(name, sizeof(name), "%d", id);
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+return;
+} else if (nb_args == 3) {
+count = qemu_find_net_clients_except(NULL, ncs,
+ NET_CLIENT_OPTIONS_KIND_NIC, 255);
+for (i = 0; i < count; i++) {
+const char *name;
+
+name = ncs[i]->name;
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+return;
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCHv2 5/8] monitor: Add host_net_add device argument completion.

2014-05-27 Thread Hani Benhabiles
Also fix the parameters documentation.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  3 ++-
 hmp.h   |  1 +
 monitor.c   | 16 
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 919af6e..aab9cf5 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1209,9 +1209,10 @@ ETEXI
 {
 .name   = "host_net_add",
 .args_type  = "device:s,opts:s?",
-.params = "tap|user|socket|vde|netmap|dump [options]",
+.params = "tap|user|socket|vde|netmap|bridge|dump [options]",
 .help   = "add host VLAN client",
 .mhandler.cmd = net_host_device_add,
+.command_completion = host_net_add_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 0c814d0..22ee836 100644
--- a/hmp.h
+++ b/hmp.h
@@ -109,5 +109,6 @@ void watchdog_action_completion(ReadLineState *rs, int 
nb_args,
 const char *str);
 void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
const char *str);
+void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 6a3a5c9..f45e0f3 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4593,6 +4593,22 @@ void migrate_set_capability_completion(ReadLineState 
*rs, int nb_args,
 }
 }
 
+void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+int i;
+size_t len;
+if (nb_args != 2) {
+return;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+for (i = 0; host_net_devices[i]; i++) {
+if (!strncmp(host_net_devices[i], str, len)) {
+readline_add_completion(rs, host_net_devices[i]);
+}
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCHv2 4/8] net: Export valid host network devices list

2014-05-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 include/net/net.h |  1 +
 net/net.c | 34 --
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 8166345..8b189da 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -177,6 +177,7 @@ struct NICInfo {
 extern int nb_nics;
 extern NICInfo nd_table[MAX_NICS];
 extern int default_net;
+extern const char *host_net_devices[];
 
 /* from net.c */
 extern const char *legacy_tftp_prefix;
diff --git a/net/net.c b/net/net.c
index 0ff2e40..6344160 100644
--- a/net/net.c
+++ b/net/net.c
@@ -49,6 +49,22 @@
 
 static QTAILQ_HEAD(, NetClientState) net_clients;
 
+const char *host_net_devices[] = {
+"tap",
+"socket",
+"dump",
+#ifdef CONFIG_NET_BRIDGE
+"bridge",
+#endif
+#ifdef CONFIG_SLIRP
+"user",
+#endif
+#ifdef CONFIG_VDE
+"vde",
+#endif
+NULL,
+};
+
 int default_net = 1;
 
 /***/
@@ -897,21 +913,11 @@ int net_client_init(QemuOpts *opts, int is_netdev, Error 
**errp)
 static int net_host_check_device(const char *device)
 {
 int i;
-const char *valid_param_list[] = { "tap", "socket", "dump"
-#ifdef CONFIG_NET_BRIDGE
-   , "bridge"
-#endif
-#ifdef CONFIG_SLIRP
-   ,"user"
-#endif
-#ifdef CONFIG_VDE
-   ,"vde"
-#endif
-};
-for (i = 0; i < ARRAY_SIZE(valid_param_list); i++) {
-if (!strncmp(valid_param_list[i], device,
- strlen(valid_param_list[i])))
+for (i = 0; host_net_devices[i]; i++) {
+if (!strncmp(host_net_devices[i], device,
+ strlen(host_net_devices[i]))) {
 return 1;
+}
 }
 
 return 0;
-- 
1.8.3.2




[Qemu-devel] [PATCHv2 0/8] monitor: Command completion for various commands

2014-05-27 Thread Hani Benhabiles
A set of patches adding completion support for various hmp commands. Following
other series that were merged earlier.

Compared to v1:
* patch 04/08: New.
* patch 05/08: Use exported list of host network devices.

Hani Benhabiles (8):
  monitor: Add ringbuf_write and ringbuf_read argument completion.
  monitor: Add watchdog_action argument completion.
  monitor: Add migrate_set_capability completion.
  net: Export valid host network devices list
  monitor: Add host_net_add device argument completion.
  readline: Make completion strings always unique.
  monitor: Add host_net_remove arguments completion.
  monitor: Add delvm and loadvm argument completion.

 hmp-commands.hx   |  10 ++-
 hmp.h |  11 
 include/net/net.h |   1 +
 include/sysemu/char.h |   3 +-
 monitor.c | 176 ++
 net/net.c |  34 ++
 qemu-char.c   |   2 +-
 util/readline.c   |   6 ++
 8 files changed, 225 insertions(+), 18 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [PATCHv2 3/8] monitor: Add migrate_set_capability completion.

2014-05-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  2 ++
 monitor.c   | 21 +
 3 files changed, 24 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 45e1763..919af6e 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -975,6 +975,7 @@ ETEXI
 .params = "capability state",
 .help   = "Enable/Disable the usage of a capability for migration",
 .mhandler.cmd = hmp_migrate_set_capability,
+.command_completion = migrate_set_capability_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index a70804d..0c814d0 100644
--- a/hmp.h
+++ b/hmp.h
@@ -107,5 +107,7 @@ void ringbuf_write_completion(ReadLineState *rs, int 
nb_args, const char *str);
 void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
 void watchdog_action_completion(ReadLineState *rs, int nb_args,
 const char *str);
+void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
+   const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index fb300c2..6a3a5c9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4572,6 +4572,27 @@ void watchdog_action_completion(ReadLineState *rs, int 
nb_args, const char *str)
 add_completion_option(rs, str, "none");
 }
 
+void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
+   const char *str)
+{
+size_t len;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+if (nb_args == 2) {
+int i;
+for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+const char *name = MigrationCapability_lookup[i];
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+} else if (nb_args == 3) {
+add_completion_option(rs, str, "on");
+add_completion_option(rs, str, "off");
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCHv2 6/8] readline: Make completion strings always unique.

2014-05-27 Thread Hani Benhabiles
There is no need to clutter the user's choices with repeating the same value
multiple times.

Signed-off-by: Hani Benhabiles 
---
 util/readline.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/util/readline.c b/util/readline.c
index 8baec55..7214e84 100644
--- a/util/readline.c
+++ b/util/readline.c
@@ -263,6 +263,12 @@ static void readline_hist_add(ReadLineState *rs, const 
char *cmdline)
 void readline_add_completion(ReadLineState *rs, const char *str)
 {
 if (rs->nb_completions < READLINE_MAX_COMPLETIONS) {
+int i;
+for (i = 0; i < rs->nb_completions; i++) {
+if (!strcmp(rs->completions[i], str)) {
+return;
+}
+}
 rs->completions[rs->nb_completions++] = g_strdup(str);
 }
 }
-- 
1.8.3.2




[Qemu-devel] [PATCHv2 8/8] monitor: Add delvm and loadvm argument completion.

2014-05-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  2 ++
 hmp.h   |  2 ++
 monitor.c   | 48 
 3 files changed, 52 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index f99da0e..5f1a677 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -335,6 +335,7 @@ ETEXI
 .params = "tag|id",
 .help   = "restore a VM snapshot from its tag or id",
 .mhandler.cmd = do_loadvm,
+.command_completion = loadvm_completion,
 },
 
 STEXI
@@ -350,6 +351,7 @@ ETEXI
 .params = "tag|id",
 .help   = "delete a VM snapshot from its tag or id",
 .mhandler.cmd = do_delvm,
+.command_completion = delvm_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index a53ad51..2d9b0a2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -112,5 +112,7 @@ void migrate_set_capability_completion(ReadLineState *rs, 
int nb_args,
 void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void host_net_remove_completion(ReadLineState *rs, int nb_args,
 const char *str);
+void delvm_completion(ReadLineState *rs, int nb_args, const char *str);
+void loadvm_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 1226bc9..0b40255 100644
--- a/monitor.c
+++ b/monitor.c
@@ -69,6 +69,7 @@
 #include "qmp-commands.h"
 #include "hmp.h"
 #include "qemu/thread.h"
+#include "block/qapi.h"
 
 /* for pic/irq_info */
 #if defined(TARGET_SPARC)
@@ -4647,6 +4648,53 @@ void host_net_remove_completion(ReadLineState *rs, int 
nb_args, const char *str)
 }
 }
 
+static void vm_completion(ReadLineState *rs, const char *str)
+{
+size_t len;
+BlockDriverState *bs = NULL;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+while ((bs = bdrv_next(bs))) {
+SnapshotInfoList *snapshots, *snapshot;
+
+if (!bdrv_can_snapshot(bs)) {
+continue;
+}
+if (bdrv_query_snapshot_info_list(bs, &snapshots, NULL)) {
+continue;
+}
+snapshot = snapshots;
+while (snapshot) {
+char *completion = snapshot->value->name;
+if (!strncmp(str, completion, len)) {
+readline_add_completion(rs, completion);
+}
+completion = snapshot->value->id;
+if (!strncmp(str, completion, len)) {
+readline_add_completion(rs, completion);
+}
+snapshot = snapshot->next;
+}
+qapi_free_SnapshotInfoList(snapshots);
+}
+
+}
+
+void delvm_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args == 2) {
+vm_completion(rs, str);
+}
+}
+
+void loadvm_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args == 2) {
+vm_completion(rs, str);
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH 4/7] monitor: Add host_net_add device argument completion.

2014-05-25 Thread Hani Benhabiles
On Fri, May 23, 2014 at 02:05:03PM +0200, Stefan Hajnoczi wrote:
> On Tue, May 20, 2014 at 12:03:17AM +0100, Hani Benhabiles wrote:
> > diff --git a/hmp-commands.hx b/hmp-commands.hx
> > index 919af6e..6aaec1b 100644
> > --- a/hmp-commands.hx
> > +++ b/hmp-commands.hx
> > @@ -1209,9 +1209,10 @@ ETEXI
> >  {
> >  .name   = "host_net_add",
> >  .args_type  = "device:s,opts:s?",
> > -.params = "tap|user|socket|vde|netmap|dump [options]",
> > +.params = "tap|user|socket|vde|bridge|dump [options]",
> 
> Why did you delete "netmap"?  I guess "bridge" should have been appended.
> 

Because "netmap" fails the net_host_check_device() check:

(qemu) host_net_add user
(qemu) host_net_add f
invalid host network device f
(qemu) host_net_add netmap
invalid host network device netmap

Should "netmap" be added there ?

> > diff --git a/monitor.c b/monitor.c
> > index 6a3a5c9..365c66a 100644
> > --- a/monitor.c
> > +++ b/monitor.c
> > @@ -4593,6 +4593,20 @@ void migrate_set_capability_completion(ReadLineState 
> > *rs, int nb_args,
> >  }
> >  }
> >  
> > +void host_net_add_completion(ReadLineState *rs, int nb_args, const char 
> > *str)
> > +{
> > +if (nb_args != 2) {
> > +return;
> > +}
> > +readline_set_completion_index(rs, strlen(str));
> > +add_completion_option(rs, str, "tap");
> > +add_completion_option(rs, str, "user");
> > +add_completion_option(rs, str, "socket");
> > +add_completion_option(rs, str, "vde");
> > +add_completion_option(rs, str, "dump");
> > +add_completion_option(rs, str, "bridge");
> 
> Please take a look at net_host_check_device() and share the list from
> there.  (Some of the netdevs depend on build-time options.)

Ok, will add a patch to share the valid_params_list[] in include/net/net.h.



[Qemu-devel] nbd: Add exports listing support

2014-05-25 Thread Hani Benhabiles
Before the patches:

$ nbd-client -l localhost
Negotiation: ..
E: Server does not support listing exports

After the patches:
$ nbd-client -l localhost
Negotiation: ..
ide0-hd0
ide1-cd0

Hani Benhabiles (2):
  nbd: Handle fixed new-style clients.
  nbd: Handle NBD_OPT_LIST option.

 include/block/nbd.h |  10 +
 nbd.c   | 109 
 2 files changed, 112 insertions(+), 7 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [PATCH 2/2] nbd: Handle NBD_OPT_LIST option.

2014-05-25 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 include/block/nbd.h |  4 +++
 nbd.c   | 97 +++--
 2 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 95d52ab..23e9a84 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -51,6 +51,10 @@ struct nbd_reply {
 /* New-style client flags. */
 #define NBD_FLAG_C_FIXED_NEWSTYLE   (1 << 0)/* Fixed newstyle protocol. */
 
+/* Reply types. */
+#define NBD_REP_ACK (1) /* Data sending finished. */
+#define NBD_REP_SERVER  (2) /* Export description. */
+
 #define NBD_CMD_MASK_COMMAND   0x
 #define NBD_CMD_FLAG_FUA   (1 << 16)
 
diff --git a/nbd.c b/nbd.c
index fb0a9cf..9150fa6 100644
--- a/nbd.c
+++ b/nbd.c
@@ -64,6 +64,7 @@
 #define NBD_REPLY_MAGIC 0x67446698
 #define NBD_OPTS_MAGIC  0x49484156454F5054LL
 #define NBD_CLIENT_MAGIC0x420281861253LL
+#define NBD_REP_MAGIC   0x3e889045565a9LL
 
 #define NBD_SET_SOCK_IO(0xab, 0)
 #define NBD_SET_BLKSIZE _IO(0xab, 1)
@@ -77,7 +78,8 @@
 #define NBD_SET_TIMEOUT _IO(0xab, 9)
 #define NBD_SET_FLAGS   _IO(0xab, 10)
 
-#define NBD_OPT_EXPORT_NAME (1 << 0)
+#define NBD_OPT_EXPORT_NAME (1)
+#define NBD_OPT_LIST(3)
 
 /* Definitions for opaque data types */
 
@@ -215,6 +217,88 @@ static ssize_t write_sync(int fd, void *buffer, size_t 
size)
 
 */
 
+static int nbd_send_rep_ack(int csock)
+{
+uint64_t magic;
+uint32_t opt, type, len;
+
+magic = cpu_to_be64(NBD_REP_MAGIC);
+if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+LOG("write failed (rep magic)");
+return -EINVAL;
+}
+opt = cpu_to_be32(NBD_OPT_LIST);
+if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
+LOG("write failed (opt list)");
+return -EINVAL;
+}
+type = cpu_to_be32(NBD_REP_ACK);
+if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
+LOG("write failed (rep ack)");
+return -EINVAL;
+}
+len = cpu_to_be32(0);
+if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
+LOG("write failed (rep data length)");
+return -EINVAL;
+}
+return 0;
+}
+
+static int nbd_send_rep_list(int csock, NBDExport *exp)
+{
+uint64_t magic, name_len;
+uint32_t opt, type, len;
+
+name_len = strlen(exp->name);
+magic = cpu_to_be64(NBD_REP_MAGIC);
+if (write_sync(csock, &magic, sizeof(magic)) != sizeof(magic)) {
+LOG("write failed (magic)");
+return -EINVAL;
+}
+opt = cpu_to_be32(NBD_OPT_LIST);
+if (write_sync(csock, &opt, sizeof(opt)) != sizeof(opt)) {
+LOG("write failed (opt)");
+return -EINVAL;
+}
+type = cpu_to_be32(NBD_REP_SERVER);
+if (write_sync(csock, &type, sizeof(type)) != sizeof(type)) {
+LOG("write failed (reply type)");
+return -EINVAL;
+}
+len = cpu_to_be32(name_len + sizeof(len));
+if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
+LOG("write failed (length)");
+return -EINVAL;
+}
+len = cpu_to_be32(name_len);
+if (write_sync(csock, &len, sizeof(len)) != sizeof(len)) {
+LOG("write failed (length)");
+return -EINVAL;
+}
+if (write_sync(csock, exp->name, name_len) != name_len) {
+LOG("write failed (buffer)");
+return -EINVAL;
+}
+return 0;
+}
+
+static int nbd_send_list(NBDClient *client)
+{
+int csock;
+NBDExport *exp;
+
+csock = client->sock;
+/* For each export, send a NBD_REP_SERVER reply. */
+QTAILQ_FOREACH(exp, &exports, next) {
+if (nbd_send_rep_list(csock, exp)) {
+return -EINVAL;
+}
+}
+/* Finish with a NBD_REP_ACK. */
+return nbd_send_rep_ack(csock);
+}
+
 static int nbd_receive_options(NBDClient *client)
 {
 int csock = client->sock;
@@ -258,6 +342,13 @@ static int nbd_receive_options(NBDClient *client)
 goto fail;
 }
 TRACE("Checking option");
+if (tmp == be32_to_cpu(NBD_OPT_LIST)) {
+if (nbd_send_list(client) < 0) {
+return -EINVAL;
+} else {
+return 1;
+}
+}
 if (tmp != be32_to_cpu(NBD_OPT_EXPORT_NAME)) {
 LOG("Bad option received");
 goto fail;
@@ -351,6 +442,8 @@ static int nbd_send_negotiate(NBDClient *client)
 if (rc < 0) {
 LOG("option negotiation failed");
 goto fail;
+} else if (rc > 0) {
+goto fail;
 }
 
 assert ((client->exp->nbdflags & ~65535) == 0);
@@ -1175,7 +1268,7 @@ NBDClient *nbd_client_new(NBDExport *ex

[Qemu-devel] [PATCH 1/2] nbd: Handle fixed new-style clients.

2014-05-25 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 include/block/nbd.h |  6 ++
 nbd.c   | 12 +++-
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/block/nbd.h b/include/block/nbd.h
index 79502a0..95d52ab 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -45,6 +45,12 @@ struct nbd_reply {
 #define NBD_FLAG_ROTATIONAL (1 << 4)/* Use elevator algorithm - 
rotational media */
 #define NBD_FLAG_SEND_TRIM  (1 << 5)/* Send TRIM (discard) */
 
+/* New-style global flags. */
+#define NBD_FLAG_FIXED_NEWSTYLE (1 << 0)/* Fixed newstyle protocol. */
+
+/* New-style client flags. */
+#define NBD_FLAG_C_FIXED_NEWSTYLE   (1 << 0)/* Fixed newstyle protocol. */
+
 #define NBD_CMD_MASK_COMMAND   0x
 #define NBD_CMD_FLAG_FUA   (1 << 16)
 
diff --git a/nbd.c b/nbd.c
index e5084b6..fb0a9cf 100644
--- a/nbd.c
+++ b/nbd.c
@@ -224,7 +224,7 @@ static int nbd_receive_options(NBDClient *client)
 int rc;
 
 /* Client sends:
-[ 0 ..   3]   reserved (0)
+[ 0 ..   3]   client flags
 [ 4 ..  11]   NBD_OPTS_MAGIC
 [12 ..  15]   NBD_OPT_EXPORT_NAME
 [16 ..  19]   length
@@ -236,9 +236,10 @@ static int nbd_receive_options(NBDClient *client)
 LOG("read failed");
 goto fail;
 }
-TRACE("Checking reserved");
-if (tmp != 0) {
-LOG("Bad reserved received");
+TRACE("Checking client flags");
+tmp = be32_to_cpu(tmp);
+if (tmp != 0 && tmp != NBD_FLAG_C_FIXED_NEWSTYLE) {
+LOG("Bad client flags received");
 goto fail;
 }
 
@@ -246,7 +247,7 @@ static int nbd_receive_options(NBDClient *client)
 LOG("read failed");
 goto fail;
 }
-TRACE("Checking reserved");
+TRACE("Checking opts magic");
 if (magic != be64_to_cpu(NBD_OPTS_MAGIC)) {
 LOG("Bad magic received");
 goto fail;
@@ -333,6 +334,7 @@ static int nbd_send_negotiate(NBDClient *client)
 cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);
 } else {
 cpu_to_be64w((uint64_t*)(buf + 8), NBD_OPTS_MAGIC);
+cpu_to_be16w((uint16_t *)(buf + 16), NBD_FLAG_FIXED_NEWSTYLE);
 }
 
 if (client->exp) {
-- 
1.8.3.2




[Qemu-devel] [PATCH 6/7] monitor: Add host_net_remove arguments completion.

2014-05-19 Thread Hani Benhabiles
Relies on readline unique completion strings patch to make the added vlan/hub
completion values unique, instead of using something like a hash table.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  2 ++
 monitor.c   | 38 ++
 3 files changed, 41 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 6aaec1b..935f744 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1227,6 +1227,7 @@ ETEXI
 .params = "vlan_id name",
 .help   = "remove host VLAN client",
 .mhandler.cmd = net_host_device_remove,
+.command_completion = host_net_remove_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 22ee836..a53ad51 100644
--- a/hmp.h
+++ b/hmp.h
@@ -110,5 +110,7 @@ void watchdog_action_completion(ReadLineState *rs, int 
nb_args,
 void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
const char *str);
 void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void host_net_remove_completion(ReadLineState *rs, int nb_args,
+const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 365c66a..805d29f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4607,6 +4607,44 @@ void host_net_add_completion(ReadLineState *rs, int 
nb_args, const char *str)
 add_completion_option(rs, str, "bridge");
 }
 
+void host_net_remove_completion(ReadLineState *rs, int nb_args, const char 
*str)
+{
+NetClientState *ncs[255];
+int count, i, len;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+if (nb_args == 2) {
+count = qemu_find_net_clients_except(NULL, ncs,
+ NET_CLIENT_OPTIONS_KIND_NONE, 
255);
+for (i = 0; i < count; i++) {
+int id;
+char name[16];
+
+if (net_hub_id_for_client(ncs[i], &id)) {
+continue;
+}
+snprintf(name, sizeof(name), "%d", id);
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+return;
+} else if (nb_args == 3) {
+count = qemu_find_net_clients_except(NULL, ncs,
+ NET_CLIENT_OPTIONS_KIND_NIC, 255);
+for (i = 0; i < count; i++) {
+const char *name;
+
+name = ncs[i]->name;
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+return;
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] monitor: Command completion for various commands

2014-05-19 Thread Hani Benhabiles
A set of patches adding completion support for various hmp commands. Following
other series that were merged earlier.

Hani Benhabiles (7):
  monitor: Add ringbuf_write and ringbuf_read argument completion.
  monitor: Add watchdog_action argument completion.
  monitor: Add migrate_set_capability completion.
  monitor: Add host_net_add device argument completion.
  readline: Make completion strings always unique.
  monitor: Add host_net_remove arguments completion.
  monitor: Add delvm and loadvm argument completion.

 hmp-commands.hx   |  10 ++-
 hmp.h |  11 
 include/sysemu/char.h |   3 +-
 monitor.c | 174 ++
 qemu-char.c   |   2 +-
 util/readline.c   |   6 ++
 6 files changed, 202 insertions(+), 4 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [PATCH 2/7] monitor: Add watchdog_action argument completion.

2014-05-19 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  2 ++
 monitor.c   | 14 ++
 3 files changed, 17 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index dcec5ef..45e1763 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1359,6 +1359,7 @@ ETEXI
 .params = "[reset|shutdown|poweroff|pause|debug|none]",
 .help   = "change watchdog action",
 .mhandler.cmd = do_watchdog_action,
+.command_completion = watchdog_action_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 212e5d2..a70804d 100644
--- a/hmp.h
+++ b/hmp.h
@@ -105,5 +105,7 @@ void netdev_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
 void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
+void watchdog_action_completion(ReadLineState *rs, int nb_args,
+const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 93eb6d8..fb300c2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4558,6 +4558,20 @@ void netdev_del_completion(ReadLineState *rs, int 
nb_args, const char *str)
 }
 }
 
+void watchdog_action_completion(ReadLineState *rs, int nb_args, const char 
*str)
+{
+if (nb_args != 2) {
+return;
+}
+readline_set_completion_index(rs, strlen(str));
+add_completion_option(rs, str, "reset");
+add_completion_option(rs, str, "shutdown");
+add_completion_option(rs, str, "poweroff");
+add_completion_option(rs, str, "pause");
+add_completion_option(rs, str, "debug");
+add_completion_option(rs, str, "none");
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCH 1/7] monitor: Add ringbuf_write and ringbuf_read argument completion.

2014-05-19 Thread Hani Benhabiles
Export chr_is_ringbuf() function. Also remove left-over function prototypes
while at it.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx   |  2 ++
 hmp.h |  2 ++
 include/sysemu/char.h |  3 +--
 monitor.c | 39 +++
 qemu-char.c   |  2 +-
 5 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 2e462c0..dcec5ef 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -852,6 +852,7 @@ ETEXI
 .params = "device data",
 .help   = "Write to a ring buffer character device",
 .mhandler.cmd = hmp_ringbuf_write,
+.command_completion = ringbuf_write_completion,
 },
 
 STEXI
@@ -868,6 +869,7 @@ ETEXI
 .params = "device size",
 .help   = "Read from a ring buffer character device",
 .mhandler.cmd = hmp_ringbuf_read,
+.command_completion = ringbuf_write_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index aba59e9..212e5d2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -103,5 +103,7 @@ void chardev_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
+void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index b81a6ff..7f5eeb3 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -286,9 +286,8 @@ void qemu_chr_add_handlers(CharDriverState *s,
 void qemu_chr_be_generic_open(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
 int qemu_chr_add_client(CharDriverState *s, int fd);
-void qemu_chr_info_print(Monitor *mon, const QObject *ret_data);
-void qemu_chr_info(Monitor *mon, QObject **ret_data);
 CharDriverState *qemu_chr_find(const char *name);
+bool chr_is_ringbuf(const CharDriverState *chr);
 
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 
diff --git a/monitor.c b/monitor.c
index 593679a..93eb6d8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4411,6 +4411,45 @@ void chardev_remove_completion(ReadLineState *rs, int 
nb_args, const char *str)
 qapi_free_ChardevInfoList(start);
 }
 
+static void ringbuf_completion(ReadLineState *rs, const char *str)
+{
+size_t len;
+ChardevInfoList *list, *start;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+
+start = list = qmp_query_chardev(NULL);
+while (list) {
+ChardevInfo *chr_info = list->value;
+
+if (!strncmp(chr_info->label, str, len)) {
+CharDriverState *chr = qemu_chr_find(chr_info->label);
+if (chr && chr_is_ringbuf(chr)) {
+readline_add_completion(rs, chr_info->label);
+}
+}
+list = list->next;
+}
+qapi_free_ChardevInfoList(start);
+}
+
+void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args != 2) {
+return;
+}
+ringbuf_completion(rs, str);
+}
+
+void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args != 2) {
+return;
+}
+ringbuf_completion(rs, str);
+}
+
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 size_t len;
diff --git a/qemu-char.c b/qemu-char.c
index 54ed244..34c8f08 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2849,7 +2849,7 @@ fail:
 return NULL;
 }
 
-static bool chr_is_ringbuf(const CharDriverState *chr)
+bool chr_is_ringbuf(const CharDriverState *chr)
 {
 return chr->chr_write == ringbuf_chr_write;
 }
-- 
1.8.3.2




[Qemu-devel] [PATCH 7/7] monitor: Add delvm and loadvm argument completion.

2014-05-19 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  2 ++
 hmp.h   |  2 ++
 monitor.c   | 48 
 3 files changed, 52 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 935f744..d68a00b 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -335,6 +335,7 @@ ETEXI
 .params = "tag|id",
 .help   = "restore a VM snapshot from its tag or id",
 .mhandler.cmd = do_loadvm,
+.command_completion = loadvm_completion,
 },
 
 STEXI
@@ -350,6 +351,7 @@ ETEXI
 .params = "tag|id",
 .help   = "delete a VM snapshot from its tag or id",
 .mhandler.cmd = do_delvm,
+.command_completion = delvm_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index a53ad51..2d9b0a2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -112,5 +112,7 @@ void migrate_set_capability_completion(ReadLineState *rs, 
int nb_args,
 void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void host_net_remove_completion(ReadLineState *rs, int nb_args,
 const char *str);
+void delvm_completion(ReadLineState *rs, int nb_args, const char *str);
+void loadvm_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 805d29f..b6ac4e0 100644
--- a/monitor.c
+++ b/monitor.c
@@ -69,6 +69,7 @@
 #include "qmp-commands.h"
 #include "hmp.h"
 #include "qemu/thread.h"
+#include "block/qapi.h"
 
 /* for pic/irq_info */
 #if defined(TARGET_SPARC)
@@ -4645,6 +4646,53 @@ void host_net_remove_completion(ReadLineState *rs, int 
nb_args, const char *str)
 }
 }
 
+static void vm_completion(ReadLineState *rs, const char *str)
+{
+size_t len;
+BlockDriverState *bs = NULL;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+while ((bs = bdrv_next(bs))) {
+SnapshotInfoList *snapshots, *snapshot;
+
+if (!bdrv_can_snapshot(bs)) {
+continue;
+}
+if (bdrv_query_snapshot_info_list(bs, &snapshots, NULL)) {
+continue;
+}
+snapshot = snapshots;
+while (snapshot) {
+char *completion = snapshot->value->name;
+if (!strncmp(str, completion, len)) {
+readline_add_completion(rs, completion);
+}
+completion = snapshot->value->id;
+if (!strncmp(str, completion, len)) {
+readline_add_completion(rs, completion);
+}
+snapshot = snapshot->next;
+}
+qapi_free_SnapshotInfoList(snapshots);
+}
+
+}
+
+void delvm_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args == 2) {
+vm_completion(rs, str);
+}
+}
+
+void loadvm_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args == 2) {
+vm_completion(rs, str);
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




Re: [Qemu-devel] monitor: Command completion for various commands

2014-05-19 Thread Hani Benhabiles
On Tue, May 20, 2014 at 12:01:01AM +0100, Hani Benhabiles wrote:
> A set of patches adding completion support for various hmp commands. Following
> other series that were merged earlier.
> 

Resent the complete series. Please ignore this incomplete one.

Sorry for the flood.

> Hani Benhabiles (7):
>   monitor: Add ringbuf_write and ringbuf_read argument completion.
>   monitor: Add watchdog_action argument completion.
>   monitor: Add migrate_set_capability completion.
>   monitor: Add host_net_add device argument completion.
>   readline: Make completion strings always unique.
>   monitor: Add host_net_remove arguments completion.
>   monitor: Add delvm and loadvm argument completion.
> 
>  hmp-commands.hx   |  10 ++-
>  hmp.h |  11 
>  include/sysemu/char.h |   3 +-
>  monitor.c | 174 
> ++
>  qemu-char.c   |   2 +-
>  util/readline.c   |   6 ++
>  6 files changed, 202 insertions(+), 4 deletions(-)
> 
> -- 
> 1.8.3.2
> 



[Qemu-devel] [PATCH 3/7] monitor: Add migrate_set_capability completion.

2014-05-19 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  2 ++
 monitor.c   | 21 +
 3 files changed, 24 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 45e1763..919af6e 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -975,6 +975,7 @@ ETEXI
 .params = "capability state",
 .help   = "Enable/Disable the usage of a capability for migration",
 .mhandler.cmd = hmp_migrate_set_capability,
+.command_completion = migrate_set_capability_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index a70804d..0c814d0 100644
--- a/hmp.h
+++ b/hmp.h
@@ -107,5 +107,7 @@ void ringbuf_write_completion(ReadLineState *rs, int 
nb_args, const char *str);
 void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
 void watchdog_action_completion(ReadLineState *rs, int nb_args,
 const char *str);
+void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
+   const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index fb300c2..6a3a5c9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4572,6 +4572,27 @@ void watchdog_action_completion(ReadLineState *rs, int 
nb_args, const char *str)
 add_completion_option(rs, str, "none");
 }
 
+void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
+   const char *str)
+{
+size_t len;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+if (nb_args == 2) {
+int i;
+for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+const char *name = MigrationCapability_lookup[i];
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+} else if (nb_args == 3) {
+add_completion_option(rs, str, "on");
+add_completion_option(rs, str, "off");
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCH 4/7] monitor: Add host_net_add device argument completion.

2014-05-19 Thread Hani Benhabiles
Also fix the parameters documentation.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  3 ++-
 hmp.h   |  1 +
 monitor.c   | 14 ++
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 919af6e..6aaec1b 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1209,9 +1209,10 @@ ETEXI
 {
 .name   = "host_net_add",
 .args_type  = "device:s,opts:s?",
-.params = "tap|user|socket|vde|netmap|dump [options]",
+.params = "tap|user|socket|vde|bridge|dump [options]",
 .help   = "add host VLAN client",
 .mhandler.cmd = net_host_device_add,
+.command_completion = host_net_add_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 0c814d0..22ee836 100644
--- a/hmp.h
+++ b/hmp.h
@@ -109,5 +109,6 @@ void watchdog_action_completion(ReadLineState *rs, int 
nb_args,
 const char *str);
 void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
const char *str);
+void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 6a3a5c9..365c66a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4593,6 +4593,20 @@ void migrate_set_capability_completion(ReadLineState 
*rs, int nb_args,
 }
 }
 
+void host_net_add_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args != 2) {
+return;
+}
+readline_set_completion_index(rs, strlen(str));
+add_completion_option(rs, str, "tap");
+add_completion_option(rs, str, "user");
+add_completion_option(rs, str, "socket");
+add_completion_option(rs, str, "vde");
+add_completion_option(rs, str, "dump");
+add_completion_option(rs, str, "bridge");
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCH 5/7] readline: Make completion strings always unique.

2014-05-19 Thread Hani Benhabiles
There is no need to clutter the user's choices with repeating the same value
multiple times.

Signed-off-by: Hani Benhabiles 
---
 util/readline.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/util/readline.c b/util/readline.c
index 8baec55..7214e84 100644
--- a/util/readline.c
+++ b/util/readline.c
@@ -263,6 +263,12 @@ static void readline_hist_add(ReadLineState *rs, const 
char *cmdline)
 void readline_add_completion(ReadLineState *rs, const char *str)
 {
 if (rs->nb_completions < READLINE_MAX_COMPLETIONS) {
+int i;
+for (i = 0; i < rs->nb_completions; i++) {
+if (!strcmp(rs->completions[i], str)) {
+return;
+}
+}
 rs->completions[rs->nb_completions++] = g_strdup(str);
 }
 }
-- 
1.8.3.2




[Qemu-devel] monitor: Command completion for various commands

2014-05-19 Thread Hani Benhabiles
A set of patches adding completion support for various hmp commands. Following
other series that were merged earlier.

Hani Benhabiles (7):
  monitor: Add ringbuf_write and ringbuf_read argument completion.
  monitor: Add watchdog_action argument completion.
  monitor: Add migrate_set_capability completion.
  monitor: Add host_net_add device argument completion.
  readline: Make completion strings always unique.
  monitor: Add host_net_remove arguments completion.
  monitor: Add delvm and loadvm argument completion.

 hmp-commands.hx   |  10 ++-
 hmp.h |  11 
 include/sysemu/char.h |   3 +-
 monitor.c | 174 ++
 qemu-char.c   |   2 +-
 util/readline.c   |   6 ++
 6 files changed, 202 insertions(+), 4 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [PATCH 3/7] monitor: Add migrate_set_capability completion.

2014-05-19 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  2 ++
 monitor.c   | 21 +
 3 files changed, 24 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 45e1763..919af6e 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -975,6 +975,7 @@ ETEXI
 .params = "capability state",
 .help   = "Enable/Disable the usage of a capability for migration",
 .mhandler.cmd = hmp_migrate_set_capability,
+.command_completion = migrate_set_capability_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index a70804d..0c814d0 100644
--- a/hmp.h
+++ b/hmp.h
@@ -107,5 +107,7 @@ void ringbuf_write_completion(ReadLineState *rs, int 
nb_args, const char *str);
 void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
 void watchdog_action_completion(ReadLineState *rs, int nb_args,
 const char *str);
+void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
+   const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index fb300c2..6a3a5c9 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4572,6 +4572,27 @@ void watchdog_action_completion(ReadLineState *rs, int 
nb_args, const char *str)
 add_completion_option(rs, str, "none");
 }
 
+void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
+   const char *str)
+{
+size_t len;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+if (nb_args == 2) {
+int i;
+for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+const char *name = MigrationCapability_lookup[i];
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+} else if (nb_args == 3) {
+add_completion_option(rs, str, "on");
+add_completion_option(rs, str, "off");
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCH 1/7] monitor: Add ringbuf_write and ringbuf_read argument completion.

2014-05-19 Thread Hani Benhabiles
Export chr_is_ringbuf() function. Also remove left-over function prototypes
while at it.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx   |  2 ++
 hmp.h |  2 ++
 include/sysemu/char.h |  3 +--
 monitor.c | 39 +++
 qemu-char.c   |  2 +-
 5 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 2e462c0..dcec5ef 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -852,6 +852,7 @@ ETEXI
 .params = "device data",
 .help   = "Write to a ring buffer character device",
 .mhandler.cmd = hmp_ringbuf_write,
+.command_completion = ringbuf_write_completion,
 },
 
 STEXI
@@ -868,6 +869,7 @@ ETEXI
 .params = "device size",
 .help   = "Read from a ring buffer character device",
 .mhandler.cmd = hmp_ringbuf_read,
+.command_completion = ringbuf_write_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index aba59e9..212e5d2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -103,5 +103,7 @@ void chardev_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
+void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index b81a6ff..7f5eeb3 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -286,9 +286,8 @@ void qemu_chr_add_handlers(CharDriverState *s,
 void qemu_chr_be_generic_open(CharDriverState *s);
 void qemu_chr_accept_input(CharDriverState *s);
 int qemu_chr_add_client(CharDriverState *s, int fd);
-void qemu_chr_info_print(Monitor *mon, const QObject *ret_data);
-void qemu_chr_info(Monitor *mon, QObject **ret_data);
 CharDriverState *qemu_chr_find(const char *name);
+bool chr_is_ringbuf(const CharDriverState *chr);
 
 QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename);
 
diff --git a/monitor.c b/monitor.c
index 593679a..93eb6d8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4411,6 +4411,45 @@ void chardev_remove_completion(ReadLineState *rs, int 
nb_args, const char *str)
 qapi_free_ChardevInfoList(start);
 }
 
+static void ringbuf_completion(ReadLineState *rs, const char *str)
+{
+size_t len;
+ChardevInfoList *list, *start;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+
+start = list = qmp_query_chardev(NULL);
+while (list) {
+ChardevInfo *chr_info = list->value;
+
+if (!strncmp(chr_info->label, str, len)) {
+CharDriverState *chr = qemu_chr_find(chr_info->label);
+if (chr && chr_is_ringbuf(chr)) {
+readline_add_completion(rs, chr_info->label);
+}
+}
+list = list->next;
+}
+qapi_free_ChardevInfoList(start);
+}
+
+void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args != 2) {
+return;
+}
+ringbuf_completion(rs, str);
+}
+
+void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+if (nb_args != 2) {
+return;
+}
+ringbuf_completion(rs, str);
+}
+
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 size_t len;
diff --git a/qemu-char.c b/qemu-char.c
index 54ed244..34c8f08 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2849,7 +2849,7 @@ fail:
 return NULL;
 }
 
-static bool chr_is_ringbuf(const CharDriverState *chr)
+bool chr_is_ringbuf(const CharDriverState *chr)
 {
 return chr->chr_write == ringbuf_chr_write;
 }
-- 
1.8.3.2




[Qemu-devel] [PATCH 2/7] monitor: Add watchdog_action argument completion.

2014-05-19 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  2 ++
 monitor.c   | 14 ++
 3 files changed, 17 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index dcec5ef..45e1763 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1359,6 +1359,7 @@ ETEXI
 .params = "[reset|shutdown|poweroff|pause|debug|none]",
 .help   = "change watchdog action",
 .mhandler.cmd = do_watchdog_action,
+.command_completion = watchdog_action_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 212e5d2..a70804d 100644
--- a/hmp.h
+++ b/hmp.h
@@ -105,5 +105,7 @@ void netdev_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void ringbuf_write_completion(ReadLineState *rs, int nb_args, const char *str);
 void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
+void watchdog_action_completion(ReadLineState *rs, int nb_args,
+const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 93eb6d8..fb300c2 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4558,6 +4558,20 @@ void netdev_del_completion(ReadLineState *rs, int 
nb_args, const char *str)
 }
 }
 
+void watchdog_action_completion(ReadLineState *rs, int nb_args, const char 
*str)
+{
+if (nb_args != 2) {
+return;
+}
+readline_set_completion_index(rs, strlen(str));
+add_completion_option(rs, str, "reset");
+add_completion_option(rs, str, "shutdown");
+add_completion_option(rs, str, "poweroff");
+add_completion_option(rs, str, "pause");
+add_completion_option(rs, str, "debug");
+add_completion_option(rs, str, "none");
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH 2/2] nbd: Don't validate from and len in NBD_CMD_DISC.

2014-05-19 Thread Hani Benhabiles
On Mon, May 19, 2014 at 01:05:12PM +0200, Paolo Bonzini wrote:
> Il 18/05/2014 12:50, Hani Benhabiles ha scritto:
> >These values aren't used in this case.
> >
> >Currently, the from field in the request sent by the nbd kernel module 
> >leading
> >to a false error message when ending the connection with the client.
> >
> >$ qemu-nbd some.img -v
> >// After nbd-client -d /dev/nbd0
> >nbd.c:nbd_trip():L1031: From: 18446744073709551104, Len: 0, Size: 20971520,
> >Offset: 0
> >nbd.c:nbd_trip():L1032: requested operation past EOF--bad client?
> >nbd.c:nbd_receive_request():L638: read failed
> >
> >Signed-off-by: Hani Benhabiles 
> >---
> > nbd.c | 7 ---
> > 1 file changed, 4 insertions(+), 3 deletions(-)
> >
> >diff --git a/nbd.c b/nbd.c
> >index e5084b6..dc076d7 100644
> >--- a/nbd.c
> >+++ b/nbd.c
> >@@ -1001,6 +1001,7 @@ static void nbd_trip(void *opaque)
> > struct nbd_request request;
> > struct nbd_reply reply;
> > ssize_t ret;
> >+uint32_t type;
> >
> > TRACE("Reading request.");
> > if (client->closing) {
> >@@ -1023,8 +1024,8 @@ static void nbd_trip(void *opaque)
> > reply.error = -ret;
> > goto error_reply;
> > }
> >-
> >-if ((request.from + request.len) > exp->size) {
> >+type = request.type & NBD_CMD_MASK_COMMAND;
> >+if (type != NBD_CMD_DISC && (request.from + request.len) > exp->size) {
> > LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
> > ", Offset: %" PRIu64 "\n",
> > request.from, request.len,
> >@@ -1033,7 +1034,7 @@ static void nbd_trip(void *opaque)
> > goto invalid_request;
> > }
> >
> >-switch (request.type & NBD_CMD_MASK_COMMAND) {
> >+switch (type) {
> > case NBD_CMD_READ:
> > TRACE("Request type is READ");
> >
> >
> 
> Applied after renaming the variable from type to command (for consistency
> with e.g. nbd_co_receive_request).

No issue. Thanks!



[Qemu-devel] [PATCH 2/2] nbd: Don't validate from and len in NBD_CMD_DISC.

2014-05-18 Thread Hani Benhabiles
These values aren't used in this case.

Currently, the from field in the request sent by the nbd kernel module leading
to a false error message when ending the connection with the client.

$ qemu-nbd some.img -v
// After nbd-client -d /dev/nbd0
nbd.c:nbd_trip():L1031: From: 18446744073709551104, Len: 0, Size: 20971520,
Offset: 0
nbd.c:nbd_trip():L1032: requested operation past EOF--bad client?
nbd.c:nbd_receive_request():L638: read failed

Signed-off-by: Hani Benhabiles 
---
 nbd.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/nbd.c b/nbd.c
index e5084b6..dc076d7 100644
--- a/nbd.c
+++ b/nbd.c
@@ -1001,6 +1001,7 @@ static void nbd_trip(void *opaque)
 struct nbd_request request;
 struct nbd_reply reply;
 ssize_t ret;
+uint32_t type;
 
 TRACE("Reading request.");
 if (client->closing) {
@@ -1023,8 +1024,8 @@ static void nbd_trip(void *opaque)
 reply.error = -ret;
 goto error_reply;
 }
-
-if ((request.from + request.len) > exp->size) {
+type = request.type & NBD_CMD_MASK_COMMAND;
+if (type != NBD_CMD_DISC && (request.from + request.len) > exp->size) {
 LOG("From: %" PRIu64 ", Len: %u, Size: %" PRIu64
 ", Offset: %" PRIu64 "\n",
 request.from, request.len,
@@ -1033,7 +1034,7 @@ static void nbd_trip(void *opaque)
 goto invalid_request;
 }
 
-switch (request.type & NBD_CMD_MASK_COMMAND) {
+switch (type) {
 case NBD_CMD_READ:
 TRACE("Request type is READ");
 
-- 
1.8.3.2




[Qemu-devel] [PATCH 1/2] nbd: Don't export a block device with no medium.

2014-05-18 Thread Hani Benhabiles
The device is exported with erroneous values and can't be read.

Before the patch:
$ sudo nbd-client localhost -p 10809 /dev/nbd0 -name floppy0
Negotiation: ..size = 17592186044415MB
bs=1024, sz=18446744073709547520 bytes

$ sudo mount /dev/nbd0 /mnt/tmp/
mount: block device /dev/nbd0 is write-protected, mounting read-only
mount: /dev/nbd0: can't read superblock

After the patch:
(qemu) nbd_server_add ide0-hd0
(qemu) nbd_server_add floppy0
Device 'floppy0' has no medium

Signed-off-by: Hani Benhabiles 
---
 blockdev-nbd.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 922cf56..a700d52 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -91,6 +91,10 @@ void qmp_nbd_server_add(const char *device, bool 
has_writable, bool writable,
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
+if (!bdrv_is_inserted(bs)) {
+error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+return;
+}
 
 if (!has_writable) {
 writable = false;
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH 0/6] Miscellaneous command completion patches

2014-05-15 Thread Hani Benhabiles
On Thu, May 15, 2014 at 04:10:11PM -0400, Luiz Capitulino wrote:
> On Thu, 15 May 2014 20:42:03 +0100
> Hani Benhabiles  wrote:
> 
> > On Wed, May 07, 2014 at 11:41:26PM +0100, Hani Benhabiles wrote:
> > > Compared to v1:
> > > * Dropped patch 02/07 for help completion conversion.
> > > * Nothing else changed. 04,05 and 06 are R-b by Stefan.
> > > 
> > > Hani Benhabiles (6):
> > >   monitor: Convert sendkey to use command_completion.
> > >   monitor: Add chardev-remove command completion.
> > >   monitor: Add chardev-add backend argument completion.
> > >   monitor: Add set_link arguments completion.
> > >   monitor: Add netdev_add type argument completion.
> > >   monitor: Add netdev_del id argument completion.
> > > 
> > 
> > Ping.
> > 
> > Luiz, is there anything still holding this series ? All 6 patches are
> > Reviewed/Acked.
> 
> I applied them a little more than one hour ago.

Thanks, just noticed it.



Re: [Qemu-devel] [PATCH 0/6] Miscellaneous command completion patches

2014-05-15 Thread Hani Benhabiles
On Wed, May 07, 2014 at 11:41:26PM +0100, Hani Benhabiles wrote:
> Compared to v1:
> * Dropped patch 02/07 for help completion conversion.
> * Nothing else changed. 04,05 and 06 are R-b by Stefan.
> 
> Hani Benhabiles (6):
>   monitor: Convert sendkey to use command_completion.
>   monitor: Add chardev-remove command completion.
>   monitor: Add chardev-add backend argument completion.
>   monitor: Add set_link arguments completion.
>   monitor: Add netdev_add type argument completion.
>   monitor: Add netdev_del id argument completion.
> 

Ping.

Luiz, is there anything still holding this series ? All 6 patches are
Reviewed/Acked.


>  hmp-commands.hx |   8 ++-
>  hmp.h   |   6 +++
>  monitor.c   | 153 
> 
>  net/net.c   |   2 +-
>  4 files changed, 158 insertions(+), 11 deletions(-)
> 
> -- 
> 1.8.3.2
> 



[Qemu-devel] [PATCH 1/2] nbd: Close socket on negotiation failure.

2014-05-12 Thread Hani Benhabiles
Otherwise, the nbd client may hang waiting for the server response.

Signed-off-by: Hani Benhabiles 
---

Quick method to trigger such behaviour:

(qemu) nbd_server_start localhost:10809
(qemu) nbd_server_add sd0
$ nbd-client localhost 10809 -name  /dev/nbd0
Negotiation: ..

(Client will hang indefinitely.)

 blockdev-nbd.c | 4 ++--
 qemu-nbd.c | 4 +++-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 922cf56..b60b66d 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -27,8 +27,8 @@ static void nbd_accept(void *opaque)
 socklen_t addr_len = sizeof(addr);
 
 int fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len);
-if (fd >= 0) {
-nbd_client_new(NULL, fd, nbd_client_put);
+if (fd >= 0 && !nbd_client_new(NULL, fd, nbd_client_put)) {
+close(fd);
 }
 }
 
diff --git a/qemu-nbd.c b/qemu-nbd.c
index eed79fa..f70e4b0 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -369,8 +369,10 @@ static void nbd_accept(void *opaque)
 return;
 }
 
-if (fd >= 0 && nbd_client_new(exp, fd, nbd_client_closed)) {
+if (nbd_client_new(exp, fd, nbd_client_closed)) {
 nb_fds++;
+} else {
+close(fd);
 }
 }
 
-- 
1.8.3.2




[Qemu-devel] [PATCH 2/2] nbd: Miscellaneous typo fixes.

2014-05-12 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 nbd.c | 2 +-
 qemu-nbd.c| 2 +-
 qemu-nbd.texi | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/nbd.c b/nbd.c
index e5084b6..e0d032c 100644
--- a/nbd.c
+++ b/nbd.c
@@ -306,7 +306,7 @@ static int nbd_send_negotiate(NBDClient *client)
 [ 8 ..  15]   magic(NBD_CLIENT_MAGIC)
 [16 ..  23]   size
 [24 ..  25]   server flags (0)
-[24 ..  27]   export flags
+[26 ..  27]   export flags
 [28 .. 151]   reserved (0)
 
Negotiation header with options, part 1:
diff --git a/qemu-nbd.c b/qemu-nbd.c
index f70e4b0..cd6bd50 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -294,7 +294,7 @@ static void *nbd_client_thread(void *arg)
 fd = open(device, O_RDWR);
 if (fd < 0) {
 /* Linux-only, we can use %m in printf.  */
-fprintf(stderr, "Failed to open %s: %m", device);
+fprintf(stderr, "Failed to open %s: %m\n", device);
 goto out_socket;
 }
 
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
index 0a7e013..46fd483 100644
--- a/qemu-nbd.texi
+++ b/qemu-nbd.texi
@@ -15,7 +15,7 @@ Export QEMU disk image using NBD protocol.
 @item @var{filename}
  is a disk image filename
 @item -p, --port=@var{port}
-  port to listen on (default @samp{1024})
+  port to listen on (default @samp{10809})
 @item -o, --offset=@var{offset}
   offset into the image
 @item -b, --bind=@var{iface}
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH qom-next 4/4] qom: Implement qom-set HMP command

2014-05-11 Thread Hani Benhabiles
On Thu, May 08, 2014 at 04:21:17PM +0200, Andreas Färber wrote:
> Re-implemented based on qmp_qom_set() to facilitate argument parsing.
> 
> Signed-off-by: Andreas Färber 
> ---
>  hmp-commands.hx | 13 +
>  hmp.c   | 18 ++
>  hmp.h   |  1 +
>  3 files changed, 32 insertions(+)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index c0603e9..73145b7 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1704,6 +1704,19 @@ Print QOM property @var{property} of object at 
> location @var{path}
>  ETEXI
>  
>  {
> +.name   = "qom-set",
> +.args_type  = "path:s,property:s,value:s",
> +.params = "path property value",
> +.help   = "set QOM property",
> +.mhandler.cmd  = hmp_qom_set,
> +},
> +
> +STEXI
> +@item qom-set @var{path} @var{property} @var{value}
> +Set QOM property @var{property} of object at location @var{path} to value 
> @var{value}
> +ETEXI
> +
> +{
>  .name   = "info",
>  .args_type  = "item:s?",
>  .params = "[subcommand]",
> diff --git a/hmp.c b/hmp.c
> index d7d7a98..1cc2e60 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -1715,3 +1715,21 @@ void hmp_qom_get(Monitor *mon, const QDict *qdict)
>  }
>  hmp_handle_error(mon, &err);
>  }
> +
> +void hmp_qom_set(Monitor *mon, const QDict *qdict)
> +{
> +const char *path = qdict_get_str(qdict, "path");
> +const char *property = qdict_get_str(qdict, "property");
> +const char *value = qdict_get_str(qdict, "value");
> +Error *err = NULL;
> +Object *obj;
> +
> +obj = object_resolve_path(path, NULL);

Is there any consensus on whether to check for path ambiguity ?

It seems to me that it would be more important to do so here than in
qmp_qom_list() for example.

Other than that, patch looks fine for me.

> +if (obj == NULL) {
> +error_set(&err, QERR_DEVICE_NOT_FOUND, path);
> +hmp_handle_error(mon, &err);
> +return;
> +}
> +object_property_parse(obj, value, property, &err);
> +hmp_handle_error(mon, &err);
> +}
> diff --git a/hmp.h b/hmp.h
> index 269d99e..6b7b1da 100644
> --- a/hmp.h
> +++ b/hmp.h
> @@ -95,6 +95,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict);
>  void hmp_object_del(Monitor *mon, const QDict *qdict);
>  void hmp_qom_list(Monitor *mon, const QDict *qdict);
>  void hmp_qom_get(Monitor *mon, const QDict *qdict);
> +void hmp_qom_set(Monitor *mon, const QDict *qdict);
>  void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
>  void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
>  void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
> -- 
> 1.8.4.5
> 
> 



Re: [Qemu-devel] [PATCH qom-next 3/4] qom: Implement qom-get HMP command

2014-05-11 Thread Hani Benhabiles
On Thu, May 08, 2014 at 04:21:16PM +0200, Andreas Färber wrote:
> Reimplement it based on qmp_qom_get() to avoid converting QObjects back
> to strings.
> 
> Inspired-by: Paolo Bonzini 
> Signed-off-by: Andreas Färber 
> ---
>  hmp-commands.hx | 13 +
>  hmp.c   | 22 ++
>  hmp.h   |  1 +
>  3 files changed, 36 insertions(+)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index a0166af..c0603e9 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1691,6 +1691,19 @@ Print QOM properties of object at location @var{path}
>  ETEXI
>  
>  {
> +.name   = "qom-get",
> +.args_type  = "path:s,property:s",
> +.params = "path property",
> +.help   = "print QOM property",
> +.mhandler.cmd  = hmp_qom_get,
> +},
> +
> +STEXI
> +@item qom-get @var{path} @var{property}
> +Print QOM property @var{property} of object at location @var{path}
> +ETEXI
> +
> +{
>  .name   = "info",
>  .args_type  = "item:s?",
>  .params = "[subcommand]",
> diff --git a/hmp.c b/hmp.c
> index 1c29c8a..d7d7a98 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -1693,3 +1693,25 @@ void hmp_qom_list(Monitor *mon, const QDict *qdict)
>  }
>  hmp_handle_error(mon, &err);
>  }
> +
> +void hmp_qom_get(Monitor *mon, const QDict *qdict)
> +{
> +const char *path = qdict_get_str(qdict, "path");
> +const char *property = qdict_get_str(qdict, "property");
> +Error *err = NULL;
> +Object *obj;
> +char *value;
> +
> +obj = object_resolve_path(path, NULL);
> +if (obj == NULL) {
> +error_set(&err, QERR_DEVICE_NOT_FOUND, path);
> +hmp_handle_error(mon, &err);
> +return;
> +}
> +value = object_property_print(obj, property, true, &err);
> +if (err == NULL) {
> +monitor_printf(mon, "%s\n", value);
> +g_free(value);
> +}
> +hmp_handle_error(mon, &err);
> +}
> diff --git a/hmp.h b/hmp.h
> index 7ab969e..269d99e 100644
> --- a/hmp.h
> +++ b/hmp.h
> @@ -94,6 +94,7 @@ void hmp_cpu_add(Monitor *mon, const QDict *qdict);
>  void hmp_object_add(Monitor *mon, const QDict *qdict);
>  void hmp_object_del(Monitor *mon, const QDict *qdict);
>  void hmp_qom_list(Monitor *mon, const QDict *qdict);
> +void hmp_qom_get(Monitor *mon, const QDict *qdict);
>  void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
>  void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
>  void device_add_completion(ReadLineState *rs, int nb_args, const char *str);

This segfaults:
(qemu) qom-get /machine/unattached/device[9] date
Segmentation fault (core dumped)

And so does
(qemu) qom-get /machine/unattached/device[0] filtered-features
Segmentation fault (core dumped)

See: https://lists.gnu.org/archive/html/qemu-devel/2014-05/msg01975.html



Re: [Qemu-devel] [PATCH qom-next 2/4] qom: Implement qom-list HMP command

2014-05-11 Thread Hani Benhabiles
On Thu, May 08, 2014 at 04:21:15PM +0200, Andreas Färber wrote:
> Implement it as a wrapper for QMP qom-list, but mimic the behavior of
> scripts/qmp/qom-list in making the path argument optional and listing
> the root if absent, to hint users what kind of path to pass.
> 
> Signed-off-by: Andreas Färber 
> ---
>  hmp-commands.hx | 13 +
>  hmp.c   | 27 +++
>  hmp.h   |  1 +
>  3 files changed, 41 insertions(+)
> 
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index 8971f1b..a0166af 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1678,6 +1678,19 @@ Add CPU with id @var{id}
>  ETEXI
>  
>  {
> +.name   = "qom-list",
> +.args_type  = "path:s?",
> +.params = "path",
> +.help   = "list QOM properties",
> +.mhandler.cmd  = hmp_qom_list,
> +},
> +
> +STEXI
> +@item qom-list [@var{path}]
> +Print QOM properties of object at location @var{path}
> +ETEXI
> +
> +{
>  .name   = "info",
>  .args_type  = "item:s?",
>  .params = "[subcommand]",
> diff --git a/hmp.c b/hmp.c
> index ca869ba..1c29c8a 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -1666,3 +1666,30 @@ void hmp_object_del(Monitor *mon, const QDict *qdict)
>  qmp_object_del(id, &err);
>  hmp_handle_error(mon, &err);
>  }
> +
> +void hmp_qom_list(Monitor *mon, const QDict *qdict)
> +{
> +const char *path = qdict_get_try_str(qdict, "path");
> +ObjectPropertyInfoList *list;
> +Error *err = NULL;
> +
> +if (path == NULL) {
> +monitor_printf(mon, "/\n");
> +return;
> +}
> +list = qmp_qom_list(path, &err);
> +if (err == NULL) {

This:

> +while (list != NULL) {
> +ObjectPropertyInfoList *next = list->next;
> +
> +monitor_printf(mon, "%s (%s)\n",
> +   list->value->name, list->value->type);
> +g_free(list->value->name);
> +g_free(list->value->type);
> +g_free(list->value);
> +g_free(list);
> +list = next;
> +}

could be simplified to:
ObjectPropertyInfoList *start = list;
while (list) {
ObjectPropertyInfo *value = list->value;
monitor_printf(mon, "%s (%s)\n", value->name, value->type);
list = list->next;
}
qapi_free_ObjectPropertyInfoList(start);

Other than that, the patch seems fine to me.

> +}
> +hmp_handle_error(mon, &err);
> +}
> diff --git a/hmp.h b/hmp.h
> index 20ef454..7ab969e 100644
> --- a/hmp.h
> +++ b/hmp.h
> @@ -93,6 +93,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict);
>  void hmp_cpu_add(Monitor *mon, const QDict *qdict);
>  void hmp_object_add(Monitor *mon, const QDict *qdict);
>  void hmp_object_del(Monitor *mon, const QDict *qdict);
> +void hmp_qom_list(Monitor *mon, const QDict *qdict);
>  void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
>  void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
>  void device_add_completion(ReadLineState *rs, int nb_args, const char *str);




Re: [Qemu-devel] [PATCH qom-next 1/4] qom: Implement info qom-composition HMP command

2014-05-11 Thread Hani Benhabiles
On Thu, May 08, 2014 at 04:21:14PM +0200, Andreas Färber wrote:
> To complement qdev's bus-oriented info qtree, info qom-composition
> prints a hierarchical view of the machine composition tree.
> 
> Signed-off-by: Andreas Färber 
> ---
>  include/monitor/qdev.h |  1 +
>  monitor.c  |  7 +++
>  qdev-monitor.c | 35 +++
>  3 files changed, 43 insertions(+)
> 
> diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
> index 8d16e11..cb5c8ee 100644
> --- a/include/monitor/qdev.h
> +++ b/include/monitor/qdev.h
> @@ -8,6 +8,7 @@
>  
>  void do_info_qtree(Monitor *mon, const QDict *qdict);
>  void do_info_qdm(Monitor *mon, const QDict *qdict);
> +void do_info_qom_composition(Monitor *mon, const QDict *dict);
>  int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data);
>  int qdev_device_help(QemuOpts *opts);
>  DeviceState *qdev_device_add(QemuOpts *opts);
> diff --git a/monitor.c b/monitor.c
> index 1266ba0..c2b9315 100644
> --- a/monitor.c
> +++ b/monitor.c
> @@ -2920,6 +2920,13 @@ static mon_cmd_t info_cmds[] = {
>  .mhandler.cmd = do_info_qdm,
>  },
>  {
> +.name   = "qom-composition",
> +.args_type  = "",
> +.params = "",
> +.help   = "show QOM machine composition tree",
> +.mhandler.cmd = do_info_qom_composition,
> +},
> +{
>  .name   = "roms",
>  .args_type  = "",
>  .params = "",
> diff --git a/qdev-monitor.c b/qdev-monitor.c
> index 02cbe43..744144a 100644
> --- a/qdev-monitor.c
> +++ b/qdev-monitor.c
> @@ -658,6 +658,41 @@ void do_info_qdm(Monitor *mon, const QDict *qdict)
>  qdev_print_devinfos(true);
>  }
>  
> +typedef struct QOMCompositionState {
> +Monitor *mon;
> +int indent;
> +} QOMCompositionState;
> +
> +static void print_qom_composition(Monitor *mon, Object *obj, int indent);
> +
> +static int print_qom_composition_child(Object *obj, void *opaque)
> +{
> +QOMCompositionState *s = opaque;
> +
> +print_qom_composition(s->mon, obj, s->indent);
> +
> +return 0;
> +}
> +
> +static void print_qom_composition(Monitor *mon, Object *obj, int indent)
> +{
> +QOMCompositionState s = {
> +.mon = mon,
> +.indent = indent + 2,
> +};
> +char *name = object_get_canonical_path_component(obj);
> +
> +monitor_printf(mon, "%*s/%s (%s)\n", indent, "", name,
> +   object_get_typename(obj));
> +g_free(name);
> +object_child_foreach(obj, print_qom_composition_child, &s);
> +}
> +
> +void do_info_qom_composition(Monitor *mon, const QDict *dict)
> +{
> +print_qom_composition(mon, qdev_get_machine(), 0);
> +}
> +
>  int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
>  {
>  Error *local_err = NULL;

Reviewed-by: Hani Benhabiles 



Re: [Qemu-devel] [PATCH] monitor: Add info qom-tree subcommand.

2014-05-11 Thread Hani Benhabiles
On Wed, May 07, 2014 at 05:39:36PM +0200, Andreas Färber wrote:
> Hi Hani,
> 
> Am 27.04.2014 12:29, schrieb Hani Benhabiles:
> > Signed-off-by: Hani Benhabiles 
> > ---
> > 
> > Not sure whether the qobject stringifying functions could fit or be of some 
> > use
> > elsewhere. Thus, I kept them as static near the only place where they are 
> > used
> > at the moment.
> 
> Your "info qom-tree" reads quite similar to my proposed qom-tree script:
> http://patchwork.ozlabs.org/patch/317224/
> 
> For HMP I had been working on a command "info qom-composition" that
> emits a trimmed-down overview-style output, such as for x86_64:
> 
> (qemu) info qom-composition
> /machine (pc-i440fx-2.1-machine)
>   /peripheral-anon (container)
>   /peripheral (container)
>   /unattached (container)
> /sysbus (System)
> /device[0] (qemu64-x86_64-cpu)
>   /apic (apic)
> /device[1] (kvmvapic)
> /device[2] (i440FX)
> /device[3] (PIIX3)
>   /isa.0 (ISA)
> /device[4] (isa-i8259)
> /device[5] (isa-i8259)
> /device[6] (cirrus-vga)
> /device[7] (hpet)
> /device[8] (mc146818rtc)
> /device[9] (isa-pit)
> /device[10] (isa-pcspk)
> /device[11] (isa-serial)
> /device[12] (isa-parallel)
> /device[13] (i8042)
> /device[14] (vmport)
> /device[15] (vmmouse)
> /device[16] (port92)
> /device[17] (isa-fdc)
> /device[18] (e1000)
> /device[19] (piix3-ide)
>   /ide.0 (IDE)
>   /ide.1 (IDE)
> /device[20] (ide-cd)
> /device[21] (PIIX4_PM)
>   /i2c (i2c-bus)
> /device[22] (smbus-eeprom)
> /device[23] (smbus-eeprom)
> /device[24] (smbus-eeprom)
> /device[25] (smbus-eeprom)
> /device[26] (smbus-eeprom)
> /device[27] (smbus-eeprom)
> /device[28] (smbus-eeprom)
> /device[29] (smbus-eeprom)
>   /icc-bridge (icc-bridge)
> /icc (icc-bus)
>   /fw_cfg (fw_cfg)
>   /i440fx (i440FX-pcihost)
> /pci.0 (PCI)
> /ioapic (ioapic)
> 
> I believe both commands can coexist. Question is how.
> 
> My tree-walking implementation is not based on QMP and thus much
> slimmer. I didn't have to care about printing properties yet - that I
> deferred to a qom-get HMP command (which based on previous feedback we
> should implement either way). Possibly we could rebase your patch onto
> mine, adding an argument for whether or not to print the properties?
>

Sure, I am fine with rebasing the patch on top of yours if that ends up with
less duplicated work.

> Compared to my script, your "info qom-tree" does not allow to change the
> root, so I believe we would need to print from "/" on (rather than
> "/machine"), for dumping RNG backends etc. as well. The alternative
> would be having arguments to the command, for specifying root and/or
> output style.

A path argument (defaulting to "/") seems like a good approach to me, but I have
no strong preference on this.



Re: [Qemu-devel] [PATCH] monitor: Add info qom-tree subcommand.

2014-05-11 Thread Hani Benhabiles
On Wed, May 07, 2014 at 01:01:12PM +0200, Paolo Bonzini wrote:
> Il 05/05/2014 20:33, Luiz Capitulino ha scritto:
> >>+data = object_property_get_qobject(obj, info->name, NULL);
> >>+if (!data) {
> >>+list = list->next;
> >>+continue;
> 
> You could use object_property_print and get rid of a relatively large amount
> of code.

Thanks for pointing that. But StringOutputVisitor doesn't have handlers for 
structs and
lists like QMP countrepart so the call segfaults when used against object
properties using that.

ie. Unless I am missing something, I should add those handlers to the string
visitor before being able to use object_property_print(), right ?

> Apart from this, the patch is definitely useful.



[Qemu-devel] [PATCH 6/6] monitor: Add netdev_del id argument completion.

2014-05-07 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 26 ++
 3 files changed, 28 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index a7f9b2f..2e462c0 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1252,6 +1252,7 @@ ETEXI
 .params = "id",
 .help   = "remove host network device",
 .mhandler.cmd = hmp_netdev_del,
+.command_completion = netdev_del_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index bcecd0d..aba59e9 100644
--- a/hmp.h
+++ b/hmp.h
@@ -102,5 +102,6 @@ void chardev_remove_completion(ReadLineState *rs, int 
nb_args, const char *str);
 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index a4c429c..7f68549 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4476,6 +4476,32 @@ void set_link_completion(ReadLineState *rs, int nb_args, 
const char *str)
 }
 }
 
+void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+int len, count, i;
+NetClientState *ncs[255];
+
+if (nb_args != 2) {
+return;
+}
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+count = qemu_find_net_clients_except(NULL, ncs, 
NET_CLIENT_OPTIONS_KIND_NIC,
+ 255);
+for (i = 0; i < count; i++) {
+QemuOpts *opts;
+const char *name = ncs[i]->name;
+if (strncmp(str, name, len)) {
+continue;
+}
+opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), name);
+if (opts) {
+readline_add_completion(rs, name);
+}
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCH 5/6] monitor: Add netdev_add type argument completion.

2014-05-07 Thread Hani Benhabiles
Also update the command's documentation.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  3 ++-
 hmp.h   |  1 +
 monitor.c   | 15 +++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 3e7b29c..a7f9b2f 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1234,9 +1234,10 @@ ETEXI
 {
 .name   = "netdev_add",
 .args_type  = "netdev:O",
-.params = 
"[user|tap|socket|hubport|netmap],id=str[,prop=value][,...]",
+.params = 
"[user|tap|socket|vde|bridge|hubport|netmap],id=str[,prop=value][,...]",
 .help   = "add host network device",
 .mhandler.cmd = hmp_netdev_add,
+.command_completion = netdev_add_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 91c9c85..bcecd0d 100644
--- a/hmp.h
+++ b/hmp.h
@@ -101,5 +101,6 @@ void sendkey_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void chardev_remove_completion(ReadLineState *rs, int nb_args, const char 
*str);
 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
+void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 5ead568..a4c429c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4286,6 +4286,21 @@ void chardev_add_completion(ReadLineState *rs, int 
nb_args, const char *str)
 qapi_free_ChardevBackendInfoList(start);
 }
 
+void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+int i;
+
+if (nb_args != 2) {
+return;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+for (i = 0; NetClientOptionsKind_lookup[i]; i++) {
+add_completion_option(rs, str, NetClientOptionsKind_lookup[i]);
+}
+}
+
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 GSList *list, *elt;
-- 
1.8.3.2




[Qemu-devel] [PATCH 0/6] Miscellaneous command completion patches

2014-05-07 Thread Hani Benhabiles
Compared to v1:
* Dropped patch 02/07 for help completion conversion.
* Nothing else changed. 04,05 and 06 are R-b by Stefan.

Hani Benhabiles (6):
  monitor: Convert sendkey to use command_completion.
  monitor: Add chardev-remove command completion.
  monitor: Add chardev-add backend argument completion.
  monitor: Add set_link arguments completion.
  monitor: Add netdev_add type argument completion.
  monitor: Add netdev_del id argument completion.

 hmp-commands.hx |   8 ++-
 hmp.h   |   6 +++
 monitor.c   | 153 
 net/net.c   |   2 +-
 4 files changed, 158 insertions(+), 11 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [PATCH 2/6] monitor: Add chardev-remove command completion.

2014-05-07 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 23 +++
 3 files changed, 25 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index b4b23c8..ba88e2a 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1639,6 +1639,7 @@ ETEXI
 .params = "id",
 .help   = "remove chardev",
 .mhandler.cmd = hmp_chardev_remove,
+.command_completion = chardev_remove_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 12e21e7..affc2b6 100644
--- a/hmp.h
+++ b/hmp.h
@@ -98,5 +98,6 @@ void object_del_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
+void chardev_remove_completion(ReadLineState *rs, int nb_args, const char 
*str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 7ef251c..6316a29 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4322,6 +4322,29 @@ static void device_del_bus_completion(ReadLineState *rs, 
 BusState *bus,
 }
 }
 
+void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+ChardevInfoList *list, *start;
+
+if (nb_args != 2) {
+return;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+
+start = list = qmp_query_chardev(NULL);
+while (list) {
+ChardevInfo *chr = list->value;
+
+if (!strncmp(chr->label, str, len)) {
+readline_add_completion(rs, chr->label);
+}
+list = list->next;
+}
+qapi_free_ChardevInfoList(start);
+}
+
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 size_t len;
-- 
1.8.3.2




[Qemu-devel] [PATCH 4/6] monitor: Add set_link arguments completion.

2014-05-07 Thread Hani Benhabiles
Make it possible to query all net clients without specifying an ID when calling
qemu_find_net_clients_except().

This also adds the add_completion_option() function which is to be used for
other commands completions as well.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 34 ++
 net/net.c   |  2 +-
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 93fa534..3e7b29c 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1340,6 +1340,7 @@ ETEXI
 .params = "name on|off",
 .help   = "change the link status of a network adapter",
 .mhandler.cmd = hmp_set_link,
+.command_completion = set_link_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index f8e16a8..91c9c85 100644
--- a/hmp.h
+++ b/hmp.h
@@ -100,5 +100,6 @@ void device_del_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
 void chardev_remove_completion(ReadLineState *rs, int nb_args, const char 
*str);
 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index dacff19..5ead568 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4252,6 +4252,17 @@ static const char *next_arg_type(const char *typestr)
 return (p != NULL ? ++p : typestr);
 }
 
+static void add_completion_option(ReadLineState *rs, const char *str,
+  const char *option)
+{
+if (!str || !option) {
+return;
+}
+if (!strncmp(option, str, strlen(str))) {
+readline_add_completion(rs, option);
+}
+}
+
 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 size_t len;
@@ -4427,6 +4438,29 @@ void sendkey_completion(ReadLineState *rs, int nb_args, 
const char *str)
 }
 }
 
+void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+if (nb_args == 2) {
+NetClientState *ncs[255];
+int count, i;
+count = qemu_find_net_clients_except(NULL, ncs,
+ NET_CLIENT_OPTIONS_KIND_NONE, 
255);
+for (i = 0; i < count; i++) {
+const char *name = ncs[i]->name;
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+} else if (nb_args == 3) {
+add_completion_option(rs, str, "on");
+add_completion_option(rs, str, "off");
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
diff --git a/net/net.c b/net/net.c
index 9db4dba..0ff2e40 100644
--- a/net/net.c
+++ b/net/net.c
@@ -633,7 +633,7 @@ int qemu_find_net_clients_except(const char *id, 
NetClientState **ncs,
 if (nc->info->type == type) {
 continue;
 }
-if (!strcmp(nc->name, id)) {
+if (!id || !strcmp(nc->name, id)) {
 if (ret < max) {
 ncs[ret] = nc;
 }
-- 
1.8.3.2




[Qemu-devel] [PATCH 3/6] monitor: Add chardev-add backend argument completion.

2014-05-07 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 23 +++
 3 files changed, 25 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index ba88e2a..93fa534 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1623,6 +1623,7 @@ ETEXI
 .params = "args",
 .help   = "add chardev",
 .mhandler.cmd = hmp_chardev_add,
+.command_completion = chardev_add_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index affc2b6..f8e16a8 100644
--- a/hmp.h
+++ b/hmp.h
@@ -99,5 +99,6 @@ void device_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
 void chardev_remove_completion(ReadLineState *rs, int nb_args, const char 
*str);
+void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 6316a29..dacff19 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4252,6 +4252,29 @@ static const char *next_arg_type(const char *typestr)
 return (p != NULL ? ++p : typestr);
 }
 
+void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+ChardevBackendInfoList *list, *start;
+
+if (nb_args != 2) {
+return;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+
+start = list = qmp_query_chardev_backends(NULL);
+while (list) {
+const char *chr_name = list->value->name;
+
+if (!strncmp(chr_name, str, len)) {
+readline_add_completion(rs, chr_name);
+}
+list = list->next;
+}
+qapi_free_ChardevBackendInfoList(start);
+}
+
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 GSList *list, *elt;
-- 
1.8.3.2




[Qemu-devel] [PATCH 1/6] monitor: Convert sendkey to use command_completion.

2014-05-07 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 32 +++-
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8971f1b..b4b23c8 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -556,6 +556,7 @@ ETEXI
 .params = "keys [hold_ms]",
 .help   = "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', 
default hold time=100 ms)",
 .mhandler.cmd = hmp_send_key,
+.command_completion = sendkey_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 20ef454..12e21e7 100644
--- a/hmp.h
+++ b/hmp.h
@@ -97,5 +97,6 @@ void object_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 2d3fb3f..7ef251c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4359,6 +4359,28 @@ void object_del_completion(ReadLineState *rs, int 
nb_args, const char *str)
 qapi_free_ObjectPropertyInfoList(start);
 }
 
+void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+int i;
+char *sep;
+size_t len;
+
+if (nb_args != 2) {
+return;
+}
+sep = strrchr(str, '-');
+if (sep) {
+str = sep + 1;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+for (i = 0; i < Q_KEY_CODE_MAX; i++) {
+if (!strncmp(str, QKeyCode_lookup[i], len)) {
+readline_add_completion(rs, QKeyCode_lookup[i]);
+}
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
@@ -4427,15 +4449,7 @@ static void monitor_find_completion_by_table(Monitor 
*mon,
 break;
 case 's':
 case 'S':
-if (!strcmp(cmd->name, "sendkey")) {
-char *sep = strrchr(str, '-');
-if (sep)
-str = sep + 1;
-readline_set_completion_index(mon->rs, strlen(str));
-for (i = 0; i < Q_KEY_CODE_MAX; i++) {
-cmd_completion(mon, str, QKeyCode_lookup[i]);
-}
-} else if (!strcmp(cmd->name, "help|?")) {
+if (!strcmp(cmd->name, "help|?")) {
 monitor_find_completion_by_table(mon, cmd_table,
  &args[1], nb_args - 1);
 }
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH 2/7] monitor: Convert help|? to use command_completion.

2014-05-07 Thread Hani Benhabiles
On Mon, May 05, 2014 at 03:51:37PM -0400, Luiz Capitulino wrote:
> On Sun, 27 Apr 2014 17:00:03 +0100
> Hani Benhabiles  wrote:
> 
> > Signed-off-by: Hani Benhabiles 
> > ---
> >  hmp-commands.hx |  1 +
> >  hmp.h   |  1 +
> >  monitor.c   | 24 +---
> >  3 files changed, 19 insertions(+), 7 deletions(-)
> > 
> > diff --git a/hmp-commands.hx b/hmp-commands.hx
> > index b3f45d6..ba13997 100644
> > --- a/hmp-commands.hx
> > +++ b/hmp-commands.hx
> > @@ -15,6 +15,7 @@ ETEXI
> >  .params = "[cmd]",
> >  .help   = "show the help",
> >  .mhandler.cmd = do_help_cmd,
> > +.command_completion = help_completion,
> >  },
> >  
> >  STEXI
> > diff --git a/hmp.h b/hmp.h
> > index 12e21e7..55f78fa 100644
> > --- a/hmp.h
> > +++ b/hmp.h
> > @@ -98,5 +98,6 @@ void object_del_completion(ReadLineState *rs, int 
> > nb_args, const char *str);
> >  void device_add_completion(ReadLineState *rs, int nb_args, const char 
> > *str);
> >  void device_del_completion(ReadLineState *rs, int nb_args, const char 
> > *str);
> >  void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
> > +void help_completion(ReadLineState *rs, int nb_args, const char *str);
> >  
> >  #endif
> > diff --git a/monitor.c b/monitor.c
> > index 7edfcee..acbbaf8 100644
> > --- a/monitor.c
> > +++ b/monitor.c
> > @@ -4407,6 +4407,23 @@ void sendkey_completion(ReadLineState *rs, int 
> > nb_args, const char *str)
> >  }
> >  }
> >  
> > +void help_completion(ReadLineState *rs, int nb_args, const char *str)
> > +{
> > +int i;
> > +size_t len;
> > +
> > +if (nb_args != 2) {
> > +return;
> > +}
> > +len = strlen(str);
> > +readline_set_completion_index(rs, len);
> > +for (i = 0; mon_cmds[i].name; i++) {
> > +if (!strncmp(str, mon_cmds[i].name, len)) {
> > +readline_add_completion(rs, mon_cmds[i].name);
> > +}
> > +}
> > +}
> > +
> >  static void monitor_find_completion_by_table(Monitor *mon,
> >   const mon_cmd_t *cmd_table,
> >   char **args,
> > @@ -4473,13 +4490,6 @@ static void monitor_find_completion_by_table(Monitor 
> > *mon,
> >  readline_set_completion_index(mon->rs, strlen(str));
> >  bdrv_iterate(block_completion_it, &mbs);
> >  break;
> > -case 's':
> > -case 'S':
> > -if (!strcmp(cmd->name, "help|?")) {
> > -monitor_find_completion_by_table(mon, cmd_table,
> > - &args[1], nb_args - 1);
> > -}
> > -break;
> >  default:
> >  break;
> >  }
> 
> This breaks auto-completion for:
> 
> (qemu) help info v
> 
> Which would auto-complete "vnc". IIRC, that's one of the reasons we have
> monitor_find_completion_by_table().

Thanks for spotting that.

Quickly thinking about it, a possible way to solve this is to change
command_completion() prototype to be passed the whole args table, and not just a
string and then have those "special cases" (like help+info) handled.

Better drop patch 02/07 and leave the rest as is for now, I believe. I will send
a v2.



Re: [Qemu-devel] [PATCH] Update QEMU checkpatch.pl to current linux version

2014-05-07 Thread Hani Benhabiles
On Tue, May 06, 2014 at 07:28:35PM +0100, Peter Maydell wrote:
> On 6 May 2014 19:16, Mike Day  wrote:
> > This updates scripts/checkpatch.pl to version 0.32. Also,
> > forward-ported the QEMU checks for no tabs and correct capitalization
> > of "QEMU." Finally, make --no-tree the default option since this will
> > be used with Qemu.
> >
> > Signed-off-by: Mike Day 
> > ---
> >
> > Notes: This is a huge patch and I needed to include white space
> > changes to get it applying cleanly.
> > I've tested this so far with some random patches off the mailing list
> > and some others that I've got around. I also tested for some intentional
> > errors.
> >
> >  scripts/checkpatch.pl | 2544 
> > -
> >  1 file changed, 2120 insertions(+), 424 deletions(-)
> 
> I think this is going to be difficult to review, to say the least.
> 
> Where does your patch come from? Is the kernel's checkpatch.pl
> just a single commit between 0.31 and 0.32 (surely not) or
> a series of fixes?
> 
> A couple of ideas about how we could approach this:
>  (1) make a commit which is simply copying the kernel's 0.32
>   into our repo; then follow that with a series of commits which
>   re-apply our local changes.
>  (2) apply all the individual commits from the kernel between 0.31
>  and 0.32 to our repo
>  (3) give up and stick with 0.31...
> 
> (note that 1 and 2 here both end up with the same result as
> applying this patch, but with a different commit history to get
> there.)
> 
> We only have 16 commits which touch checkpatch.pl, so
> my favourite of these is (1). This also makes it easier when
> we want to upgrade to 0.33 some time in the future, I think.
> 
> It might also be helpful if you could describe the benefits
> we get from this update (any bugfixes for false positives we
> tend to run into? useful new checks?)

FWIW, this new version doesn't trigger a false positive I was having with
patches 05-07 in [1].

However, from a quick test for this patch on a couple of patches, I am getting
warnings like this: "WARNING: braces {} are not necessary for single statement
blocks" so there are still some Qemu related changes missing.

[1] https://lists.gnu.org/archive/html/qemu-devel/2014-04/msg04180.html



[Qemu-devel] [PATCH] readline: Sort completions before printing them.

2014-05-01 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 util/readline.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/util/readline.c b/util/readline.c
index 8441be4..8d2a0d3 100644
--- a/util/readline.c
+++ b/util/readline.c
@@ -272,6 +272,11 @@ void readline_set_completion_index(ReadLineState *rs, int 
index)
 rs->completion_index = index;
 }
 
+static int completion_comp(const void *a, const void *b)
+{
+return strcmp(*(const char **) a, *(const char **) b);
+}
+
 static void readline_completion(ReadLineState *rs)
 {
 int len, i, j, max_width, nb_cols, max_prefix;
@@ -297,6 +302,8 @@ static void readline_completion(ReadLineState *rs)
 if (len > 0 && rs->completions[0][len - 1] != '/')
 readline_insert_char(rs, ' ');
 } else {
+qsort(rs->completions, rs->nb_completions, sizeof(char *),
+  completion_comp);
 rs->printf_func(rs->opaque, "\n");
 max_width = 0;
 max_prefix = 0;
-- 
1.8.3.2




Re: [Qemu-devel] [Crucial bug] Qemu-2.0.0 do not support virtio-net hot plug/unplug exceed two times

2014-04-29 Thread Hani Benhabiles
On Mon, Apr 28, 2014 at 02:55:03AM +, Gonglei (Arei) wrote:
> Hi,
> 
> > Il 26/04/2014 10:56, Gonglei (Arei) ha scritto:
> > > Public bug reported:
> > >
> > > I want to repeated hot-plug/unplug the virtio-net in the latest qemu
> > upstream
> > > (commit 839a5547574e57cce62f49bfc50fe1f04b00589a), but I am failed at
> > the
> > > second time hot plug the virtio-net to guest.
> > >
> > > Then I tried to use Qemu-2.0.0 release version, but I got the error too.
> > >
> > > Cmdline for vm:
> > >
> > > /mnt/sdb/gonglei/qemu/x86_64-softmmu/qemu-system-x86_64 -enable-kvm
> > -m 4096 -smp 4 -name sles-et -boot c -drive file=/mnt/sdb/gonglei/image/
> > sles-3.img -vnc 0.0.0.0:10 -monitor stdio
> > > QEMU 1.7.50 monitor - type 'help' for more information
> > 
> > For commit 839a5547574e57cce62f49bfc50fe1f04b00589a you should have
> > gotten 1.7.90 as the version number.
> > 
> Maybe just because Peter Maydell merge remote-tracking branch. But it doesn't 
> matter.
> 
> > > (qemu) device_add virtio-net-pci,id=net1
> > > (qemu) device_del net1
> > > (qemu) device_add virtio-net-pci,id=net1
> > > Duplicate ID 'net1' for device
> > > (qemu)
> > 
> > I cannot reproduce this on Fedora running the 2.0.0 package from the
> > virt-preview repository (qemu-system-x86-2.0.0-2.fc20.x86_64).
> > 
> > For what it's worth, I get this for --version:
> > 
> > $ qemu-system-x86_64 --version
> > QEMU emulator version 2.0.0, Copyright (c) 2003-2008 Fabrice Bellard
> > 
> > and likewise, when starting QEMU with "-monitor stdio":
> > 
> > QEMU 2.0.0 monitor - type 'help' for more information
> > 
> I got the QEMU 2.0.0 version from http://wiki.qemu.org/Download
> 
> The issue was reproduced perforce:
> UVP:/mnt/sdb/gonglei/code/qemu-2.0.0/x86_64-softmmu #./qemu-system-x86_64 
> -enable-kvm -m 4096 -smp 4 -name sles \
>  -boot c -drive file=/mnt/sdb/gonglei/image/sles-3.img -vnc 0.0.0.0:10 
> -monitor stdio
> QEMU 2.0.0 monitor - type 'help' for more information
> (qemu) device_add virtio-net-pci,id=net1
> (qemu) device_del net1
> (qemu)  device_add virtio-net-pci,id=net1
> Duplicate ID 'net1' for device
> (qemu)
> 
> Anything wrong? Thanks!

Issue confirmed with both -monitor and qmp-shell with different other device
models like e1000.



[Qemu-devel] [PATCH] qmp: Report path ambiguity error.

2014-04-28 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
Suggested-by: Andreas Färber 
---
 qmp.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/qmp.c b/qmp.c
index 74107be..0d49abf 100644
--- a/qmp.c
+++ b/qmp.c
@@ -199,7 +199,10 @@ ObjectPropertyInfoList *qmp_qom_list(const char *path, 
Error **errp)
 ObjectProperty *prop;
 
 obj = object_resolve_path(path, &ambiguous);
-if (obj == NULL) {
+if (ambiguous) {
+error_setg(errp, "Path '%s' is ambiguous", path);
+return NULL;
+} else if (obj == NULL) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, path);
 return NULL;
 }
-- 
1.8.3.2




[Qemu-devel] [PATCH 3/7] monitor: Add chardev-remove command completion.

2014-04-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 23 +++
 3 files changed, 25 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index ba13997..8c93e61 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1632,6 +1632,7 @@ ETEXI
 .params = "id",
 .help   = "remove chardev",
 .mhandler.cmd = hmp_chardev_remove,
+.command_completion = chardev_remove_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 55f78fa..59e3463 100644
--- a/hmp.h
+++ b/hmp.h
@@ -99,5 +99,6 @@ void device_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
 void help_completion(ReadLineState *rs, int nb_args, const char *str);
+void chardev_remove_completion(ReadLineState *rs, int nb_args, const char 
*str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index acbbaf8..b0c7a19 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4348,6 +4348,29 @@ static void device_del_bus_completion(ReadLineState *rs, 
 BusState *bus,
 }
 }
 
+void chardev_remove_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+ChardevInfoList *list, *start;
+
+if (nb_args != 2) {
+return;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+
+start = list = qmp_query_chardev(NULL);
+while (list) {
+ChardevInfo *chr = list->value;
+
+if (!strncmp(chr->label, str, len)) {
+readline_add_completion(rs, chr->label);
+}
+list = list->next;
+}
+qapi_free_ChardevInfoList(start);
+}
+
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 size_t len;
-- 
1.8.3.2




[Qemu-devel] [PATCH 5/7] monitor: Add set_link arguments completion.

2014-04-27 Thread Hani Benhabiles
Make it possible to query all net clients without specifying an ID when calling
qemu_find_net_clients_except().

This also adds the add_completion_option() function which is to be used for
other commands completions as well.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 34 ++
 net/net.c   |  2 +-
 4 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 648400a..353161f 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1333,6 +1333,7 @@ ETEXI
 .params = "name on|off",
 .help   = "change the link status of a network adapter",
 .mhandler.cmd = hmp_set_link,
+.command_completion = set_link_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 9fc48b2..dec29c7 100644
--- a/hmp.h
+++ b/hmp.h
@@ -101,5 +101,6 @@ void sendkey_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void help_completion(ReadLineState *rs, int nb_args, const char *str);
 void chardev_remove_completion(ReadLineState *rs, int nb_args, const char 
*str);
 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 1ce283a..c7ad78c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4278,6 +4278,17 @@ static const char *next_arg_type(const char *typestr)
 return (p != NULL ? ++p : typestr);
 }
 
+static void add_completion_option(ReadLineState *rs, const char *str,
+  const char *option)
+{
+if (!str || !option) {
+return;
+}
+if (!strncmp(option, str, strlen(str))) {
+readline_add_completion(rs, option);
+}
+}
+
 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 size_t len;
@@ -4470,6 +4481,29 @@ void help_completion(ReadLineState *rs, int nb_args, 
const char *str)
 }
 }
 
+void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+if (nb_args == 2) {
+NetClientState *ncs[255];
+int count, i;
+count = qemu_find_net_clients_except(NULL, ncs,
+ NET_CLIENT_OPTIONS_KIND_NONE, 
255);
+for (i = 0; i < count; i++) {
+const char *name = ncs[i]->name;
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+} else if (nb_args == 3) {
+add_completion_option(rs, str, "on");
+add_completion_option(rs, str, "off");
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
diff --git a/net/net.c b/net/net.c
index a4aadff..b6cd75f 100644
--- a/net/net.c
+++ b/net/net.c
@@ -633,7 +633,7 @@ int qemu_find_net_clients_except(const char *id, 
NetClientState **ncs,
 if (nc->info->type == type) {
 continue;
 }
-if (!strcmp(nc->name, id)) {
+if (!id || !strcmp(nc->name, id)) {
 if (ret < max) {
 ncs[ret] = nc;
 }
-- 
1.8.3.2




[Qemu-devel] [PATCH 0/7] Miscellaneous command completion patches

2014-04-27 Thread Hani Benhabiles
Compared to the larger series sent before:
* Patches 01-03 are already in qmp branch.
* Added patches to convert sendkey, help/? to use new completion callback.
* Dropped patch 06 (cpu index completion) as deemed not useful enough.
* netdev_add now uses the same values array as qapi instead of hardcoding them.
* Left patches 10-17 for a separate series to make review process faster.
* wrt. to Luiz' question about set_link patch: It prints both backend and
  frontend values because both are accepted by set_link command.

Hani Benhabiles (7):
  monitor: Convert sendkey to use command_completion.
  monitor: Convert help|? to use command_completion.
  monitor: Add chardev-remove command completion.
  monitor: Add chardev-add backend argument completion.
  monitor: Add set_link arguments completion.
  monitor: Add netdev_add type argument completion.
  monitor: Add netdev_del id argument completion.

 hmp-commands.hx |   9 ++-
 hmp.h   |   7 +++
 monitor.c   | 175 +++-
 net/net.c   |   2 +-
 4 files changed, 176 insertions(+), 17 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [PATCH 2/7] monitor: Convert help|? to use command_completion.

2014-04-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 24 +---
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index b3f45d6..ba13997 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -15,6 +15,7 @@ ETEXI
 .params = "[cmd]",
 .help   = "show the help",
 .mhandler.cmd = do_help_cmd,
+.command_completion = help_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 12e21e7..55f78fa 100644
--- a/hmp.h
+++ b/hmp.h
@@ -98,5 +98,6 @@ void object_del_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
+void help_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 7edfcee..acbbaf8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4407,6 +4407,23 @@ void sendkey_completion(ReadLineState *rs, int nb_args, 
const char *str)
 }
 }
 
+void help_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+int i;
+size_t len;
+
+if (nb_args != 2) {
+return;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+for (i = 0; mon_cmds[i].name; i++) {
+if (!strncmp(str, mon_cmds[i].name, len)) {
+readline_add_completion(rs, mon_cmds[i].name);
+}
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
@@ -4473,13 +4490,6 @@ static void monitor_find_completion_by_table(Monitor 
*mon,
 readline_set_completion_index(mon->rs, strlen(str));
 bdrv_iterate(block_completion_it, &mbs);
 break;
-case 's':
-case 'S':
-if (!strcmp(cmd->name, "help|?")) {
-monitor_find_completion_by_table(mon, cmd_table,
- &args[1], nb_args - 1);
-}
-break;
 default:
 break;
 }
-- 
1.8.3.2




[Qemu-devel] [PATCH 7/7] monitor: Add netdev_del id argument completion.

2014-04-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 26 ++
 3 files changed, 28 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 73fbe54..f10f52f 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1245,6 +1245,7 @@ ETEXI
 .params = "id",
 .help   = "remove host network device",
 .mhandler.cmd = hmp_netdev_del,
+.command_completion = netdev_del_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 7b85834..98b599a 100644
--- a/hmp.h
+++ b/hmp.h
@@ -103,5 +103,6 @@ void chardev_remove_completion(ReadLineState *rs, int 
nb_args, const char *str);
 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
 void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index cc6d01b..c48f9db 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4519,6 +4519,32 @@ void set_link_completion(ReadLineState *rs, int nb_args, 
const char *str)
 }
 }
 
+void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+int len, count, i;
+NetClientState *ncs[255];
+
+if (nb_args != 2) {
+return;
+}
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+count = qemu_find_net_clients_except(NULL, ncs, 
NET_CLIENT_OPTIONS_KIND_NIC,
+ 255);
+for (i = 0; i < count; i++) {
+QemuOpts *opts;
+const char *name = ncs[i]->name;
+if (strncmp(str, name, len)) {
+continue;
+}
+opts = qemu_opts_find(qemu_find_opts_err("netdev", NULL), name);
+if (opts) {
+readline_add_completion(rs, name);
+}
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




[Qemu-devel] [PATCH 6/7] monitor: Add netdev_add type argument completion.

2014-04-27 Thread Hani Benhabiles
Also update the command's documentation.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  3 ++-
 hmp.h   |  1 +
 monitor.c   | 15 +++
 3 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 353161f..73fbe54 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1227,9 +1227,10 @@ ETEXI
 {
 .name   = "netdev_add",
 .args_type  = "netdev:O",
-.params = 
"[user|tap|socket|hubport|netmap],id=str[,prop=value][,...]",
+.params = 
"[user|tap|socket|vde|bridge|hubport|netmap],id=str[,prop=value][,...]",
 .help   = "add host network device",
 .mhandler.cmd = hmp_netdev_add,
+.command_completion = netdev_add_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index dec29c7..7b85834 100644
--- a/hmp.h
+++ b/hmp.h
@@ -102,5 +102,6 @@ void help_completion(ReadLineState *rs, int nb_args, const 
char *str);
 void chardev_remove_completion(ReadLineState *rs, int nb_args, const char 
*str);
 void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void set_link_completion(ReadLineState *rs, int nb_args, const char *str);
+void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index c7ad78c..cc6d01b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4312,6 +4312,21 @@ void chardev_add_completion(ReadLineState *rs, int 
nb_args, const char *str)
 qapi_free_ChardevBackendInfoList(start);
 }
 
+void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+int i;
+
+if (nb_args != 2) {
+return;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+for (i = 0; NetClientOptionsKind_lookup[i]; i++) {
+add_completion_option(rs, str, NetClientOptionsKind_lookup[i]);
+}
+}
+
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 GSList *list, *elt;
-- 
1.8.3.2




[Qemu-devel] [PATCH 1/7] monitor: Convert sendkey to use command_completion.

2014-04-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 32 +++-
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 4c4d261..b3f45d6 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -556,6 +556,7 @@ ETEXI
 .params = "keys [hold_ms]",
 .help   = "send keys to the VM (e.g. 'sendkey ctrl-alt-f1', 
default hold time=100 ms)",
 .mhandler.cmd = hmp_send_key,
+.command_completion = sendkey_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 20ef454..12e21e7 100644
--- a/hmp.h
+++ b/hmp.h
@@ -97,5 +97,6 @@ void object_add_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 17738f8..7edfcee 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4385,6 +4385,28 @@ void object_del_completion(ReadLineState *rs, int 
nb_args, const char *str)
 qapi_free_ObjectPropertyInfoList(start);
 }
 
+void sendkey_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+int i;
+char *sep;
+size_t len;
+
+if (nb_args != 2) {
+return;
+}
+sep = strrchr(str, '-');
+if (sep) {
+str = sep + 1;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+for (i = 0; i < Q_KEY_CODE_MAX; i++) {
+if (!strncmp(str, QKeyCode_lookup[i], len)) {
+readline_add_completion(rs, QKeyCode_lookup[i]);
+}
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
@@ -4453,15 +4475,7 @@ static void monitor_find_completion_by_table(Monitor 
*mon,
 break;
 case 's':
 case 'S':
-if (!strcmp(cmd->name, "sendkey")) {
-char *sep = strrchr(str, '-');
-if (sep)
-str = sep + 1;
-readline_set_completion_index(mon->rs, strlen(str));
-for (i = 0; i < Q_KEY_CODE_MAX; i++) {
-cmd_completion(mon, str, QKeyCode_lookup[i]);
-}
-} else if (!strcmp(cmd->name, "help|?")) {
+if (!strcmp(cmd->name, "help|?")) {
 monitor_find_completion_by_table(mon, cmd_table,
  &args[1], nb_args - 1);
 }
-- 
1.8.3.2




[Qemu-devel] [PATCH 4/7] monitor: Add chardev-add backend argument completion.

2014-04-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  1 +
 monitor.c   | 23 +++
 3 files changed, 25 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 8c93e61..648400a 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1616,6 +1616,7 @@ ETEXI
 .params = "args",
 .help   = "add chardev",
 .mhandler.cmd = hmp_chardev_add,
+.command_completion = chardev_add_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 59e3463..9fc48b2 100644
--- a/hmp.h
+++ b/hmp.h
@@ -100,5 +100,6 @@ void device_del_completion(ReadLineState *rs, int nb_args, 
const char *str);
 void sendkey_completion(ReadLineState *rs, int nb_args, const char *str);
 void help_completion(ReadLineState *rs, int nb_args, const char *str);
 void chardev_remove_completion(ReadLineState *rs, int nb_args, const char 
*str);
+void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index b0c7a19..1ce283a 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4278,6 +4278,29 @@ static const char *next_arg_type(const char *typestr)
 return (p != NULL ? ++p : typestr);
 }
 
+void chardev_add_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+ChardevBackendInfoList *list, *start;
+
+if (nb_args != 2) {
+return;
+}
+len = strlen(str);
+readline_set_completion_index(rs, len);
+
+start = list = qmp_query_chardev_backends(NULL);
+while (list) {
+const char *chr_name = list->value->name;
+
+if (!strncmp(chr_name, str, len)) {
+readline_add_completion(rs, chr_name);
+}
+list = list->next;
+}
+qapi_free_ChardevBackendInfoList(start);
+}
+
 void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 GSList *list, *elt;
-- 
1.8.3.2




[Qemu-devel] [PATCH] monitor: Add info qom-tree subcommand.

2014-04-27 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---

Not sure whether the qobject stringifying functions could fit or be of some use
elsewhere. Thus, I kept them as static near the only place where they are used
at the moment.

 hmp-commands.hx |   2 +
 hmp.c   | 143 
 hmp.h   |   1 +
 monitor.c   |   7 +++
 4 files changed, 153 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index f3fc514..65b5e33 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1754,6 +1754,8 @@ show qdev device model list
 show roms
 @item info tpm
 show the TPM device
+@item info qom-tree
+show the QOM tree
 @end table
 ETEXI
 
diff --git a/hmp.c b/hmp.c
index 2f279c4..891a34e 100644
--- a/hmp.c
+++ b/hmp.c
@@ -22,9 +22,11 @@
 #include "qemu/sockets.h"
 #include "monitor/monitor.h"
 #include "qapi/opts-visitor.h"
+#include "qapi/qmp/types.h"
 #include "ui/console.h"
 #include "block/qapi.h"
 #include "qemu-io.h"
+#include "qom/qom-qobject.h"
 
 static void hmp_handle_error(Monitor *mon, Error **errp)
 {
@@ -712,6 +714,147 @@ void hmp_info_tpm(Monitor *mon, const QDict *qdict)
 qapi_free_TPMInfoList(info_list);
 }
 
+static char *qobject_to_str(const QObject *, int);
+
+static char *qlist_to_str(const QObject *obj, int indent)
+{
+char *buf = NULL;
+const QListEntry *entry;
+int i = 0;
+
+assert(qobject_type(obj) == QTYPE_QLIST);
+
+entry = qlist_first(qobject_to_qlist(obj));
+while (entry) {
+char *new, *str;
+int type = qobject_type(entry->value);
+str = qobject_to_str(entry->value, indent);
+if (type == QTYPE_QLIST || type == QTYPE_QDICT) {
+new = g_strdup_printf("%s%*sElement #%d:\n%s", buf ?: "",
+  indent, "", i++, str);
+} else {
+new = g_strdup_printf("%s%*sElement #%d: %s\n", buf ?: "",
+  indent, "", i++, str);
+}
+g_free(buf);
+g_free(str);
+buf = new;
+entry = qlist_next(entry);
+}
+return buf;
+}
+
+static char *qdict_to_str(const QObject *obj, int indent)
+{
+QDict *dict = qobject_to_qdict(obj);
+const QDictEntry *entry;
+char *buf = NULL;
+
+assert(qobject_type(obj) == QTYPE_QDICT);
+
+for (entry = qdict_first(dict); entry; entry = qdict_next(dict, entry)) {
+char *str, *new;
+int type = qobject_type(entry->value);
+str = qobject_to_str(entry->value, indent);
+if (type == QTYPE_QLIST || type == QTYPE_QDICT) {
+new = g_strdup_printf("%s%*s%s:\n%s", buf ?: "", indent, "",
+  entry->key, str);
+} else {
+new = g_strdup_printf("%s%*s%s: %s\n", buf ?: "", indent, "",
+  entry->key, str);
+}
+g_free(buf);
+g_free(str);
+buf = new;
+}
+return buf;
+}
+
+static char *qobject_to_str(const QObject *obj, int indent)
+{
+switch (qobject_type(obj)) {
+case QTYPE_QSTRING: {
+QString *value = qobject_to_qstring(obj);
+return g_strdup(qstring_get_str(value));
+}
+case QTYPE_QINT: {
+QInt *value = qobject_to_qint(obj);
+return g_strdup_printf("%" PRId64, qint_get_int(value));
+}
+case QTYPE_QBOOL: {
+QBool *value = qobject_to_qbool(obj);
+return g_strdup(qbool_get_int(value) ? "True" : "False");
+}
+case QTYPE_QERROR: {
+QString *value = qerror_human((QError *)obj);
+return g_strdup(qstring_get_str(value));
+}
+case QTYPE_QFLOAT: {
+QFloat *value = qobject_to_qfloat(obj);
+return g_strdup_printf("%g", qfloat_get_double(value));
+}
+case QTYPE_QLIST:
+return qlist_to_str(obj, indent + 2);
+case QTYPE_QDICT:
+return qdict_to_str(obj, indent + 2);
+case QTYPE_NONE:
+break;
+case QTYPE_MAX:
+default:
+abort();
+}
+return NULL;
+}
+
+static void hmp_print_qom_tree(Monitor *mon, const char *path, int indent)
+{
+ObjectPropertyInfoList *list, *start;
+
+monitor_printf(mon, "%*s%s:\n", indent, "", path);
+start = list = qmp_qom_list(path, NULL);
+indent += 2;
+while (list) {
+ObjectPropertyInfo *info = list->value;
+
+if (!strncmp(info->type, "child<", 5)) {
+char *name = g_strdup_printf("%s/%s", path, info->name);
+hmp_print_qom_tree(mon, name, indent);
+g_free(name);
+} else {
+Object *obj = NULL;
+QObject *data = NULL;
+char *str;
+
+obj = object_resolve_pat

Re: [Qemu-devel] [PATCH] qmp: Remove unused variable.

2014-04-25 Thread Hani Benhabiles
On Fri, Apr 25, 2014 at 05:51:33PM +0200, Andreas Färber wrote:
> Am 25.04.2014 17:40, schrieb Luiz Capitulino:
> > On Tue, 22 Apr 2014 22:44:03 +0100
> > Hani Benhabiles  wrote:
> > 
> >> Signed-off-by: Hani Benhabiles 
> >> ---
> >>  qmp.c | 3 +--
> >>  1 file changed, 1 insertion(+), 2 deletions(-)
> >>
> >> diff --git a/qmp.c b/qmp.c
> >> index 87a28f7..44a6e17 100644
> >> --- a/qmp.c
> >> +++ b/qmp.c
> >> @@ -194,11 +194,10 @@ void qmp_system_wakeup(Error **errp)
> >>  ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
> >>  {
> >>  Object *obj;
> >> -bool ambiguous = false;
> >>  ObjectPropertyInfoList *props = NULL;
> >>  ObjectProperty *prop;
> >>  
> >> -obj = object_resolve_path(path, &ambiguous);
> >> +obj = object_resolve_path(path, NULL);
> >>  if (obj == NULL) {
> >>  error_set(errp, QERR_DEVICE_NOT_FOUND, path);
> >>  return NULL;
> > 
> > I'm under the impression that this check in object_resolve_partial_path():
> > 
> > if (ambiguous && *ambiguous) {
> > return NULL;
> > }
> > 
> > Uses 'ambiguous' internally. In that case, this change could have a side 
> > effect.
> > 
> > But I'm not sure, I think it would be good to get a reviewed-by from
> > a QOM expert.
> 
> Your understanding matches mine. I would propose to instead use the
> variable in error reporting:
> 

Luiz, Andreas, thanks for spotting this.

On second thought, I agree that this has the side effect of listing the last
found object with that path value, though the preivous behaviour too is
suboptimal as it reports that no devices are found at that path.

> if (ambiguous) {
> error_setg(errp, "Path '%s' is ambiguous.", path);
> } else {
> error_set(errp, QERR_DEVICE_NOT_FOUND, path);
> }
> 

Probably, you meant something like this:

if (ambiguous) {
error_set(errp, QERR_AMBIGUOUS_PATH, path);
} else if (!obj) {
error_set(errp, QERR_DEVICE_NOT_FOUND, path);
}


> My reasoning is that an ambiguous path might deliver unpredictable
> results (whichever it encounters first), across QEMU versions at least.
> 
> But I'd like to hear Paolo's opinion, too, since he was involved in
> loosening requirements on paths.
> 

Is this documented somewhere ? Searching the mailing-list archives doesn't show
something concrete. Paolo ?

Quick grepping shows only one out of 9 other object_resolve_path() calls
checking for path ambiguity.




Re: [Qemu-devel] [PATCH 0/3] monitor: Improve command completion

2014-04-25 Thread Hani Benhabiles
On Fri, Apr 25, 2014 at 09:48:33AM -0400, Luiz Capitulino wrote:
> On Sun, 13 Apr 2014 16:25:04 +0100
> Hani Benhabiles  wrote:
> 
> > This patch series adds a new callback to mon_cmd_t which will make adding
> > completion support for more commands cleaner.
> > 
> > It moves some existing commands completions to using the new callback and 
> > also
> > fixes the completion for device_add and drive_del commands.
> > 
> > Hani Benhabiles (3):
> >   monitor: Fix drive_del id argument type completion.
> >   monitor: Add command_completion callback to mon_cmd_t.
> >   monitor: Add device_add and device_del completion.
> > 
> >  hmp-commands.hx |  6 +-
> >  hmp.h   |  5 +
> >  monitor.c   | 57 
> > +
> >  3 files changed, 47 insertions(+), 21 deletions(-)
> 
> Applied to the qmp branch, but sendkey conversion is missing. Not sure
> we can convert help too.

Thanks. Will take a look at them.



[Qemu-devel] [PATCH] qmp: Remove unused variable.

2014-04-22 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 qmp.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/qmp.c b/qmp.c
index 87a28f7..44a6e17 100644
--- a/qmp.c
+++ b/qmp.c
@@ -194,11 +194,10 @@ void qmp_system_wakeup(Error **errp)
 ObjectPropertyInfoList *qmp_qom_list(const char *path, Error **errp)
 {
 Object *obj;
-bool ambiguous = false;
 ObjectPropertyInfoList *props = NULL;
 ObjectProperty *prop;
 
-obj = object_resolve_path(path, &ambiguous);
+obj = object_resolve_path(path, NULL);
 if (obj == NULL) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, path);
 return NULL;
-- 
1.8.3.2




[Qemu-devel] [PATCH 3/3] monitor: Add device_add and device_del completion.

2014-04-13 Thread Hani Benhabiles
Also fix device_add completion including non-hotpluggable devices.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  2 ++
 hmp.h   |  2 ++
 monitor.c   | 38 --
 3 files changed, 28 insertions(+), 14 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 1b382b6..4c4d261 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -658,6 +658,7 @@ ETEXI
 .help   = "add device, like -device on the command line",
 .user_print = monitor_user_noop,
 .mhandler.cmd_new = do_device_add,
+.command_completion = device_add_completion,
 },
 
 STEXI
@@ -673,6 +674,7 @@ ETEXI
 .params = "device",
 .help   = "remove device",
 .mhandler.cmd = hmp_device_del,
+.command_completion = device_del_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 2f2c059..20ef454 100644
--- a/hmp.h
+++ b/hmp.h
@@ -95,5 +95,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict);
 void hmp_object_del(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 566a83f..17738f8 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4278,11 +4278,15 @@ static const char *next_arg_type(const char *typestr)
 return (p != NULL ? ++p : typestr);
 }
 
-static void device_add_completion(ReadLineState *rs, const char *str)
+void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 GSList *list, *elt;
 size_t len;
 
+if (nb_args != 2) {
+return;
+}
+
 len = strlen(str);
 readline_set_completion_index(rs, len);
 list = elt = object_class_get_list(TYPE_DEVICE, false);
@@ -4291,7 +4295,9 @@ static void device_add_completion(ReadLineState *rs, 
const char *str)
 DeviceClass *dc = OBJECT_CLASS_CHECK(DeviceClass, elt->data,
  TYPE_DEVICE);
 name = object_class_get_name(OBJECT_CLASS(dc));
-if (!strncmp(name, str, len)) {
+
+if (!dc->cannot_instantiate_with_device_add_yet
+&& !strncmp(name, str, len)) {
 readline_add_completion(rs, name);
 }
 elt = elt->next;
@@ -4323,8 +4329,8 @@ void object_add_completion(ReadLineState *rs, int 
nb_args, const char *str)
 g_slist_free(list);
 }
 
-static void device_del_completion(ReadLineState *rs, BusState *bus,
-  const char *str, size_t len)
+static void device_del_bus_completion(ReadLineState *rs,  BusState *bus,
+  const char *str, size_t len)
 {
 BusChild *kid;
 
@@ -4337,11 +4343,24 @@ static void device_del_completion(ReadLineState *rs, 
BusState *bus,
 }
 
 QLIST_FOREACH(dev_child, &dev->child_bus, sibling) {
-device_del_completion(rs, dev_child, str, len);
+device_del_bus_completion(rs, dev_child, str, len);
 }
 }
 }
 
+void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+
+if (nb_args != 2) {
+return;
+}
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+device_del_bus_completion(rs, sysbus_get_default(), str, len);
+}
+
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 ObjectPropertyInfoList *list, *start;
@@ -4432,11 +4451,6 @@ static void monitor_find_completion_by_table(Monitor 
*mon,
 readline_set_completion_index(mon->rs, strlen(str));
 bdrv_iterate(block_completion_it, &mbs);
 break;
-case 'O':
-if (!strcmp(cmd->name, "device_add") && nb_args == 2) {
-device_add_completion(mon->rs, str);
-}
-break;
 case 's':
 case 'S':
 if (!strcmp(cmd->name, "sendkey")) {
@@ -4450,10 +4464,6 @@ static void monitor_find_completion_by_table(Monitor 
*mon,
 } else if (!strcmp(cmd->name, "help|?")) {
 monitor_find_completion_by_table(mon, cmd_table,
  &args[1], nb_args - 1);
-} else if (!strcmp(cmd->name, "device_del") && nb_args == 2) {
-size_t len = strlen(str);
-readline_set_completion_index(mon->rs, len);
-device_del_completion(mon->rs, sysbus_get_default(), str, len);
 }
 break;
 default:
-- 
1.8.3.2




[Qemu-devel] [PATCH 1/3] monitor: Fix drive_del id argument type completion.

2014-04-13 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index f3fc514..6bf4797 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -176,7 +176,7 @@ ETEXI
 
 {
 .name   = "drive_del",
-.args_type  = "id:s",
+.args_type  = "id:B",
 .params = "device",
 .help   = "remove host block device",
 .user_print = monitor_user_noop,
-- 
1.8.3.2




[Qemu-devel] [PATCH 0/3] monitor: Improve command completion

2014-04-13 Thread Hani Benhabiles
This patch series adds a new callback to mon_cmd_t which will make adding
completion support for more commands cleaner.

It moves some existing commands completions to using the new callback and also
fixes the completion for device_add and drive_del commands.

Hani Benhabiles (3):
  monitor: Fix drive_del id argument type completion.
  monitor: Add command_completion callback to mon_cmd_t.
  monitor: Add device_add and device_del completion.

 hmp-commands.hx |  6 +-
 hmp.h   |  5 +
 monitor.c   | 57 +
 3 files changed, 47 insertions(+), 21 deletions(-)

-- 
1.8.3.2




[Qemu-devel] [PATCH 2/3] monitor: Add command_completion callback to mon_cmd_t.

2014-04-13 Thread Hani Benhabiles
Convert object_add and object_del commands to use the new callback.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  2 ++
 hmp.h   |  3 +++
 monitor.c   | 19 +--
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 6bf4797..1b382b6 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1254,6 +1254,7 @@ ETEXI
 .params = "[qom-type=]type,id=str[,prop=value][,...]",
 .help   = "create QOM object",
 .mhandler.cmd = hmp_object_add,
+.command_completion = object_add_completion,
 },
 
 STEXI
@@ -1268,6 +1269,7 @@ ETEXI
 .params = "id",
 .help   = "destroy QOM object",
 .mhandler.cmd = hmp_object_del,
+.command_completion = object_del_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index ed58f0e..2f2c059 100644
--- a/hmp.h
+++ b/hmp.h
@@ -15,6 +15,7 @@
 #define HMP_H
 
 #include "qemu-common.h"
+#include "qemu/readline.h"
 #include "qapi-types.h"
 #include "qapi/qmp/qdict.h"
 
@@ -92,5 +93,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict);
 void hmp_cpu_add(Monitor *mon, const QDict *qdict);
 void hmp_object_add(Monitor *mon, const QDict *qdict);
 void hmp_object_del(Monitor *mon, const QDict *qdict);
+void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 342e83b..566a83f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -137,6 +137,7 @@ typedef struct mon_cmd_t {
  * used, and mhandler of 1st level plays the role of help function.
  */
 struct mon_cmd_t *sub_table;
+void (*command_completion)(ReadLineState *rs, int nb_args, const char 
*str);
 } mon_cmd_t;
 
 /* file descriptors passed via SCM_RIGHTS */
@@ -4298,11 +4299,15 @@ static void device_add_completion(ReadLineState *rs, 
const char *str)
 g_slist_free(list);
 }
 
-static void object_add_completion(ReadLineState *rs, const char *str)
+void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 GSList *list, *elt;
 size_t len;
 
+if (nb_args != 2) {
+return;
+}
+
 len = strlen(str);
 readline_set_completion_index(rs, len);
 list = elt = object_class_get_list(TYPE_USER_CREATABLE, false);
@@ -4337,11 +4342,14 @@ static void device_del_completion(ReadLineState *rs, 
BusState *bus,
 }
 }
 
-static void object_del_completion(ReadLineState *rs, const char *str)
+void object_del_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 ObjectPropertyInfoList *list, *start;
 size_t len;
 
+if (nb_args != 2) {
+return;
+}
 len = strlen(str);
 readline_set_completion_index(rs, len);
 
@@ -4395,6 +4403,9 @@ static void monitor_find_completion_by_table(Monitor *mon,
 return monitor_find_completion_by_table(mon, cmd->sub_table,
 &args[1], nb_args - 1);
 }
+if (cmd->command_completion) {
+return cmd->command_completion(mon->rs, nb_args, args[nb_args - 
1]);
+}
 
 ptype = next_arg_type(cmd->args_type);
 for(i = 0; i < nb_args - 2; i++) {
@@ -4424,8 +4435,6 @@ static void monitor_find_completion_by_table(Monitor *mon,
 case 'O':
 if (!strcmp(cmd->name, "device_add") && nb_args == 2) {
 device_add_completion(mon->rs, str);
-} else if (!strcmp(cmd->name, "object_add") && nb_args == 2) {
-object_add_completion(mon->rs, str);
 }
 break;
 case 's':
@@ -4445,8 +4454,6 @@ static void monitor_find_completion_by_table(Monitor *mon,
 size_t len = strlen(str);
 readline_set_completion_index(mon->rs, len);
 device_del_completion(mon->rs, sysbus_get_default(), str, len);
-} else if (!strcmp(cmd->name, "object_del") && nb_args == 2) {
-object_del_completion(mon->rs, str);
 }
 break;
 default:
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH v2 00/17] monitor: Completion support for various commands

2014-04-13 Thread Hani Benhabiles
On Fri, Apr 11, 2014 at 01:50:57PM -0400, Luiz Capitulino wrote:
> On Sun, 30 Mar 2014 11:58:22 +0100
> Hani Benhabiles  wrote:
> 
> > This patch series adds a new callback to mon_cmd_t which will make adding
> > completion support for more commands cleaner.
> > 
> > It then adds full or partial arguments completion for multiple hmp commands.
> 
> I was half-way through this series when something occurred to me: what
> about merging only the existing completions first? I think that that can
> be merged faster because it won't require other people's reviews and
> discussions on new completions won't hold the entire series.
> 
> If you agree, please repost it and I'll try to review it quicker.
> 

Ok, no problem. Will resend shortly.
> > 
> > Changes since v1:
> >  * Splitting patch 1/7 to 1/17, 2/17 and 3/17.
> >  * Changed command_completion's first argument from Monitor to 
> > ReadLineState.
> >  * Added new commands completions (10/17 to 17/17)
> > 
> > 
> > Hani Benhabiles (17):
> >   monitor: Fix drive_del id argument type completion.
> >   monitor: Add command_completion callback to mon_cmd_t.
> >   monitor: Add device_add and device_del completion.
> >   monitor: Add chardev-remove id argument completion.
> >   monitor: Add chardev-add backend argument completion.
> >   monitor: Add cpu index argument completion.
> >   monitor: Add set_link arguments completion.
> >   monitor: Add netdev_add type argument completion.
> >   monitor: Add netdev_del id argument completion.
> >   monitor: Add ringbuf_write and ringbuf_read argument completion.
> >   monitor: Add watchdog_action argument completion.
> >   monitor: Add migrate_set_capability completion.
> >   monitor: Add host_net_add device argument completion.
> >   readline: Make completion strings always unique.
> >   monitor: Add host_net_remove arguments completion.
> >   monitor: Add mouse_set index argument completion.
> >   monitor: Add delvm and loadvm argument completion.
> > 
> >  hmp-commands.hx   |  25 +++-
> >  hmp.h |  23 +++
> >  include/sysemu/char.h |   3 +-
> >  monitor.c | 397 
> > +++---
> >  net/net.c |   2 +-
> >  qemu-char.c   |   2 +-
> >  util/readline.c   |   6 +
> >  7 files changed, 432 insertions(+), 26 deletions(-)
> > 
> 



[Qemu-devel] [PATCH] net: Report error when device / hub combo is not found.

2014-03-31 Thread Hani Benhabiles
Also convert nearby monitor_printf() call to error_report().

Signed-off-by: Hani Benhabiles 
---
 net/net.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/net.c b/net/net.c
index e3ef1e4..d319f49 100644
--- a/net/net.c
+++ b/net/net.c
@@ -952,10 +952,12 @@ void net_host_device_remove(Monitor *mon, const QDict 
*qdict)
 
 nc = net_hub_find_client_by_name(vlan_id, device);
 if (!nc) {
+error_report("Host network device '%s' on hub '%d' not found",
+ device, vlan_id);
 return;
 }
 if (!net_host_check_device(nc->model)) {
-monitor_printf(mon, "invalid host network device %s\n", device);
+error_report("invalid host network device '%s'", device);
 return;
 }
 qemu_del_net_client(nc);
-- 
1.8.3.2




Re: [Qemu-devel] [PATCH] input: mouse_set should check input device type.

2014-03-31 Thread Hani Benhabiles
On Mon, Mar 31, 2014 at 02:45:49PM +0200, Markus Armbruster wrote:
> Gerd Hoffmann  writes:
> 
> >> +if (!(s->handler->mask & (INPUT_EVENT_MASK_REL |
> >> +  INPUT_EVENT_MASK_ABS))) {
> >> +monitor_printf(mon, "Input device '%s' is not a mouse",
> >> +   s->handler->name);
> >
> > That should be error_report (I think, Markus?).
> 
> Yes, please.  Same for the "Mouse at given index not found\n" message
> further down.  Note that error_report() does *not* want \n.

Ok, thanks.

I just followed the other monitor_printf() usage for consistency. v2 sent.

> 
> >
> > Otherwise the patch is fine.
> >
> > cheers,
> >   Gerd



[Qemu-devel] [PATCH v2] input: mouse_set should check input device type.

2014-03-31 Thread Hani Benhabiles
Otherwise, the index of an input device like a usb-kbd is silently accepted.

(qemu) info mice
  Mouse #2: QEMU PS/2 Mouse
* Mouse #3: QEMU HID Mouse
(qemu) mouse_set 1
(qemu) info mice
  Mouse #2: QEMU PS/2 Mouse
* Mouse #3: QEMU HID Mouse

Also replace monitor_printf() call in do_mouse_set() with error_report() and
adjust error message.

Signed-off-by: Hani Benhabiles 
---

 ui/input.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/ui/input.c b/ui/input.c
index 2761911..6e6a924 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -342,15 +342,21 @@ void do_mouse_set(Monitor *mon, const QDict *qdict)
 int found = 0;
 
 QTAILQ_FOREACH(s, &handlers, node) {
-if (s->id == index) {
-found = 1;
-qemu_input_handler_activate(s);
-break;
+if (s->id != index) {
+continue;
 }
+if (!(s->handler->mask & (INPUT_EVENT_MASK_REL |
+  INPUT_EVENT_MASK_ABS))) {
+error_report("Input device '%s' is not a mouse", s->handler->name);
+return;
+}
+found = 1;
+qemu_input_handler_activate(s);
+break;
 }
 
 if (!found) {
-monitor_printf(mon, "Mouse at given index not found\n");
+error_report("Mouse at index '%d' not found", index);
 }
 
 qemu_input_check_mode_change();
-- 
1.8.3.2




[Qemu-devel] [PATCH] input: mouse_set should check input device type.

2014-03-30 Thread Hani Benhabiles
Otherwise, the index of an input device like a usb-kbd is silently accepted.

(qemu) info mice
  Mouse #2: QEMU PS/2 Mouse
* Mouse #3: QEMU HID Mouse
(qemu) mouse_set 1
(qemu) info mice
  Mouse #2: QEMU PS/2 Mouse
* Mouse #3: QEMU HID Mouse

Signed-off-by: Hani Benhabiles 
---
 ui/input.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/ui/input.c b/ui/input.c
index 2761911..013de95 100644
--- a/ui/input.c
+++ b/ui/input.c
@@ -342,11 +342,18 @@ void do_mouse_set(Monitor *mon, const QDict *qdict)
 int found = 0;
 
 QTAILQ_FOREACH(s, &handlers, node) {
-if (s->id == index) {
-found = 1;
-qemu_input_handler_activate(s);
-break;
+if (s->id != index) {
+continue;
 }
+if (!(s->handler->mask & (INPUT_EVENT_MASK_REL |
+  INPUT_EVENT_MASK_ABS))) {
+monitor_printf(mon, "Input device '%s' is not a mouse",
+   s->handler->name);
+return;
+}
+found = 1;
+qemu_input_handler_activate(s);
+break;
 }
 
 if (!found) {
-- 
1.8.3.2




[Qemu-devel] [PATCH v2 03/17] monitor: Add device_add and device_del completion.

2014-03-30 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  2 ++
 hmp.h   |  2 ++
 monitor.c   | 34 +-
 3 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 1b382b6..4c4d261 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -658,6 +658,7 @@ ETEXI
 .help   = "add device, like -device on the command line",
 .user_print = monitor_user_noop,
 .mhandler.cmd_new = do_device_add,
+.command_completion = device_add_completion,
 },
 
 STEXI
@@ -673,6 +674,7 @@ ETEXI
 .params = "device",
 .help   = "remove device",
 .mhandler.cmd = hmp_device_del,
+.command_completion = device_del_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index 2f2c059..20ef454 100644
--- a/hmp.h
+++ b/hmp.h
@@ -95,5 +95,7 @@ void hmp_object_add(Monitor *mon, const QDict *qdict);
 void hmp_object_del(Monitor *mon, const QDict *qdict);
 void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
+void device_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void device_del_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 566a83f..710ba25 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4278,11 +4278,15 @@ static const char *next_arg_type(const char *typestr)
 return (p != NULL ? ++p : typestr);
 }
 
-static void device_add_completion(ReadLineState *rs, const char *str)
+void device_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 GSList *list, *elt;
 size_t len;
 
+if (nb_args != 2) {
+return;
+}
+
 len = strlen(str);
 readline_set_completion_index(rs, len);
 list = elt = object_class_get_list(TYPE_DEVICE, false);
@@ -4323,8 +4327,8 @@ void object_add_completion(ReadLineState *rs, int 
nb_args, const char *str)
 g_slist_free(list);
 }
 
-static void device_del_completion(ReadLineState *rs, BusState *bus,
-  const char *str, size_t len)
+static void device_del_bus_completion(ReadLineState *rs,  BusState *bus,
+  const char *str, size_t len)
 {
 BusChild *kid;
 
@@ -4337,11 +4341,24 @@ static void device_del_completion(ReadLineState *rs, 
BusState *bus,
 }
 
 QLIST_FOREACH(dev_child, &dev->child_bus, sibling) {
-device_del_completion(rs, dev_child, str, len);
+device_del_bus_completion(rs, dev_child, str, len);
 }
 }
 }
 
+void device_del_completion(ReadLineState *rs, int nb_args, const char *str)
+{
+size_t len;
+
+if (nb_args != 2) {
+return;
+}
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+device_del_bus_completion(rs, sysbus_get_default(), str, len);
+}
+
 void object_del_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 ObjectPropertyInfoList *list, *start;
@@ -4432,11 +4449,6 @@ static void monitor_find_completion_by_table(Monitor 
*mon,
 readline_set_completion_index(mon->rs, strlen(str));
 bdrv_iterate(block_completion_it, &mbs);
 break;
-case 'O':
-if (!strcmp(cmd->name, "device_add") && nb_args == 2) {
-device_add_completion(mon->rs, str);
-}
-break;
 case 's':
 case 'S':
 if (!strcmp(cmd->name, "sendkey")) {
@@ -4450,10 +4462,6 @@ static void monitor_find_completion_by_table(Monitor 
*mon,
 } else if (!strcmp(cmd->name, "help|?")) {
 monitor_find_completion_by_table(mon, cmd_table,
  &args[1], nb_args - 1);
-} else if (!strcmp(cmd->name, "device_del") && nb_args == 2) {
-size_t len = strlen(str);
-readline_set_completion_index(mon->rs, len);
-device_del_completion(mon->rs, sysbus_get_default(), str, len);
 }
 break;
 default:
-- 
1.8.3.2




[Qemu-devel] [PATCH v2 02/17] monitor: Add command_completion callback to mon_cmd_t.

2014-03-30 Thread Hani Benhabiles
Convert object_add and object_del commands to use the new callback.

Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  2 ++
 hmp.h   |  3 +++
 monitor.c   | 19 +--
 3 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 6bf4797..1b382b6 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1254,6 +1254,7 @@ ETEXI
 .params = "[qom-type=]type,id=str[,prop=value][,...]",
 .help   = "create QOM object",
 .mhandler.cmd = hmp_object_add,
+.command_completion = object_add_completion,
 },
 
 STEXI
@@ -1268,6 +1269,7 @@ ETEXI
 .params = "id",
 .help   = "destroy QOM object",
 .mhandler.cmd = hmp_object_del,
+.command_completion = object_del_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index ed58f0e..2f2c059 100644
--- a/hmp.h
+++ b/hmp.h
@@ -15,6 +15,7 @@
 #define HMP_H
 
 #include "qemu-common.h"
+#include "qemu/readline.h"
 #include "qapi-types.h"
 #include "qapi/qmp/qdict.h"
 
@@ -92,5 +93,7 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict);
 void hmp_cpu_add(Monitor *mon, const QDict *qdict);
 void hmp_object_add(Monitor *mon, const QDict *qdict);
 void hmp_object_del(Monitor *mon, const QDict *qdict);
+void object_add_completion(ReadLineState *rs, int nb_args, const char *str);
+void object_del_completion(ReadLineState *rs, int nb_args, const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index 342e83b..566a83f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -137,6 +137,7 @@ typedef struct mon_cmd_t {
  * used, and mhandler of 1st level plays the role of help function.
  */
 struct mon_cmd_t *sub_table;
+void (*command_completion)(ReadLineState *rs, int nb_args, const char 
*str);
 } mon_cmd_t;
 
 /* file descriptors passed via SCM_RIGHTS */
@@ -4298,11 +4299,15 @@ static void device_add_completion(ReadLineState *rs, 
const char *str)
 g_slist_free(list);
 }
 
-static void object_add_completion(ReadLineState *rs, const char *str)
+void object_add_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 GSList *list, *elt;
 size_t len;
 
+if (nb_args != 2) {
+return;
+}
+
 len = strlen(str);
 readline_set_completion_index(rs, len);
 list = elt = object_class_get_list(TYPE_USER_CREATABLE, false);
@@ -4337,11 +4342,14 @@ static void device_del_completion(ReadLineState *rs, 
BusState *bus,
 }
 }
 
-static void object_del_completion(ReadLineState *rs, const char *str)
+void object_del_completion(ReadLineState *rs, int nb_args, const char *str)
 {
 ObjectPropertyInfoList *list, *start;
 size_t len;
 
+if (nb_args != 2) {
+return;
+}
 len = strlen(str);
 readline_set_completion_index(rs, len);
 
@@ -4395,6 +4403,9 @@ static void monitor_find_completion_by_table(Monitor *mon,
 return monitor_find_completion_by_table(mon, cmd->sub_table,
 &args[1], nb_args - 1);
 }
+if (cmd->command_completion) {
+return cmd->command_completion(mon->rs, nb_args, args[nb_args - 
1]);
+}
 
 ptype = next_arg_type(cmd->args_type);
 for(i = 0; i < nb_args - 2; i++) {
@@ -4424,8 +4435,6 @@ static void monitor_find_completion_by_table(Monitor *mon,
 case 'O':
 if (!strcmp(cmd->name, "device_add") && nb_args == 2) {
 device_add_completion(mon->rs, str);
-} else if (!strcmp(cmd->name, "object_add") && nb_args == 2) {
-object_add_completion(mon->rs, str);
 }
 break;
 case 's':
@@ -4445,8 +4454,6 @@ static void monitor_find_completion_by_table(Monitor *mon,
 size_t len = strlen(str);
 readline_set_completion_index(mon->rs, len);
 device_del_completion(mon->rs, sysbus_get_default(), str, len);
-} else if (!strcmp(cmd->name, "object_del") && nb_args == 2) {
-object_del_completion(mon->rs, str);
 }
 break;
 default:
-- 
1.8.3.2




[Qemu-devel] [PATCH v2 12/17] monitor: Add migrate_set_capability completion.

2014-03-30 Thread Hani Benhabiles
Signed-off-by: Hani Benhabiles 
---
 hmp-commands.hx |  1 +
 hmp.h   |  2 ++
 monitor.c   | 21 +
 3 files changed, 24 insertions(+)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 669a845..8c674ba 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -975,6 +975,7 @@ ETEXI
 .params = "capability state",
 .help   = "Enable/Disable the usage of a capability for migration",
 .mhandler.cmd = hmp_migrate_set_capability,
+.command_completion = migrate_set_capability_completion,
 },
 
 STEXI
diff --git a/hmp.h b/hmp.h
index eca50b4..3570530 100644
--- a/hmp.h
+++ b/hmp.h
@@ -107,5 +107,7 @@ void ringbuf_write_completion(ReadLineState *rs, int 
nb_args, const char *str);
 void ringbuf_read_completion(ReadLineState *rs, int nb_args, const char *str);
 void watchdog_action_completion(ReadLineState *rs, int nb_args,
 const char *str);
+void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
+   const char *str);
 
 #endif
diff --git a/monitor.c b/monitor.c
index cb1fb7c..2974a66 100644
--- a/monitor.c
+++ b/monitor.c
@@ -4584,6 +4584,27 @@ void watchdog_action_completion(ReadLineState *rs, int 
nb_args, const char *str)
 add_completion_option(rs, str, "none");
 }
 
+void migrate_set_capability_completion(ReadLineState *rs, int nb_args,
+   const char *str)
+{
+size_t len;
+
+len = strlen(str);
+readline_set_completion_index(rs, len);
+if (nb_args == 2) {
+int i;
+for (i = 0; i < MIGRATION_CAPABILITY_MAX; i++) {
+const char *name = MigrationCapability_lookup[i];
+if (!strncmp(str, name, len)) {
+readline_add_completion(rs, name);
+}
+}
+} else if (nb_args == 3) {
+add_completion_option(rs, str, "on");
+add_completion_option(rs, str, "off");
+}
+}
+
 static void monitor_find_completion_by_table(Monitor *mon,
  const mon_cmd_t *cmd_table,
  char **args,
-- 
1.8.3.2




  1   2   >