qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs
@ 2019-06-20 18:47 Dr. David Alan Gilbert (git)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 1/5] net/announce: Allow optional list of interfaces Dr. David Alan Gilbert (git)
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-06-20 18:47 UTC (permalink / raw)
  To: qemu-devel, jasowang, eblake, armbru, laine

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Up until now, the 'announce' feature has mainly been used
for migration where we announce on all interfaces.  Another
use for 'announce' is in cases of network topology changes.

Since network topology changes may only affect a subset
of the interfaces, we add an 'interface list' to announce
to restrict the announcment to the interfaces we're interested
in.

Multiple topology changes might happen in close succession,
so we allow multiple timers, each with their own parameters
(including the interface list).

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>

v5
  Minor review fixes [Jason] 

Dr. David Alan Gilbert (5):
  net/announce: Allow optional list of interfaces
  net/announce: Add HMP optional interface list
  net/announce: Add optional ID
  net/announce: Add HMP optional ID
  net/announce: Expand test for stopping self announce

 hmp-commands.hx         |  7 +++-
 hw/net/virtio-net.c     |  4 +-
 include/net/announce.h  |  8 +++-
 monitor/hmp-cmds.c      | 41 ++++++++++++++++++-
 net/announce.c          | 89 +++++++++++++++++++++++++++++++++++------
 net/trace-events        |  3 +-
 qapi/net.json           | 16 ++++++--
 tests/virtio-net-test.c | 57 ++++++++++++++++++++++++--
 8 files changed, 198 insertions(+), 27 deletions(-)

-- 
2.21.0



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 1/5] net/announce: Allow optional list of interfaces
  2019-06-20 18:47 [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Dr. David Alan Gilbert (git)
@ 2019-06-20 18:47 ` Dr. David Alan Gilbert (git)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 2/5] net/announce: Add HMP optional interface list Dr. David Alan Gilbert (git)
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-06-20 18:47 UTC (permalink / raw)
  To: qemu-devel, jasowang, eblake, armbru, laine

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Allow the caller to restrict the set of interfaces that announces are
sent on.  The default is still to send on all interfaces.

e.g.

  { "execute": "announce-self", "arguments": { "initial": 50, "max": 550, "rounds": 5, "step": 50, "interfaces": ["vn2", "vn1"] } }

This doesn't affect the behaviour of migraiton announcments.

Note: There's still only one timer for the qmp command, so that
performing an 'announce-self' on one list of interfaces followed
by another 'announce-self' on another list will stop the announces
on the existing set.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 include/net/announce.h |  2 +-
 net/announce.c         | 39 ++++++++++++++++++++++++++++++++-------
 net/trace-events       |  2 +-
 qapi/net.json          | 11 ++++++++---
 4 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/include/net/announce.h b/include/net/announce.h
index 04a035f679..773470428b 100644
--- a/include/net/announce.h
+++ b/include/net/announce.h
@@ -22,7 +22,7 @@ struct AnnounceTimer {
 /* Returns: update the timer to the next time point */
 int64_t qemu_announce_timer_step(AnnounceTimer *timer);
 
-/* Delete the underlying timer */
+/* Delete the underlying timer and other data */
 void qemu_announce_timer_del(AnnounceTimer *timer);
 
 /*
diff --git a/net/announce.c b/net/announce.c
index 91e9a6e267..1ce42b571d 100644
--- a/net/announce.c
+++ b/net/announce.c
@@ -38,6 +38,8 @@ void qemu_announce_timer_del(AnnounceTimer *timer)
         timer_free(timer->tm);
         timer->tm = NULL;
     }
+    qapi_free_strList(timer->params.interfaces);
+    timer->params.interfaces = NULL;
 }
 
 /*
@@ -96,24 +98,47 @@ static int announce_self_create(uint8_t *buf,
 
 static void qemu_announce_self_iter(NICState *nic, void *opaque)
 {
+    AnnounceTimer *timer = opaque;
     uint8_t buf[60];
     int len;
+    bool skip;
+
+    if (timer->params.has_interfaces) {
+        strList *entry = timer->params.interfaces;
+        /* Skip unless we find our name in the requested list */
+        skip = true;
+
+        while (entry) {
+            if (!strcmp(entry->value, nic->ncs->name)) {
+                /* Found us */
+                skip = false;
+                break;
+            }
+            entry = entry->next;
+        }
+    } else {
+        skip = false;
+    }
+
+    trace_qemu_announce_self_iter(nic->ncs->name,
+                                  qemu_ether_ntoa(&nic->conf->macaddr), skip);
 
-    trace_qemu_announce_self_iter(qemu_ether_ntoa(&nic->conf->macaddr));
-    len = announce_self_create(buf, nic->conf->macaddr.a);
+    if (!skip) {
+        len = announce_self_create(buf, nic->conf->macaddr.a);
 
-    qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
+        qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
 
-    /* if the NIC provides it's own announcement support, use it as well */
-    if (nic->ncs->info->announce) {
-        nic->ncs->info->announce(nic->ncs);
+        /* if the NIC provides it's own announcement support, use it as well */
+        if (nic->ncs->info->announce) {
+            nic->ncs->info->announce(nic->ncs);
+        }
     }
 }
 static void qemu_announce_self_once(void *opaque)
 {
     AnnounceTimer *timer = (AnnounceTimer *)opaque;
 
-    qemu_foreach_nic(qemu_announce_self_iter, NULL);
+    qemu_foreach_nic(qemu_announce_self_iter, timer);
 
     if (--timer->round) {
         qemu_announce_timer_step(timer);
diff --git a/net/trace-events b/net/trace-events
index a7937f3f3a..875ef2a0f3 100644
--- a/net/trace-events
+++ b/net/trace-events
@@ -1,7 +1,7 @@
 # See docs/devel/tracing.txt for syntax documentation.
 
 # announce.c
-qemu_announce_self_iter(const char *mac) "%s"
+qemu_announce_self_iter(const char *name, const char *mac, int skip) "%s:%s skip: %d"
 
 # vhost-user.c
 vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
diff --git a/qapi/net.json b/qapi/net.json
index 5f7bff1637..6f2cd4f530 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -699,6 +699,9 @@
 #
 # @step: Delay increase (in ms) after each self-announcement attempt
 #
+# @interfaces: An optional list of interface names, which restricts the
+#        announcement to the listed interfaces. (Since 4.1)
+#
 # Since: 4.0
 ##
 
@@ -706,7 +709,8 @@
   'data': { 'initial': 'int',
             'max': 'int',
             'rounds': 'int',
-            'step': 'int' } }
+            'step': 'int',
+            '*interfaces': ['str'] } }
 
 ##
 # @announce-self:
@@ -718,9 +722,10 @@
 #
 # Example:
 #
-# -> { "execute": "announce-self"
+# -> { "execute": "announce-self",
 #      "arguments": {
-#          "initial": 50, "max": 550, "rounds": 10, "step": 50 } }
+#          "initial": 50, "max": 550, "rounds": 10, "step": 50,
+#          "interfaces": ["vn2", "vn3"] } }
 # <- { "return": {} }
 #
 # Since: 4.0
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 2/5] net/announce: Add HMP optional interface list
  2019-06-20 18:47 [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Dr. David Alan Gilbert (git)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 1/5] net/announce: Allow optional list of interfaces Dr. David Alan Gilbert (git)
@ 2019-06-20 18:47 ` Dr. David Alan Gilbert (git)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 3/5] net/announce: Add optional ID Dr. David Alan Gilbert (git)
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-06-20 18:47 UTC (permalink / raw)
  To: qemu-devel, jasowang, eblake, armbru, laine

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Add the optional interface list to the HMP command.

i.e.

   All interfaces
        announce_self

   Just the named interfaces:
        announce_self vn1,vn2

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 hmp-commands.hx    |  6 ++++--
 monitor/hmp-cmds.c | 38 +++++++++++++++++++++++++++++++++++++-
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 810b7b9283..c2a2df9708 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -955,8 +955,8 @@ ETEXI
 
     {
         .name       = "announce_self",
-        .args_type  = "",
-        .params     = "",
+        .args_type  = "interfaces:s?",
+        .params     = "[interfaces]",
         .help       = "Trigger GARP/RARP announcements",
         .cmd        = hmp_announce_self,
     },
@@ -967,6 +967,8 @@ STEXI
 Trigger a round of GARP/RARP broadcasts; this is useful for explicitly updating the
 network infrastructure after a reconfiguration or some forms of migration.
 The timings of the round are set by the migration announce parameters.
+An optional comma separated @var{interfaces} list restricts the announce to the
+named set of interfaces.
 ETEXI
 
     {
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index a7ae586723..a3d34b12fe 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -27,6 +27,7 @@
 #include "monitor/monitor-internal.h"
 #include "monitor/qdev.h"
 #include "qapi/error.h"
+#include "qapi/clone-visitor.h"
 #include "qapi/opts-visitor.h"
 #include "qapi/qapi-builtin-visit.h"
 #include "qapi/qapi-commands-block.h"
@@ -38,6 +39,7 @@
 #include "qapi/qapi-commands-run-state.h"
 #include "qapi/qapi-commands-tpm.h"
 #include "qapi/qapi-commands-ui.h"
+#include "qapi/qapi-visit-net.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/string-input-visitor.h"
@@ -67,6 +69,32 @@ static void hmp_handle_error(Monitor *mon, Error **errp)
     }
 }
 
+/*
+ * Produce a strList from a comma separated list.
+ * A NULL or empty input string return NULL.
+ */
+static strList *strList_from_comma_list(const char *in)
+{
+    strList *res = NULL;
+    strList **hook = &res;
+
+    while (in && in[0]) {
+        char *comma = strchr(in, ',');
+        *hook = g_new0(strList, 1);
+
+        if (comma) {
+            (*hook)->value = g_strndup(in, comma - in);
+            in = comma + 1; /* skip the , */
+        } else {
+            (*hook)->value = g_strdup(in);
+            in = NULL;
+        }
+        hook = &(*hook)->next;
+    }
+
+    return res;
+}
+
 void hmp_info_name(Monitor *mon, const QDict *qdict)
 {
     NameInfo *info;
@@ -1640,7 +1668,15 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
 
 void hmp_announce_self(Monitor *mon, const QDict *qdict)
 {
-    qmp_announce_self(migrate_announce_params(), NULL);
+    const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
+    AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
+                                            migrate_announce_params());
+
+    qapi_free_strList(params->interfaces);
+    params->interfaces = strList_from_comma_list(interfaces_str);
+    params->has_interfaces = params->interfaces != NULL;
+    qmp_announce_self(params, NULL);
+    qapi_free_AnnounceParameters(params);
 }
 
 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 3/5] net/announce: Add optional ID
  2019-06-20 18:47 [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Dr. David Alan Gilbert (git)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 1/5] net/announce: Allow optional list of interfaces Dr. David Alan Gilbert (git)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 2/5] net/announce: Add HMP optional interface list Dr. David Alan Gilbert (git)
@ 2019-06-20 18:47 ` Dr. David Alan Gilbert (git)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 4/5] net/announce: Add HMP " Dr. David Alan Gilbert (git)
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-06-20 18:47 UTC (permalink / raw)
  To: qemu-devel, jasowang, eblake, armbru, laine

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Previously there was a single instance of the timer used by
monitor triggered announces, that's OK, but when combined with the
previous change that lets you have announces for subsets of interfaces
it's a bit restrictive if you want to do different things to different
interfaces.

Add an 'id' field to the announce, and maintain a list of the
timers based on id.

This allows you to for example:
    a) Start an announce going on interface eth0 for a long time
    b) Start an announce going on interface eth1 for a long time
    c) Kill the announce on eth0 while leaving eth1 going.

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 hw/net/virtio-net.c    |  4 ++--
 include/net/announce.h |  8 +++++--
 net/announce.c         | 52 ++++++++++++++++++++++++++++++++++++------
 net/trace-events       |  3 ++-
 qapi/net.json          |  9 ++++++--
 5 files changed, 62 insertions(+), 14 deletions(-)

diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index c3f5fccfd1..b9e1cd71cf 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -2360,7 +2360,7 @@ static int virtio_net_post_load_device(void *opaque, int version_id)
             timer_mod(n->announce_timer.tm,
                       qemu_clock_get_ms(n->announce_timer.type));
         } else {
-            qemu_announce_timer_del(&n->announce_timer);
+            qemu_announce_timer_del(&n->announce_timer, false);
         }
     }
 
@@ -2784,7 +2784,7 @@ static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
         virtio_net_del_queue(n, i);
     }
 
-    qemu_announce_timer_del(&n->announce_timer);
+    qemu_announce_timer_del(&n->announce_timer, false);
     g_free(n->vqs);
     qemu_del_nic(n->nic);
     virtio_net_rsc_cleanup(n);
diff --git a/include/net/announce.h b/include/net/announce.h
index 773470428b..3d90c83c23 100644
--- a/include/net/announce.h
+++ b/include/net/announce.h
@@ -22,8 +22,12 @@ struct AnnounceTimer {
 /* Returns: update the timer to the next time point */
 int64_t qemu_announce_timer_step(AnnounceTimer *timer);
 
-/* Delete the underlying timer and other data */
-void qemu_announce_timer_del(AnnounceTimer *timer);
+/*
+ * Delete the underlying timer and other data
+ * If 'free_named' true and the timer is a named timer, then remove
+ * it from the list of named timers and free the AnnounceTimer itself.
+ */
+void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named);
 
 /*
  * Under BQL/main thread
diff --git a/net/announce.c b/net/announce.c
index 1ce42b571d..db90d3bd4b 100644
--- a/net/announce.c
+++ b/net/announce.c
@@ -15,6 +15,8 @@
 #include "qapi/qapi-commands-net.h"
 #include "trace.h"
 
+static GData *named_timers;
+
 int64_t qemu_announce_timer_step(AnnounceTimer *timer)
 {
     int64_t step;
@@ -31,8 +33,13 @@ int64_t qemu_announce_timer_step(AnnounceTimer *timer)
     return step;
 }
 
-void qemu_announce_timer_del(AnnounceTimer *timer)
+/*
+ * If 'free_named' is true, then remove the timer from the list
+ * and free the timer itself.
+ */
+void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named)
 {
+    bool free_timer = false;
     if (timer->tm) {
         timer_del(timer->tm);
         timer_free(timer->tm);
@@ -40,6 +47,24 @@ void qemu_announce_timer_del(AnnounceTimer *timer)
     }
     qapi_free_strList(timer->params.interfaces);
     timer->params.interfaces = NULL;
+    if (free_named && timer->params.has_id) {
+        AnnounceTimer *list_timer;
+        /*
+         * Sanity check: There should only be one timer on the list with
+         * the id.
+         */
+        list_timer = g_datalist_get_data(&named_timers, timer->params.id);
+        assert(timer == list_timer);
+        free_timer = true;
+        g_datalist_remove_data(&named_timers, timer->params.id);
+    }
+    trace_qemu_announce_timer_del(free_named, free_timer, timer->params.id);
+    g_free(timer->params.id);
+    timer->params.id = NULL;
+
+    if (free_timer) {
+        g_free(timer);
+    }
 }
 
 /*
@@ -56,7 +81,7 @@ void qemu_announce_timer_reset(AnnounceTimer *timer,
      * We're under the BQL, so the current timer can't
      * be firing, so we should be able to delete it.
      */
-    qemu_announce_timer_del(timer);
+    qemu_announce_timer_del(timer, false);
 
     QAPI_CLONE_MEMBERS(AnnounceParameters, &timer->params, params);
     timer->round = params->rounds;
@@ -120,7 +145,8 @@ static void qemu_announce_self_iter(NICState *nic, void *opaque)
         skip = false;
     }
 
-    trace_qemu_announce_self_iter(nic->ncs->name,
+    trace_qemu_announce_self_iter(timer->params.has_id ? timer->params.id : "_",
+                                  nic->ncs->name,
                                   qemu_ether_ntoa(&nic->conf->macaddr), skip);
 
     if (!skip) {
@@ -143,7 +169,7 @@ static void qemu_announce_self_once(void *opaque)
     if (--timer->round) {
         qemu_announce_timer_step(timer);
     } else {
-        qemu_announce_timer_del(timer);
+        qemu_announce_timer_del(timer, true);
     }
 }
 
@@ -154,12 +180,24 @@ void qemu_announce_self(AnnounceTimer *timer, AnnounceParameters *params)
     if (params->rounds) {
         qemu_announce_self_once(timer);
     } else {
-        qemu_announce_timer_del(timer);
+        qemu_announce_timer_del(timer, true);
     }
 }
 
 void qmp_announce_self(AnnounceParameters *params, Error **errp)
 {
-    static AnnounceTimer announce_timer;
-    qemu_announce_self(&announce_timer, params);
+    AnnounceTimer *named_timer;
+    if (!params->has_id) {
+        params->id = g_strdup("");
+        params->has_id = true;
+    }
+
+    named_timer = g_datalist_get_data(&named_timers, params->id);
+
+    if (!named_timer) {
+        named_timer = g_new0(AnnounceTimer, 1);
+        g_datalist_set_data(&named_timers, params->id, named_timer);
+    }
+
+    qemu_announce_self(named_timer, params);
 }
diff --git a/net/trace-events b/net/trace-events
index 875ef2a0f3..ac57056497 100644
--- a/net/trace-events
+++ b/net/trace-events
@@ -1,7 +1,8 @@
 # See docs/devel/tracing.txt for syntax documentation.
 
 # announce.c
-qemu_announce_self_iter(const char *name, const char *mac, int skip) "%s:%s skip: %d"
+qemu_announce_self_iter(const char *id, const char *name, const char *mac, int skip) "%s:%s:%s skip: %d"
+qemu_announce_timer_del(bool free_named, bool free_timer, char *id) "free named: %d free timer: %d id: %s"
 
 # vhost-user.c
 vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
diff --git a/qapi/net.json b/qapi/net.json
index 6f2cd4f530..728990f4fb 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -702,6 +702,10 @@
 # @interfaces: An optional list of interface names, which restricts the
 #        announcement to the listed interfaces. (Since 4.1)
 #
+# @id: A name to be used to identify an instance of announce-timers
+#        and to allow it to modified later.  Not for use as
+#        part of the migration parameters. (Since 4.1)
+#
 # Since: 4.0
 ##
 
@@ -710,7 +714,8 @@
             'max': 'int',
             'rounds': 'int',
             'step': 'int',
-            '*interfaces': ['str'] } }
+            '*interfaces': ['str'],
+            '*id' : 'str' } }
 
 ##
 # @announce-self:
@@ -725,7 +730,7 @@
 # -> { "execute": "announce-self",
 #      "arguments": {
 #          "initial": 50, "max": 550, "rounds": 10, "step": 50,
-#          "interfaces": ["vn2", "vn3"] } }
+#          "interfaces": ["vn2", "vn3"], "id": "bob" } }
 # <- { "return": {} }
 #
 # Since: 4.0
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 4/5] net/announce: Add HMP optional ID
  2019-06-20 18:47 [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Dr. David Alan Gilbert (git)
                   ` (2 preceding siblings ...)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 3/5] net/announce: Add optional ID Dr. David Alan Gilbert (git)
@ 2019-06-20 18:47 ` Dr. David Alan Gilbert (git)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 5/5] net/announce: Expand test for stopping self announce Dr. David Alan Gilbert (git)
  2019-06-27  2:07 ` [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Jason Wang
  5 siblings, 0 replies; 7+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-06-20 18:47 UTC (permalink / raw)
  To: qemu-devel, jasowang, eblake, armbru, laine

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Add the optional ID to the HMP command.

e.g.
   # start an announce for a long time on eth1
   migrate_set_parameter announce-rounds 1000
   announce_self "eth1" e1

   # start an announce on eth2
   announce_self "eth2" e2

   # Change e1 to be announcing on eth1 and eth3
   announce_self "eth1,eth3" e1

   # Cancel e1
   migrate_set_parameter announce-rounds 0
   announce_self "" e1

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 hmp-commands.hx    | 7 ++++---
 monitor/hmp-cmds.c | 3 +++
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index c2a2df9708..61d0be29d8 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -955,8 +955,8 @@ ETEXI
 
     {
         .name       = "announce_self",
-        .args_type  = "interfaces:s?",
-        .params     = "[interfaces]",
+        .args_type  = "interfaces:s?,id:s?",
+        .params     = "[interfaces] [id]",
         .help       = "Trigger GARP/RARP announcements",
         .cmd        = hmp_announce_self,
     },
@@ -968,7 +968,8 @@ Trigger a round of GARP/RARP broadcasts; this is useful for explicitly updating
 network infrastructure after a reconfiguration or some forms of migration.
 The timings of the round are set by the migration announce parameters.
 An optional comma separated @var{interfaces} list restricts the announce to the
-named set of interfaces.
+named set of interfaces. An optional @var{id} can be used to start a separate announce
+timer and to change the parameters of it later.
 ETEXI
 
     {
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index a3d34b12fe..96715c7103 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1669,12 +1669,15 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
 void hmp_announce_self(Monitor *mon, const QDict *qdict)
 {
     const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
+    const char *id = qdict_get_try_str(qdict, "id");
     AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
                                             migrate_announce_params());
 
     qapi_free_strList(params->interfaces);
     params->interfaces = strList_from_comma_list(interfaces_str);
     params->has_interfaces = params->interfaces != NULL;
+    params->id = g_strdup(id);
+    params->has_id = !!params->id;
     qmp_announce_self(params, NULL);
     qapi_free_AnnounceParameters(params);
 }
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PATCH v5 5/5] net/announce: Expand test for stopping self announce
  2019-06-20 18:47 [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Dr. David Alan Gilbert (git)
                   ` (3 preceding siblings ...)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 4/5] net/announce: Add HMP " Dr. David Alan Gilbert (git)
@ 2019-06-20 18:47 ` Dr. David Alan Gilbert (git)
  2019-06-27  2:07 ` [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Jason Wang
  5 siblings, 0 replies; 7+ messages in thread
From: Dr. David Alan Gilbert (git) @ 2019-06-20 18:47 UTC (permalink / raw)
  To: qemu-devel, jasowang, eblake, armbru, laine

From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>

Expand self-announce test to check we can stop an announce timer.
We set it up to send 300 packets, but after we receive
the first one we tell it to stop.

We error if:
   a) We receive more than 30 of the packets
   b) We're still receiving packets after a lot longer than the
      30 seconds should have arrived

Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
---
 tests/virtio-net-test.c | 57 ++++++++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 3 deletions(-)

diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
index 663cf7ea7e..7aa9622f30 100644
--- a/tests/virtio-net-test.c
+++ b/tests/virtio-net-test.c
@@ -184,21 +184,72 @@ static void announce_self(void *obj, void *data, QGuestAllocator *t_alloc)
     QDict *rsp;
     int ret;
     uint16_t *proto = (uint16_t *)&buffer[12];
+    size_t total_received = 0;
+    uint64_t start, now, last_rxt, deadline;
 
+    /* Send a set of packets over a few second period */
     rsp = qmp("{ 'execute' : 'announce-self', "
                   " 'arguments': {"
-                      " 'initial': 50, 'max': 550,"
-                      " 'rounds': 10, 'step': 50 } }");
+                      " 'initial': 20, 'max': 100,"
+                      " 'rounds': 300, 'step': 10, 'id': 'bob' } }");
     assert(!qdict_haskey(rsp, "error"));
     qobject_unref(rsp);
 
-    /* Catch the packet and make sure it's a RARP */
+    /* Catch the first packet and make sure it's a RARP */
     ret = qemu_recv(sv[0], &len, sizeof(len), 0);
     g_assert_cmpint(ret, ==,  sizeof(len));
     len = ntohl(len);
 
     ret = qemu_recv(sv[0], buffer, len, 0);
     g_assert_cmpint(*proto, ==, htons(ETH_P_RARP));
+
+    /*
+     * Stop the announcment by settings rounds to 0 on the
+     * existing timer.
+     */
+    rsp = qmp("{ 'execute' : 'announce-self', "
+                  " 'arguments': {"
+                      " 'initial': 20, 'max': 100,"
+                      " 'rounds': 0, 'step': 10, 'id': 'bob' } }");
+    assert(!qdict_haskey(rsp, "error"));
+    qobject_unref(rsp);
+
+    /* Now make sure the packets stop */
+
+    /* Times are in us */
+    start = g_get_monotonic_time();
+    /* 30 packets, max gap 100ms, * 4 for wiggle */
+    deadline = start + 1000 * (100 * 30 * 4);
+    last_rxt = start;
+
+    while (true) {
+        int saved_err;
+        ret = qemu_recv(sv[0], buffer, 60, MSG_DONTWAIT);
+        saved_err = errno;
+        now = g_get_monotonic_time();
+        g_assert_cmpint(now, <, deadline);
+
+        if (ret >= 0) {
+            if (ret) {
+                last_rxt = now;
+            }
+            total_received += ret;
+
+            /* Check it's not spewing loads */
+            g_assert_cmpint(total_received, <, 60 * 30 * 2);
+        } else {
+            g_assert_cmpint(saved_err, ==, EAGAIN);
+
+            /* 400ms, i.e. 4 worst case gaps */
+            if ((now - last_rxt) > (1000 * 100 * 4)) {
+                /* Nothings arrived for a while - must have stopped */
+                break;
+            };
+
+            /* 100ms */
+            g_usleep(1000 * 100);
+        }
+    };
 }
 
 static void virtio_net_test_cleanup(void *sockets)
-- 
2.21.0



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs
  2019-06-20 18:47 [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Dr. David Alan Gilbert (git)
                   ` (4 preceding siblings ...)
  2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 5/5] net/announce: Expand test for stopping self announce Dr. David Alan Gilbert (git)
@ 2019-06-27  2:07 ` Jason Wang
  5 siblings, 0 replies; 7+ messages in thread
From: Jason Wang @ 2019-06-27  2:07 UTC (permalink / raw)
  To: Dr. David Alan Gilbert (git), qemu-devel, eblake, armbru, laine


On 2019/6/21 上午2:47, Dr. David Alan Gilbert (git) wrote:
> From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
>
> Up until now, the 'announce' feature has mainly been used
> for migration where we announce on all interfaces.  Another
> use for 'announce' is in cases of network topology changes.
>
> Since network topology changes may only affect a subset
> of the interfaces, we add an 'interface list' to announce
> to restrict the announcment to the interfaces we're interested
> in.
>
> Multiple topology changes might happen in close succession,
> so we allow multiple timers, each with their own parameters
> (including the interface list).
>
> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
>
> v5
>    Minor review fixes [Jason]
>
> Dr. David Alan Gilbert (5):
>    net/announce: Allow optional list of interfaces
>    net/announce: Add HMP optional interface list
>    net/announce: Add optional ID
>    net/announce: Add HMP optional ID
>    net/announce: Expand test for stopping self announce
>
>   hmp-commands.hx         |  7 +++-
>   hw/net/virtio-net.c     |  4 +-
>   include/net/announce.h  |  8 +++-
>   monitor/hmp-cmds.c      | 41 ++++++++++++++++++-
>   net/announce.c          | 89 +++++++++++++++++++++++++++++++++++------
>   net/trace-events        |  3 +-
>   qapi/net.json           | 16 ++++++--
>   tests/virtio-net-test.c | 57 ++++++++++++++++++++++++--
>   8 files changed, 198 insertions(+), 27 deletions(-)


Applied.

Thanks




^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-06-27  2:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-20 18:47 [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Dr. David Alan Gilbert (git)
2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 1/5] net/announce: Allow optional list of interfaces Dr. David Alan Gilbert (git)
2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 2/5] net/announce: Add HMP optional interface list Dr. David Alan Gilbert (git)
2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 3/5] net/announce: Add optional ID Dr. David Alan Gilbert (git)
2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 4/5] net/announce: Add HMP " Dr. David Alan Gilbert (git)
2019-06-20 18:47 ` [Qemu-devel] [PATCH v5 5/5] net/announce: Expand test for stopping self announce Dr. David Alan Gilbert (git)
2019-06-27  2:07 ` [Qemu-devel] [PATCH v5 0/5] network announce; interface selection & IDs Jason Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).