1
The following changes since commit 7d0e02405fc02a181319b1ab8681d2f72246b7c6:
1
The following changes since commit aa90f1161bb17a4863e16ec2f75104cff0752d4e:
2
2
3
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-patches-pull-request' into staging (2019-07-01 17:40:32 +0100)
3
Merge tag 'migration-20250314-pull-request' of https://gitlab.com/farosas/qemu into staging (2025-03-16 02:45:22 -0400)
4
4
5
are available in the git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/jasowang/qemu.git tags/net-pull-request
7
https://github.com/jasowang/qemu.git tags/net-pull-request
8
8
9
for you to fetch changes up to 0e8818f023616677416840d6ddc880db8de3c967:
9
for you to fetch changes up to b027f55a994af885a7a498a40373a2dcc2d8b15e:
10
10
11
migration/colo.c: Add missed filter notify for Xen COLO. (2019-07-02 10:21:07 +0800)
11
vdpa: Allow vDPA to work on big-endian machine (2025-03-17 13:46:28 +0800)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
-----BEGIN PGP SIGNATURE-----
15
16
iQEzBAABCAAdFiEEIV1G9IJGaJ7HfzVi7wSWWzmNYhEFAmfX5/cACgkQ7wSWWzmN
17
YhFRHQgArp4daHmnfc4r8TNel7fBjeSTpfDGwQcUJbcljKK2ABtylcESAEg6tsAw
18
aBzaZ2PwoTQfDV2s//g/d2uzd3BWH0Iu3qimsyBtx7Um7D4h7NsGB+gTB/7IhcK8
19
1LjMHqDnaeS6fzJ93/umTXuyQLzA3tIFkJBzvxVseLrmv6uBPmAy+PDNe/uZ2jeF
20
2H20jNt/HMc1Yf7sE7NKTBkX+OxuIFkpOGcBtVxiPK1//Wmhw+v+zlQOFjUC+6CD
21
LxiBB0Q0tD7ekfbuF6x2SOnuzLDHgpMzgoGqLIYzeQhBX9TdHLM0LtEHHaMyW1pj
22
7mGPSY4avVSM1sePgtmNJ5Y5r/xTRA==
23
=e7Sc
24
-----END PGP SIGNATURE-----
14
25
15
----------------------------------------------------------------
26
----------------------------------------------------------------
16
Cédric Le Goater (1):
27
Konstantin Shkolnyy (1):
17
ftgmac100: do not link to netdev
28
vdpa: Allow vDPA to work on big-endian machine
18
29
19
Dr. David Alan Gilbert (5):
30
net/vhost-vdpa.c | 13 +++++++++++++
20
net/announce: Allow optional list of interfaces
31
1 file changed, 13 insertions(+)
21
net/announce: Add HMP optional interface list
22
net/announce: Add optional ID
23
net/announce: Add HMP optional ID
24
net/announce: Expand test for stopping self announce
25
26
Markus Armbruster (2):
27
MAINTAINERS: Add qemu-bridge-helper.c to "Network device backends"
28
qemu-bridge-helper: Document known shortcomings
29
30
Stefano Garzarella (4):
31
net: fix assertion failure when ipv6-prefixlen is not a number
32
net: avoid using variable length array in net_client_init()
33
net: use g_strsplit() for parsing host address and port
34
net: remove unused get_str_sep() function
35
36
Zhang Chen (5):
37
COLO-compare: Add new parameter to communicate with remote colo-frame
38
COLO-compare: Add remote notification chardev handler frame
39
COLO-compare: Make the compare_chr_send() can send notification message.
40
COLO-compare: Add colo-compare remote notify support
41
migration/colo.c: Add missed filter notify for Xen COLO.
42
43
MAINTAINERS | 1 +
44
hmp-commands.hx | 7 ++-
45
hw/net/ftgmac100.c | 2 -
46
hw/net/virtio-net.c | 4 +-
47
include/net/announce.h | 8 ++-
48
migration/colo.c | 2 +
49
monitor/hmp-cmds.c | 41 ++++++++++++-
50
net/announce.c | 89 +++++++++++++++++++++++----
51
net/colo-compare.c | 155 ++++++++++++++++++++++++++++++++++++++++++------
52
net/net.c | 99 +++++++++++++++----------------
53
net/trace-events | 3 +-
54
qapi/net.json | 16 ++++-
55
qemu-bridge-helper.c | 12 +++-
56
qemu-options.hx | 33 ++++++++++-
57
tests/virtio-net-test.c | 57 +++++++++++++++++-
58
15 files changed, 430 insertions(+), 99 deletions(-)
59
60
diff view generated by jsdifflib
Deleted patch
1
From: Markus Armbruster <armbru@redhat.com>
2
1
3
Signed-off-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
6
MAINTAINERS | 1 +
7
1 file changed, 1 insertion(+)
8
9
diff --git a/MAINTAINERS b/MAINTAINERS
10
index XXXXXXX..XXXXXXX 100644
11
--- a/MAINTAINERS
12
+++ b/MAINTAINERS
13
@@ -XXX,XX +XXX,XX @@ M: Jason Wang <jasowang@redhat.com>
14
S: Maintained
15
F: net/
16
F: include/net/
17
+F: qemu-bridge-helper.c
18
T: git https://github.com/jasowang/qemu.git net
19
F: qapi/net.json
20
21
--
22
2.5.0
23
24
diff view generated by jsdifflib
Deleted patch
1
From: Markus Armbruster <armbru@redhat.com>
2
1
3
Signed-off-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Jason Wang <jasowang@redhat.com>
5
---
6
qemu-bridge-helper.c | 12 +++++++++++-
7
1 file changed, 11 insertions(+), 1 deletion(-)
8
9
diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/qemu-bridge-helper.c
12
+++ b/qemu-bridge-helper.c
13
@@ -XXX,XX +XXX,XX @@
14
*
15
* This work is licensed under the terms of the GNU GPL, version 2. See
16
* the COPYING file in the top-level directory.
17
- *
18
+ */
19
+
20
+/*
21
+ * Known shortcomings:
22
+ * - There is no manual page
23
+ * - The syntax of the ACL file is not documented anywhere
24
+ * - parse_acl_file() doesn't report fopen() failure properly, fails
25
+ * to check ferror() after fgets() failure, arbitrarily truncates
26
+ * long lines, handles whitespace inconsistently, error messages
27
+ * don't point to the offending file and line, errors in included
28
+ * files are reported, but otherwise ignored, ...
29
*/
30
31
#include "qemu/osdep.h"
32
--
33
2.5.0
34
35
diff view generated by jsdifflib
Deleted patch
1
From: Cédric Le Goater <clg@kaod.org>
2
1
3
qdev_set_nic_properties() is already used in the Aspeed SoC level to
4
bind the ftgmac100 device to the netdev.
5
6
This is fixing support for multiple net devices.
7
8
Signed-off-by: Cédric Le Goater <clg@kaod.org>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
hw/net/ftgmac100.c | 2 --
12
1 file changed, 2 deletions(-)
13
14
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/ftgmac100.c
17
+++ b/hw/net/ftgmac100.c
18
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_realize(DeviceState *dev, Error **errp)
19
sysbus_init_irq(sbd, &s->irq);
20
qemu_macaddr_default_if_unset(&s->conf.macaddr);
21
22
- s->conf.peers.ncs[0] = nd_table[0].netdev;
23
-
24
s->nic = qemu_new_nic(&net_ftgmac100_info, &s->conf,
25
object_get_typename(OBJECT(dev)), DEVICE(dev)->id,
26
s);
27
--
28
2.5.0
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
If 'ipv6-prefixlen' is not a number, the current behaviour
4
produces an assertion failure:
5
$ qemu-system-x86_64 -net user,ipv6-net=feca::0/a
6
qemu-system-x86_64: qemu/util/qemu-option.c:1175: qemu_opts_foreach:
7
Assertion `!errp || !*errp' failed.
8
Aborted (core dumped)
9
10
This patch fixes it, jumping to the end of the function when
11
'ipv6-prefixlen' is not a number, and printing the more friendly
12
message:
13
$ qemu-system-x86_64 -net user,ipv6-net=feca::0/a
14
qemu-system-x86_64: Parameter 'ipv6-prefixlen' expects a number
15
16
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
17
Reviewed-by: Markus Armbruster <armbru@redhat.com>
18
Signed-off-by: Jason Wang <jasowang@redhat.com>
19
---
20
net/net.c | 9 +++++----
21
1 file changed, 5 insertions(+), 4 deletions(-)
22
23
diff --git a/net/net.c b/net/net.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/net/net.c
26
+++ b/net/net.c
27
@@ -XXX,XX +XXX,XX @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
28
29
if (err) {
30
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
31
- "ipv6-prefix", "a number");
32
- } else {
33
- qemu_opt_set_number(opts, "ipv6-prefixlen", len,
34
- &error_abort);
35
+ "ipv6-prefixlen", "a number");
36
+ goto out;
37
}
38
+
39
+ qemu_opt_set_number(opts, "ipv6-prefixlen", len, &error_abort);
40
}
41
qemu_opt_unset(opts, "ipv6-net");
42
}
43
@@ -XXX,XX +XXX,XX @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
44
qapi_free_NetLegacy(object);
45
}
46
47
+out:
48
error_propagate(errp, err);
49
visit_free(v);
50
return ret;
51
--
52
2.5.0
53
54
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
net_client_init() uses a variable length array to store the prefix
4
of 'ipv6-net' parameter (e.g. if ipv6-net=fec0::0/64, the prefix
5
is 'fec0::0').
6
This patch introduces g_strsplit() to split the 'ipv6-net' parameter,
7
so we can remove the variable length array.
8
9
Suggested-by: Markus Armbruster <armbru@redhat.com>
10
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
11
Reviewed-by: Markus Armbruster <armbru@redhat.com>
12
Signed-off-by: Jason Wang <jasowang@redhat.com>
13
---
14
net/net.c | 31 +++++++++++++++++++------------
15
1 file changed, 19 insertions(+), 12 deletions(-)
16
17
diff --git a/net/net.c b/net/net.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/net/net.c
20
+++ b/net/net.c
21
@@ -XXX,XX +XXX,XX @@ static void show_netdevs(void)
22
23
static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
24
{
25
+ gchar **substrings = NULL;
26
void *object = NULL;
27
Error *err = NULL;
28
int ret = -1;
29
@@ -XXX,XX +XXX,XX @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
30
const char *ip6_net = qemu_opt_get(opts, "ipv6-net");
31
32
if (ip6_net) {
33
- char buf[strlen(ip6_net) + 1];
34
+ char *prefix_addr;
35
+ unsigned long prefix_len = 64; /* Default 64bit prefix length. */
36
+
37
+ substrings = g_strsplit(ip6_net, "/", 2);
38
+ if (!substrings || !substrings[0]) {
39
+ error_setg(errp, QERR_INVALID_PARAMETER_VALUE, "ipv6-net",
40
+ "a valid IPv6 prefix");
41
+ goto out;
42
+ }
43
44
- if (get_str_sep(buf, sizeof(buf), &ip6_net, '/') < 0) {
45
- /* Default 64bit prefix length. */
46
- qemu_opt_set(opts, "ipv6-prefix", ip6_net, &error_abort);
47
- qemu_opt_set_number(opts, "ipv6-prefixlen", 64, &error_abort);
48
- } else {
49
+ prefix_addr = substrings[0];
50
+
51
+ if (substrings[1]) {
52
/* User-specified prefix length. */
53
- unsigned long len;
54
int err;
55
56
- qemu_opt_set(opts, "ipv6-prefix", buf, &error_abort);
57
- err = qemu_strtoul(ip6_net, NULL, 10, &len);
58
-
59
+ err = qemu_strtoul(substrings[1], NULL, 10, &prefix_len);
60
if (err) {
61
error_setg(errp, QERR_INVALID_PARAMETER_VALUE,
62
"ipv6-prefixlen", "a number");
63
goto out;
64
}
65
-
66
- qemu_opt_set_number(opts, "ipv6-prefixlen", len, &error_abort);
67
}
68
+
69
+ qemu_opt_set(opts, "ipv6-prefix", prefix_addr, &error_abort);
70
+ qemu_opt_set_number(opts, "ipv6-prefixlen", prefix_len,
71
+ &error_abort);
72
qemu_opt_unset(opts, "ipv6-net");
73
}
74
}
75
@@ -XXX,XX +XXX,XX @@ static int net_client_init(QemuOpts *opts, bool is_netdev, Error **errp)
76
77
out:
78
error_propagate(errp, err);
79
+ g_strfreev(substrings);
80
visit_free(v);
81
return ret;
82
}
83
--
84
2.5.0
85
86
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
Use the glib function to split host address and port in
4
the parse_host_port() function.
5
6
Suggested-by: Markus Armbruster <armbru@redhat.com>
7
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
8
Reviewed-by: Markus Armbruster <armbru@redhat.com>
9
Signed-off-by: Jason Wang <jasowang@redhat.com>
10
---
11
net/net.c | 43 +++++++++++++++++++++++++++----------------
12
1 file changed, 27 insertions(+), 16 deletions(-)
13
14
diff --git a/net/net.c b/net/net.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/net/net.c
17
+++ b/net/net.c
18
@@ -XXX,XX +XXX,XX @@ static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
19
int parse_host_port(struct sockaddr_in *saddr, const char *str,
20
Error **errp)
21
{
22
- char buf[512];
23
+ gchar **substrings;
24
struct hostent *he;
25
- const char *p, *r;
26
- int port;
27
+ const char *addr, *p, *r;
28
+ int port, ret = 0;
29
30
- p = str;
31
- if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {
32
+ substrings = g_strsplit(str, ":", 2);
33
+ if (!substrings || !substrings[0] || !substrings[1]) {
34
error_setg(errp, "host address '%s' doesn't contain ':' "
35
"separating host from port", str);
36
- return -1;
37
+ ret = -1;
38
+ goto out;
39
}
40
+
41
+ addr = substrings[0];
42
+ p = substrings[1];
43
+
44
saddr->sin_family = AF_INET;
45
- if (buf[0] == '\0') {
46
+ if (addr[0] == '\0') {
47
saddr->sin_addr.s_addr = 0;
48
} else {
49
- if (qemu_isdigit(buf[0])) {
50
- if (!inet_aton(buf, &saddr->sin_addr)) {
51
+ if (qemu_isdigit(addr[0])) {
52
+ if (!inet_aton(addr, &saddr->sin_addr)) {
53
error_setg(errp, "host address '%s' is not a valid "
54
- "IPv4 address", buf);
55
- return -1;
56
+ "IPv4 address", addr);
57
+ ret = -1;
58
+ goto out;
59
}
60
} else {
61
- he = gethostbyname(buf);
62
+ he = gethostbyname(addr);
63
if (he == NULL) {
64
- error_setg(errp, "can't resolve host address '%s'", buf);
65
- return - 1;
66
+ error_setg(errp, "can't resolve host address '%s'", addr);
67
+ ret = -1;
68
+ goto out;
69
}
70
saddr->sin_addr = *(struct in_addr *)he->h_addr;
71
}
72
@@ -XXX,XX +XXX,XX @@ int parse_host_port(struct sockaddr_in *saddr, const char *str,
73
port = strtol(p, (char **)&r, 0);
74
if (r == p) {
75
error_setg(errp, "port number '%s' is invalid", p);
76
- return -1;
77
+ ret = -1;
78
+ goto out;
79
}
80
saddr->sin_port = htons(port);
81
- return 0;
82
+
83
+out:
84
+ g_strfreev(substrings);
85
+ return ret;
86
}
87
88
char *qemu_mac_strdup_printf(const uint8_t *macaddr)
89
--
90
2.5.0
91
92
diff view generated by jsdifflib
Deleted patch
1
From: Stefano Garzarella <sgarzare@redhat.com>
2
1
3
Since the get_str_sep() function is no longer used in
4
net/net.c, we can remove it.
5
6
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
7
Reviewed-by: Markus Armbruster <armbru@redhat.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
net/net.c | 20 --------------------
11
1 file changed, 20 deletions(-)
12
13
diff --git a/net/net.c b/net/net.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/net/net.c
16
+++ b/net/net.c
17
@@ -XXX,XX +XXX,XX @@ static QTAILQ_HEAD(, NetClientState) net_clients;
18
/***********************************************************/
19
/* network device redirectors */
20
21
-static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
22
-{
23
- const char *p, *p1;
24
- int len;
25
- p = *pp;
26
- p1 = strchr(p, sep);
27
- if (!p1)
28
- return -1;
29
- len = p1 - p;
30
- p1++;
31
- if (buf_size > 0) {
32
- if (len > buf_size - 1)
33
- len = buf_size - 1;
34
- memcpy(buf, p, len);
35
- buf[len] = '\0';
36
- }
37
- *pp = p1;
38
- return 0;
39
-}
40
-
41
int parse_host_port(struct sockaddr_in *saddr, const char *str,
42
Error **errp)
43
{
44
--
45
2.5.0
46
47
diff view generated by jsdifflib
Deleted patch
1
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
2
1
3
Allow the caller to restrict the set of interfaces that announces are
4
sent on. The default is still to send on all interfaces.
5
6
e.g.
7
8
{ "execute": "announce-self", "arguments": { "initial": 50, "max": 550, "rounds": 5, "step": 50, "interfaces": ["vn2", "vn1"] } }
9
10
This doesn't affect the behaviour of migraiton announcments.
11
12
Note: There's still only one timer for the qmp command, so that
13
performing an 'announce-self' on one list of interfaces followed
14
by another 'announce-self' on another list will stop the announces
15
on the existing set.
16
17
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
18
Signed-off-by: Jason Wang <jasowang@redhat.com>
19
---
20
include/net/announce.h | 2 +-
21
net/announce.c | 39 ++++++++++++++++++++++++++++++++-------
22
net/trace-events | 2 +-
23
qapi/net.json | 11 ++++++++---
24
4 files changed, 42 insertions(+), 12 deletions(-)
25
26
diff --git a/include/net/announce.h b/include/net/announce.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/net/announce.h
29
+++ b/include/net/announce.h
30
@@ -XXX,XX +XXX,XX @@ struct AnnounceTimer {
31
/* Returns: update the timer to the next time point */
32
int64_t qemu_announce_timer_step(AnnounceTimer *timer);
33
34
-/* Delete the underlying timer */
35
+/* Delete the underlying timer and other data */
36
void qemu_announce_timer_del(AnnounceTimer *timer);
37
38
/*
39
diff --git a/net/announce.c b/net/announce.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/net/announce.c
42
+++ b/net/announce.c
43
@@ -XXX,XX +XXX,XX @@ void qemu_announce_timer_del(AnnounceTimer *timer)
44
timer_free(timer->tm);
45
timer->tm = NULL;
46
}
47
+ qapi_free_strList(timer->params.interfaces);
48
+ timer->params.interfaces = NULL;
49
}
50
51
/*
52
@@ -XXX,XX +XXX,XX @@ static int announce_self_create(uint8_t *buf,
53
54
static void qemu_announce_self_iter(NICState *nic, void *opaque)
55
{
56
+ AnnounceTimer *timer = opaque;
57
uint8_t buf[60];
58
int len;
59
+ bool skip;
60
+
61
+ if (timer->params.has_interfaces) {
62
+ strList *entry = timer->params.interfaces;
63
+ /* Skip unless we find our name in the requested list */
64
+ skip = true;
65
+
66
+ while (entry) {
67
+ if (!strcmp(entry->value, nic->ncs->name)) {
68
+ /* Found us */
69
+ skip = false;
70
+ break;
71
+ }
72
+ entry = entry->next;
73
+ }
74
+ } else {
75
+ skip = false;
76
+ }
77
+
78
+ trace_qemu_announce_self_iter(nic->ncs->name,
79
+ qemu_ether_ntoa(&nic->conf->macaddr), skip);
80
81
- trace_qemu_announce_self_iter(qemu_ether_ntoa(&nic->conf->macaddr));
82
- len = announce_self_create(buf, nic->conf->macaddr.a);
83
+ if (!skip) {
84
+ len = announce_self_create(buf, nic->conf->macaddr.a);
85
86
- qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
87
+ qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
88
89
- /* if the NIC provides it's own announcement support, use it as well */
90
- if (nic->ncs->info->announce) {
91
- nic->ncs->info->announce(nic->ncs);
92
+ /* if the NIC provides it's own announcement support, use it as well */
93
+ if (nic->ncs->info->announce) {
94
+ nic->ncs->info->announce(nic->ncs);
95
+ }
96
}
97
}
98
static void qemu_announce_self_once(void *opaque)
99
{
100
AnnounceTimer *timer = (AnnounceTimer *)opaque;
101
102
- qemu_foreach_nic(qemu_announce_self_iter, NULL);
103
+ qemu_foreach_nic(qemu_announce_self_iter, timer);
104
105
if (--timer->round) {
106
qemu_announce_timer_step(timer);
107
diff --git a/net/trace-events b/net/trace-events
108
index XXXXXXX..XXXXXXX 100644
109
--- a/net/trace-events
110
+++ b/net/trace-events
111
@@ -XXX,XX +XXX,XX @@
112
# See docs/devel/tracing.txt for syntax documentation.
113
114
# announce.c
115
-qemu_announce_self_iter(const char *mac) "%s"
116
+qemu_announce_self_iter(const char *name, const char *mac, int skip) "%s:%s skip: %d"
117
118
# vhost-user.c
119
vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
120
diff --git a/qapi/net.json b/qapi/net.json
121
index XXXXXXX..XXXXXXX 100644
122
--- a/qapi/net.json
123
+++ b/qapi/net.json
124
@@ -XXX,XX +XXX,XX @@
125
#
126
# @step: Delay increase (in ms) after each self-announcement attempt
127
#
128
+# @interfaces: An optional list of interface names, which restricts the
129
+# announcement to the listed interfaces. (Since 4.1)
130
+#
131
# Since: 4.0
132
##
133
134
@@ -XXX,XX +XXX,XX @@
135
'data': { 'initial': 'int',
136
'max': 'int',
137
'rounds': 'int',
138
- 'step': 'int' } }
139
+ 'step': 'int',
140
+ '*interfaces': ['str'] } }
141
142
##
143
# @announce-self:
144
@@ -XXX,XX +XXX,XX @@
145
#
146
# Example:
147
#
148
-# -> { "execute": "announce-self"
149
+# -> { "execute": "announce-self",
150
# "arguments": {
151
-# "initial": 50, "max": 550, "rounds": 10, "step": 50 } }
152
+# "initial": 50, "max": 550, "rounds": 10, "step": 50,
153
+# "interfaces": ["vn2", "vn3"] } }
154
# <- { "return": {} }
155
#
156
# Since: 4.0
157
--
158
2.5.0
159
160
diff view generated by jsdifflib
1
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
1
From: Konstantin Shkolnyy <kshk@linux.ibm.com>
2
2
3
Add the optional interface list to the HMP command.
3
Add .set_vnet_le() function that always returns success, assuming that
4
vDPA h/w always implements LE data format. Otherwise, QEMU disables vDPA and
5
outputs the message:
6
"backend does not support LE vnet headers; falling back on userspace virtio"
4
7
5
i.e.
8
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
6
9
Acked-by: Eugenio Pérez <eperezma@redhat.com>
7
All interfaces
10
Signed-off-by: Konstantin Shkolnyy <kshk@linux.ibm.com>
8
announce_self
9
10
Just the named interfaces:
11
announce_self vn1,vn2
12
13
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
14
Signed-off-by: Jason Wang <jasowang@redhat.com>
11
Signed-off-by: Jason Wang <jasowang@redhat.com>
15
---
12
---
16
hmp-commands.hx | 6 ++++--
13
net/vhost-vdpa.c | 13 +++++++++++++
17
monitor/hmp-cmds.c | 38 +++++++++++++++++++++++++++++++++++++-
14
1 file changed, 13 insertions(+)
18
2 files changed, 41 insertions(+), 3 deletions(-)
19
15
20
diff --git a/hmp-commands.hx b/hmp-commands.hx
16
diff --git a/net/vhost-vdpa.c b/net/vhost-vdpa.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/hmp-commands.hx
18
--- a/net/vhost-vdpa.c
23
+++ b/hmp-commands.hx
19
+++ b/net/vhost-vdpa.c
24
@@ -XXX,XX +XXX,XX @@ ETEXI
20
@@ -XXX,XX +XXX,XX @@ static bool vhost_vdpa_has_ufo(NetClientState *nc)
25
21
26
{
27
.name = "announce_self",
28
- .args_type = "",
29
- .params = "",
30
+ .args_type = "interfaces:s?",
31
+ .params = "[interfaces]",
32
.help = "Trigger GARP/RARP announcements",
33
.cmd = hmp_announce_self,
34
},
35
@@ -XXX,XX +XXX,XX @@ STEXI
36
Trigger a round of GARP/RARP broadcasts; this is useful for explicitly updating the
37
network infrastructure after a reconfiguration or some forms of migration.
38
The timings of the round are set by the migration announce parameters.
39
+An optional comma separated @var{interfaces} list restricts the announce to the
40
+named set of interfaces.
41
ETEXI
42
43
{
44
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/monitor/hmp-cmds.c
47
+++ b/monitor/hmp-cmds.c
48
@@ -XXX,XX +XXX,XX @@
49
#include "monitor/monitor-internal.h"
50
#include "monitor/qdev.h"
51
#include "qapi/error.h"
52
+#include "qapi/clone-visitor.h"
53
#include "qapi/opts-visitor.h"
54
#include "qapi/qapi-builtin-visit.h"
55
#include "qapi/qapi-commands-block.h"
56
@@ -XXX,XX +XXX,XX @@
57
#include "qapi/qapi-commands-run-state.h"
58
#include "qapi/qapi-commands-tpm.h"
59
#include "qapi/qapi-commands-ui.h"
60
+#include "qapi/qapi-visit-net.h"
61
#include "qapi/qmp/qdict.h"
62
#include "qapi/qmp/qerror.h"
63
#include "qapi/string-input-visitor.h"
64
@@ -XXX,XX +XXX,XX @@ static void hmp_handle_error(Monitor *mon, Error **errp)
65
}
66
}
22
}
67
23
68
+/*
24
+/*
69
+ * Produce a strList from a comma separated list.
25
+ * FIXME: vhost_vdpa doesn't have an API to "set h/w endianness". But it's
70
+ * A NULL or empty input string return NULL.
26
+ * reasonable to assume that h/w is LE by default, because LE is what
27
+ * virtio 1.0 and later ask for. So, this function just says "yes, the h/w is
28
+ * LE". Otherwise, on a BE machine, higher-level code would mistakely think
29
+ * the h/w is BE and can't support VDPA for a virtio 1.0 client.
71
+ */
30
+ */
72
+static strList *strList_from_comma_list(const char *in)
31
+static int vhost_vdpa_set_vnet_le(NetClientState *nc, bool enable)
73
+{
32
+{
74
+ strList *res = NULL;
33
+ return 0;
75
+ strList **hook = &res;
76
+
77
+ while (in && in[0]) {
78
+ char *comma = strchr(in, ',');
79
+ *hook = g_new0(strList, 1);
80
+
81
+ if (comma) {
82
+ (*hook)->value = g_strndup(in, comma - in);
83
+ in = comma + 1; /* skip the , */
84
+ } else {
85
+ (*hook)->value = g_strdup(in);
86
+ in = NULL;
87
+ }
88
+ hook = &(*hook)->next;
89
+ }
90
+
91
+ return res;
92
+}
34
+}
93
+
35
+
94
void hmp_info_name(Monitor *mon, const QDict *qdict)
36
static bool vhost_vdpa_check_peer_type(NetClientState *nc, ObjectClass *oc,
37
Error **errp)
95
{
38
{
96
NameInfo *info;
39
@@ -XXX,XX +XXX,XX @@ static NetClientInfo net_vhost_vdpa_info = {
97
@@ -XXX,XX +XXX,XX @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
40
.cleanup = vhost_vdpa_cleanup,
98
41
.has_vnet_hdr = vhost_vdpa_has_vnet_hdr,
99
void hmp_announce_self(Monitor *mon, const QDict *qdict)
42
.has_ufo = vhost_vdpa_has_ufo,
100
{
43
+ .set_vnet_le = vhost_vdpa_set_vnet_le,
101
- qmp_announce_self(migrate_announce_params(), NULL);
44
.check_peer_type = vhost_vdpa_check_peer_type,
102
+ const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
45
.set_steering_ebpf = vhost_vdpa_set_steering_ebpf,
103
+ AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
46
};
104
+ migrate_announce_params());
105
+
106
+ qapi_free_strList(params->interfaces);
107
+ params->interfaces = strList_from_comma_list(interfaces_str);
108
+ params->has_interfaces = params->interfaces != NULL;
109
+ qmp_announce_self(params, NULL);
110
+ qapi_free_AnnounceParameters(params);
111
}
112
113
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict)
114
--
47
--
115
2.5.0
48
2.42.0
116
49
117
50
diff view generated by jsdifflib
Deleted patch
1
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
2
1
3
Previously there was a single instance of the timer used by
4
monitor triggered announces, that's OK, but when combined with the
5
previous change that lets you have announces for subsets of interfaces
6
it's a bit restrictive if you want to do different things to different
7
interfaces.
8
9
Add an 'id' field to the announce, and maintain a list of the
10
timers based on id.
11
12
This allows you to for example:
13
a) Start an announce going on interface eth0 for a long time
14
b) Start an announce going on interface eth1 for a long time
15
c) Kill the announce on eth0 while leaving eth1 going.
16
17
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
18
Signed-off-by: Jason Wang <jasowang@redhat.com>
19
---
20
hw/net/virtio-net.c | 4 ++--
21
include/net/announce.h | 8 ++++++--
22
net/announce.c | 52 +++++++++++++++++++++++++++++++++++++++++++-------
23
net/trace-events | 3 ++-
24
qapi/net.json | 9 +++++++--
25
5 files changed, 62 insertions(+), 14 deletions(-)
26
27
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/net/virtio-net.c
30
+++ b/hw/net/virtio-net.c
31
@@ -XXX,XX +XXX,XX @@ static int virtio_net_post_load_device(void *opaque, int version_id)
32
timer_mod(n->announce_timer.tm,
33
qemu_clock_get_ms(n->announce_timer.type));
34
} else {
35
- qemu_announce_timer_del(&n->announce_timer);
36
+ qemu_announce_timer_del(&n->announce_timer, false);
37
}
38
}
39
40
@@ -XXX,XX +XXX,XX @@ static void virtio_net_device_unrealize(DeviceState *dev, Error **errp)
41
virtio_net_del_queue(n, i);
42
}
43
44
- qemu_announce_timer_del(&n->announce_timer);
45
+ qemu_announce_timer_del(&n->announce_timer, false);
46
g_free(n->vqs);
47
qemu_del_nic(n->nic);
48
virtio_net_rsc_cleanup(n);
49
diff --git a/include/net/announce.h b/include/net/announce.h
50
index XXXXXXX..XXXXXXX 100644
51
--- a/include/net/announce.h
52
+++ b/include/net/announce.h
53
@@ -XXX,XX +XXX,XX @@ struct AnnounceTimer {
54
/* Returns: update the timer to the next time point */
55
int64_t qemu_announce_timer_step(AnnounceTimer *timer);
56
57
-/* Delete the underlying timer and other data */
58
-void qemu_announce_timer_del(AnnounceTimer *timer);
59
+/*
60
+ * Delete the underlying timer and other data
61
+ * If 'free_named' true and the timer is a named timer, then remove
62
+ * it from the list of named timers and free the AnnounceTimer itself.
63
+ */
64
+void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named);
65
66
/*
67
* Under BQL/main thread
68
diff --git a/net/announce.c b/net/announce.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/net/announce.c
71
+++ b/net/announce.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "qapi/qapi-commands-net.h"
74
#include "trace.h"
75
76
+static GData *named_timers;
77
+
78
int64_t qemu_announce_timer_step(AnnounceTimer *timer)
79
{
80
int64_t step;
81
@@ -XXX,XX +XXX,XX @@ int64_t qemu_announce_timer_step(AnnounceTimer *timer)
82
return step;
83
}
84
85
-void qemu_announce_timer_del(AnnounceTimer *timer)
86
+/*
87
+ * If 'free_named' is true, then remove the timer from the list
88
+ * and free the timer itself.
89
+ */
90
+void qemu_announce_timer_del(AnnounceTimer *timer, bool free_named)
91
{
92
+ bool free_timer = false;
93
if (timer->tm) {
94
timer_del(timer->tm);
95
timer_free(timer->tm);
96
@@ -XXX,XX +XXX,XX @@ void qemu_announce_timer_del(AnnounceTimer *timer)
97
}
98
qapi_free_strList(timer->params.interfaces);
99
timer->params.interfaces = NULL;
100
+ if (free_named && timer->params.has_id) {
101
+ AnnounceTimer *list_timer;
102
+ /*
103
+ * Sanity check: There should only be one timer on the list with
104
+ * the id.
105
+ */
106
+ list_timer = g_datalist_get_data(&named_timers, timer->params.id);
107
+ assert(timer == list_timer);
108
+ free_timer = true;
109
+ g_datalist_remove_data(&named_timers, timer->params.id);
110
+ }
111
+ trace_qemu_announce_timer_del(free_named, free_timer, timer->params.id);
112
+ g_free(timer->params.id);
113
+ timer->params.id = NULL;
114
+
115
+ if (free_timer) {
116
+ g_free(timer);
117
+ }
118
}
119
120
/*
121
@@ -XXX,XX +XXX,XX @@ void qemu_announce_timer_reset(AnnounceTimer *timer,
122
* We're under the BQL, so the current timer can't
123
* be firing, so we should be able to delete it.
124
*/
125
- qemu_announce_timer_del(timer);
126
+ qemu_announce_timer_del(timer, false);
127
128
QAPI_CLONE_MEMBERS(AnnounceParameters, &timer->params, params);
129
timer->round = params->rounds;
130
@@ -XXX,XX +XXX,XX @@ static void qemu_announce_self_iter(NICState *nic, void *opaque)
131
skip = false;
132
}
133
134
- trace_qemu_announce_self_iter(nic->ncs->name,
135
+ trace_qemu_announce_self_iter(timer->params.has_id ? timer->params.id : "_",
136
+ nic->ncs->name,
137
qemu_ether_ntoa(&nic->conf->macaddr), skip);
138
139
if (!skip) {
140
@@ -XXX,XX +XXX,XX @@ static void qemu_announce_self_once(void *opaque)
141
if (--timer->round) {
142
qemu_announce_timer_step(timer);
143
} else {
144
- qemu_announce_timer_del(timer);
145
+ qemu_announce_timer_del(timer, true);
146
}
147
}
148
149
@@ -XXX,XX +XXX,XX @@ void qemu_announce_self(AnnounceTimer *timer, AnnounceParameters *params)
150
if (params->rounds) {
151
qemu_announce_self_once(timer);
152
} else {
153
- qemu_announce_timer_del(timer);
154
+ qemu_announce_timer_del(timer, true);
155
}
156
}
157
158
void qmp_announce_self(AnnounceParameters *params, Error **errp)
159
{
160
- static AnnounceTimer announce_timer;
161
- qemu_announce_self(&announce_timer, params);
162
+ AnnounceTimer *named_timer;
163
+ if (!params->has_id) {
164
+ params->id = g_strdup("");
165
+ params->has_id = true;
166
+ }
167
+
168
+ named_timer = g_datalist_get_data(&named_timers, params->id);
169
+
170
+ if (!named_timer) {
171
+ named_timer = g_new0(AnnounceTimer, 1);
172
+ g_datalist_set_data(&named_timers, params->id, named_timer);
173
+ }
174
+
175
+ qemu_announce_self(named_timer, params);
176
}
177
diff --git a/net/trace-events b/net/trace-events
178
index XXXXXXX..XXXXXXX 100644
179
--- a/net/trace-events
180
+++ b/net/trace-events
181
@@ -XXX,XX +XXX,XX @@
182
# See docs/devel/tracing.txt for syntax documentation.
183
184
# announce.c
185
-qemu_announce_self_iter(const char *name, const char *mac, int skip) "%s:%s skip: %d"
186
+qemu_announce_self_iter(const char *id, const char *name, const char *mac, int skip) "%s:%s:%s skip: %d"
187
+qemu_announce_timer_del(bool free_named, bool free_timer, char *id) "free named: %d free timer: %d id: %s"
188
189
# vhost-user.c
190
vhost_user_event(const char *chr, int event) "chr: %s got event: %d"
191
diff --git a/qapi/net.json b/qapi/net.json
192
index XXXXXXX..XXXXXXX 100644
193
--- a/qapi/net.json
194
+++ b/qapi/net.json
195
@@ -XXX,XX +XXX,XX @@
196
# @interfaces: An optional list of interface names, which restricts the
197
# announcement to the listed interfaces. (Since 4.1)
198
#
199
+# @id: A name to be used to identify an instance of announce-timers
200
+# and to allow it to modified later. Not for use as
201
+# part of the migration parameters. (Since 4.1)
202
+#
203
# Since: 4.0
204
##
205
206
@@ -XXX,XX +XXX,XX @@
207
'max': 'int',
208
'rounds': 'int',
209
'step': 'int',
210
- '*interfaces': ['str'] } }
211
+ '*interfaces': ['str'],
212
+ '*id' : 'str' } }
213
214
##
215
# @announce-self:
216
@@ -XXX,XX +XXX,XX @@
217
# -> { "execute": "announce-self",
218
# "arguments": {
219
# "initial": 50, "max": 550, "rounds": 10, "step": 50,
220
-# "interfaces": ["vn2", "vn3"] } }
221
+# "interfaces": ["vn2", "vn3"], "id": "bob" } }
222
# <- { "return": {} }
223
#
224
# Since: 4.0
225
--
226
2.5.0
227
228
diff view generated by jsdifflib
Deleted patch
1
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
2
1
3
Add the optional ID to the HMP command.
4
5
e.g.
6
# start an announce for a long time on eth1
7
migrate_set_parameter announce-rounds 1000
8
announce_self "eth1" e1
9
10
# start an announce on eth2
11
announce_self "eth2" e2
12
13
# Change e1 to be announcing on eth1 and eth3
14
announce_self "eth1,eth3" e1
15
16
# Cancel e1
17
migrate_set_parameter announce-rounds 0
18
announce_self "" e1
19
20
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
21
Signed-off-by: Jason Wang <jasowang@redhat.com>
22
---
23
hmp-commands.hx | 7 ++++---
24
monitor/hmp-cmds.c | 3 +++
25
2 files changed, 7 insertions(+), 3 deletions(-)
26
27
diff --git a/hmp-commands.hx b/hmp-commands.hx
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hmp-commands.hx
30
+++ b/hmp-commands.hx
31
@@ -XXX,XX +XXX,XX @@ ETEXI
32
33
{
34
.name = "announce_self",
35
- .args_type = "interfaces:s?",
36
- .params = "[interfaces]",
37
+ .args_type = "interfaces:s?,id:s?",
38
+ .params = "[interfaces] [id]",
39
.help = "Trigger GARP/RARP announcements",
40
.cmd = hmp_announce_self,
41
},
42
@@ -XXX,XX +XXX,XX @@ Trigger a round of GARP/RARP broadcasts; this is useful for explicitly updating
43
network infrastructure after a reconfiguration or some forms of migration.
44
The timings of the round are set by the migration announce parameters.
45
An optional comma separated @var{interfaces} list restricts the announce to the
46
-named set of interfaces.
47
+named set of interfaces. An optional @var{id} can be used to start a separate announce
48
+timer and to change the parameters of it later.
49
ETEXI
50
51
{
52
diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/monitor/hmp-cmds.c
55
+++ b/monitor/hmp-cmds.c
56
@@ -XXX,XX +XXX,XX @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
57
void hmp_announce_self(Monitor *mon, const QDict *qdict)
58
{
59
const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
60
+ const char *id = qdict_get_try_str(qdict, "id");
61
AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
62
migrate_announce_params());
63
64
qapi_free_strList(params->interfaces);
65
params->interfaces = strList_from_comma_list(interfaces_str);
66
params->has_interfaces = params->interfaces != NULL;
67
+ params->id = g_strdup(id);
68
+ params->has_id = !!params->id;
69
qmp_announce_self(params, NULL);
70
qapi_free_AnnounceParameters(params);
71
}
72
--
73
2.5.0
74
75
diff view generated by jsdifflib
Deleted patch
1
From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
2
1
3
Expand self-announce test to check we can stop an announce timer.
4
We set it up to send 300 packets, but after we receive
5
the first one we tell it to stop.
6
7
We error if:
8
a) We receive more than 30 of the packets
9
b) We're still receiving packets after a lot longer than the
10
30 seconds should have arrived
11
12
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
13
Signed-off-by: Jason Wang <jasowang@redhat.com>
14
---
15
tests/virtio-net-test.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++---
16
1 file changed, 54 insertions(+), 3 deletions(-)
17
18
diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/tests/virtio-net-test.c
21
+++ b/tests/virtio-net-test.c
22
@@ -XXX,XX +XXX,XX @@ static void announce_self(void *obj, void *data, QGuestAllocator *t_alloc)
23
QDict *rsp;
24
int ret;
25
uint16_t *proto = (uint16_t *)&buffer[12];
26
+ size_t total_received = 0;
27
+ uint64_t start, now, last_rxt, deadline;
28
29
+ /* Send a set of packets over a few second period */
30
rsp = qmp("{ 'execute' : 'announce-self', "
31
" 'arguments': {"
32
- " 'initial': 50, 'max': 550,"
33
- " 'rounds': 10, 'step': 50 } }");
34
+ " 'initial': 20, 'max': 100,"
35
+ " 'rounds': 300, 'step': 10, 'id': 'bob' } }");
36
assert(!qdict_haskey(rsp, "error"));
37
qobject_unref(rsp);
38
39
- /* Catch the packet and make sure it's a RARP */
40
+ /* Catch the first packet and make sure it's a RARP */
41
ret = qemu_recv(sv[0], &len, sizeof(len), 0);
42
g_assert_cmpint(ret, ==, sizeof(len));
43
len = ntohl(len);
44
45
ret = qemu_recv(sv[0], buffer, len, 0);
46
g_assert_cmpint(*proto, ==, htons(ETH_P_RARP));
47
+
48
+ /*
49
+ * Stop the announcment by settings rounds to 0 on the
50
+ * existing timer.
51
+ */
52
+ rsp = qmp("{ 'execute' : 'announce-self', "
53
+ " 'arguments': {"
54
+ " 'initial': 20, 'max': 100,"
55
+ " 'rounds': 0, 'step': 10, 'id': 'bob' } }");
56
+ assert(!qdict_haskey(rsp, "error"));
57
+ qobject_unref(rsp);
58
+
59
+ /* Now make sure the packets stop */
60
+
61
+ /* Times are in us */
62
+ start = g_get_monotonic_time();
63
+ /* 30 packets, max gap 100ms, * 4 for wiggle */
64
+ deadline = start + 1000 * (100 * 30 * 4);
65
+ last_rxt = start;
66
+
67
+ while (true) {
68
+ int saved_err;
69
+ ret = qemu_recv(sv[0], buffer, 60, MSG_DONTWAIT);
70
+ saved_err = errno;
71
+ now = g_get_monotonic_time();
72
+ g_assert_cmpint(now, <, deadline);
73
+
74
+ if (ret >= 0) {
75
+ if (ret) {
76
+ last_rxt = now;
77
+ }
78
+ total_received += ret;
79
+
80
+ /* Check it's not spewing loads */
81
+ g_assert_cmpint(total_received, <, 60 * 30 * 2);
82
+ } else {
83
+ g_assert_cmpint(saved_err, ==, EAGAIN);
84
+
85
+ /* 400ms, i.e. 4 worst case gaps */
86
+ if ((now - last_rxt) > (1000 * 100 * 4)) {
87
+ /* Nothings arrived for a while - must have stopped */
88
+ break;
89
+ };
90
+
91
+ /* 100ms */
92
+ g_usleep(1000 * 100);
93
+ }
94
+ };
95
}
96
97
static void virtio_net_test_cleanup(void *sockets)
98
--
99
2.5.0
100
101
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <chen.zhang@intel.com>
2
1
3
We add the "notify_dev=chardevID" parameter. After that colo-compare can connect with
4
remote(currently just for Xen, KVM-COLO didn't need it.) colo-frame through chardev socket,
5
it can notify remote(Xen) colo-frame to handle checkpoint event.
6
7
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
8
Signed-off-by: Jason Wang <jasowang@redhat.com>
9
---
10
net/colo-compare.c | 21 +++++++++++++++++++++
11
qemu-options.hx | 33 ++++++++++++++++++++++++++++++++-
12
2 files changed, 53 insertions(+), 1 deletion(-)
13
14
diff --git a/net/colo-compare.c b/net/colo-compare.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/net/colo-compare.c
17
+++ b/net/colo-compare.c
18
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
19
char *pri_indev;
20
char *sec_indev;
21
char *outdev;
22
+ char *notify_dev;
23
CharBackend chr_pri_in;
24
CharBackend chr_sec_in;
25
CharBackend chr_out;
26
@@ -XXX,XX +XXX,XX @@ static void compare_set_vnet_hdr(Object *obj,
27
s->vnet_hdr = value;
28
}
29
30
+static char *compare_get_notify_dev(Object *obj, Error **errp)
31
+{
32
+ CompareState *s = COLO_COMPARE(obj);
33
+
34
+ return g_strdup(s->notify_dev);
35
+}
36
+
37
+static void compare_set_notify_dev(Object *obj, const char *value, Error **errp)
38
+{
39
+ CompareState *s = COLO_COMPARE(obj);
40
+
41
+ g_free(s->notify_dev);
42
+ s->notify_dev = g_strdup(value);
43
+}
44
+
45
static void compare_pri_rs_finalize(SocketReadState *pri_rs)
46
{
47
CompareState *s = container_of(pri_rs, CompareState, pri_rs);
48
@@ -XXX,XX +XXX,XX @@ static void colo_compare_init(Object *obj)
49
(Object **)&s->iothread,
50
object_property_allow_set_link,
51
OBJ_PROP_LINK_STRONG, NULL);
52
+ /* This parameter just for Xen COLO */
53
+ object_property_add_str(obj, "notify_dev",
54
+ compare_get_notify_dev, compare_set_notify_dev,
55
+ NULL);
56
57
s->vnet_hdr = false;
58
object_property_add_bool(obj, "vnet_hdr_support", compare_get_vnet_hdr,
59
@@ -XXX,XX +XXX,XX @@ static void colo_compare_finalize(Object *obj)
60
g_free(s->pri_indev);
61
g_free(s->sec_indev);
62
g_free(s->outdev);
63
+ g_free(s->notify_dev);
64
}
65
66
static const TypeInfo colo_compare_info = {
67
diff --git a/qemu-options.hx b/qemu-options.hx
68
index XXXXXXX..XXXXXXX 100644
69
--- a/qemu-options.hx
70
+++ b/qemu-options.hx
71
@@ -XXX,XX +XXX,XX @@ Dump the network traffic on netdev @var{dev} to the file specified by
72
The file format is libpcap, so it can be analyzed with tools such as tcpdump
73
or Wireshark.
74
75
-@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid},iothread=@var{id}[,vnet_hdr_support]
76
+@item -object colo-compare,id=@var{id},primary_in=@var{chardevid},secondary_in=@var{chardevid},outdev=@var{chardevid},iothread=@var{id}[,vnet_hdr_support][,notify_dev=@var{id}]
77
78
Colo-compare gets packet from primary_in@var{chardevid} and secondary_in@var{chardevid}, than compare primary packet with
79
secondary packet. If the packets are same, we will output primary
80
@@ -XXX,XX +XXX,XX @@ do checkpoint and send primary packet to outdev@var{chardevid}.
81
In order to improve efficiency, we need to put the task of comparison
82
in another thread. If it has the vnet_hdr_support flag, colo compare
83
will send/recv packet with vnet_hdr_len.
84
+If you want to use Xen COLO, will need the notify_dev to notify Xen
85
+colo-frame to do checkpoint.
86
87
we must use it with the help of filter-mirror and filter-redirector.
88
89
@example
90
91
+KVM COLO
92
+
93
primary:
94
-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
95
-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
96
@@ -XXX,XX +XXX,XX @@ secondary:
97
-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
98
-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
99
100
+
101
+Xen COLO
102
+
103
+primary:
104
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown
105
+-device e1000,id=e0,netdev=hn0,mac=52:a4:00:12:78:66
106
+-chardev socket,id=mirror0,host=3.3.3.3,port=9003,server,nowait
107
+-chardev socket,id=compare1,host=3.3.3.3,port=9004,server,nowait
108
+-chardev socket,id=compare0,host=3.3.3.3,port=9001,server,nowait
109
+-chardev socket,id=compare0-0,host=3.3.3.3,port=9001
110
+-chardev socket,id=compare_out,host=3.3.3.3,port=9005,server,nowait
111
+-chardev socket,id=compare_out0,host=3.3.3.3,port=9005
112
+-chardev socket,id=notify_way,host=3.3.3.3,port=9009,server,nowait
113
+-object filter-mirror,id=m0,netdev=hn0,queue=tx,outdev=mirror0
114
+-object filter-redirector,netdev=hn0,id=redire0,queue=rx,indev=compare_out
115
+-object filter-redirector,netdev=hn0,id=redire1,queue=rx,outdev=compare0
116
+-object iothread,id=iothread1
117
+-object colo-compare,id=comp0,primary_in=compare0-0,secondary_in=compare1,outdev=compare_out0,notify_dev=nofity_way,iothread=iothread1
118
+
119
+secondary:
120
+-netdev tap,id=hn0,vhost=off,script=/etc/qemu-ifup,down script=/etc/qemu-ifdown
121
+-device e1000,netdev=hn0,mac=52:a4:00:12:78:66
122
+-chardev socket,id=red0,host=3.3.3.3,port=9003
123
+-chardev socket,id=red1,host=3.3.3.3,port=9004
124
+-object filter-redirector,id=f1,netdev=hn0,queue=tx,indev=red0
125
+-object filter-redirector,id=f2,netdev=hn0,queue=rx,outdev=red1
126
+
127
@end example
128
129
If you want to know the detail of above command line, you can read
130
--
131
2.5.0
132
133
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <chen.zhang@intel.com>
2
1
3
Add chardev handler to send notification to remote(current from Xen) colo-frame.
4
5
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
net/colo-compare.c | 39 +++++++++++++++++++++++++++++++++++++++
9
1 file changed, 39 insertions(+)
10
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
14
+++ b/net/colo-compare.c
15
@@ -XXX,XX +XXX,XX @@ typedef struct CompareState {
16
CharBackend chr_pri_in;
17
CharBackend chr_sec_in;
18
CharBackend chr_out;
19
+ CharBackend chr_notify_dev;
20
SocketReadState pri_rs;
21
SocketReadState sec_rs;
22
+ SocketReadState notify_rs;
23
bool vnet_hdr;
24
25
/*
26
@@ -XXX,XX +XXX,XX @@ static void compare_sec_chr_in(void *opaque, const uint8_t *buf, int size)
27
}
28
}
29
30
+static void compare_notify_chr(void *opaque, const uint8_t *buf, int size)
31
+{
32
+ CompareState *s = COLO_COMPARE(opaque);
33
+ int ret;
34
+
35
+ ret = net_fill_rstate(&s->notify_rs, buf, size);
36
+ if (ret == -1) {
37
+ qemu_chr_fe_set_handlers(&s->chr_notify_dev, NULL, NULL, NULL, NULL,
38
+ NULL, NULL, true);
39
+ error_report("colo-compare notify_dev error");
40
+ }
41
+}
42
+
43
/*
44
* Check old packet regularly so it can watch for any packets
45
* that the secondary hasn't produced equivalents of.
46
@@ -XXX,XX +XXX,XX @@ static void colo_compare_iothread(CompareState *s)
47
qemu_chr_fe_set_handlers(&s->chr_sec_in, compare_chr_can_read,
48
compare_sec_chr_in, NULL, NULL,
49
s, s->worker_context, true);
50
+ if (s->notify_dev) {
51
+ qemu_chr_fe_set_handlers(&s->chr_notify_dev, compare_chr_can_read,
52
+ compare_notify_chr, NULL, NULL,
53
+ s, s->worker_context, true);
54
+ }
55
56
colo_compare_timer_init(s);
57
s->event_bh = qemu_bh_new(colo_compare_handle_event, s);
58
@@ -XXX,XX +XXX,XX @@ static void compare_sec_rs_finalize(SocketReadState *sec_rs)
59
}
60
}
61
62
+static void compare_notify_rs_finalize(SocketReadState *notify_rs)
63
+{
64
+ /* Get Xen colo-frame's notify and handle the message */
65
+}
66
67
/*
68
* Return 0 is success.
69
@@ -XXX,XX +XXX,XX @@ static void colo_compare_complete(UserCreatable *uc, Error **errp)
70
net_socket_rs_init(&s->pri_rs, compare_pri_rs_finalize, s->vnet_hdr);
71
net_socket_rs_init(&s->sec_rs, compare_sec_rs_finalize, s->vnet_hdr);
72
73
+ /* Try to enable remote notify chardev, currently just for Xen COLO */
74
+ if (s->notify_dev) {
75
+ if (find_and_check_chardev(&chr, s->notify_dev, errp) ||
76
+ !qemu_chr_fe_init(&s->chr_notify_dev, chr, errp)) {
77
+ return;
78
+ }
79
+
80
+ net_socket_rs_init(&s->notify_rs, compare_notify_rs_finalize,
81
+ s->vnet_hdr);
82
+ }
83
+
84
QTAILQ_INSERT_TAIL(&net_compares, s, next);
85
86
g_queue_init(&s->conn_list);
87
@@ -XXX,XX +XXX,XX @@ static void colo_compare_finalize(Object *obj)
88
qemu_chr_fe_deinit(&s->chr_pri_in, false);
89
qemu_chr_fe_deinit(&s->chr_sec_in, false);
90
qemu_chr_fe_deinit(&s->chr_out, false);
91
+ if (s->notify_dev) {
92
+ qemu_chr_fe_deinit(&s->chr_notify_dev, false);
93
+ }
94
+
95
if (s->iothread) {
96
colo_compare_timer_del(s);
97
}
98
--
99
2.5.0
100
101
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <chen.zhang@intel.com>
2
1
3
We need use this function to send notification message for remote colo-frame(Xen).
4
So we add new parameter for this job.
5
6
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
7
Signed-off-by: Jason Wang <jasowang@redhat.com>
8
---
9
net/colo-compare.c | 41 +++++++++++++++++++++++++++++++++--------
10
1 file changed, 33 insertions(+), 8 deletions(-)
11
12
diff --git a/net/colo-compare.c b/net/colo-compare.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/net/colo-compare.c
15
+++ b/net/colo-compare.c
16
@@ -XXX,XX +XXX,XX @@ static void colo_compare_inconsistency_notify(void)
17
static int compare_chr_send(CompareState *s,
18
const uint8_t *buf,
19
uint32_t size,
20
- uint32_t vnet_hdr_len);
21
+ uint32_t vnet_hdr_len,
22
+ bool notify_remote_frame);
23
24
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
25
{
26
@@ -XXX,XX +XXX,XX @@ static void colo_release_primary_pkt(CompareState *s, Packet *pkt)
27
ret = compare_chr_send(s,
28
pkt->data,
29
pkt->size,
30
- pkt->vnet_hdr_len);
31
+ pkt->vnet_hdr_len,
32
+ false);
33
if (ret < 0) {
34
error_report("colo send primary packet failed");
35
}
36
@@ -XXX,XX +XXX,XX @@ static void colo_compare_connection(void *opaque, void *user_data)
37
static int compare_chr_send(CompareState *s,
38
const uint8_t *buf,
39
uint32_t size,
40
- uint32_t vnet_hdr_len)
41
+ uint32_t vnet_hdr_len,
42
+ bool notify_remote_frame)
43
{
44
int ret = 0;
45
uint32_t len = htonl(size);
46
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s,
47
return 0;
48
}
49
50
- ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
51
+ if (notify_remote_frame) {
52
+ ret = qemu_chr_fe_write_all(&s->chr_notify_dev,
53
+ (uint8_t *)&len,
54
+ sizeof(len));
55
+ } else {
56
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
57
+ }
58
+
59
if (ret != sizeof(len)) {
60
goto err;
61
}
62
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s,
63
* know how to parse net packet correctly.
64
*/
65
len = htonl(vnet_hdr_len);
66
- ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)&len, sizeof(len));
67
+
68
+ if (!notify_remote_frame) {
69
+ ret = qemu_chr_fe_write_all(&s->chr_out,
70
+ (uint8_t *)&len,
71
+ sizeof(len));
72
+ }
73
+
74
if (ret != sizeof(len)) {
75
goto err;
76
}
77
}
78
79
- ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
80
+ if (notify_remote_frame) {
81
+ ret = qemu_chr_fe_write_all(&s->chr_notify_dev,
82
+ (uint8_t *)buf,
83
+ size);
84
+ } else {
85
+ ret = qemu_chr_fe_write_all(&s->chr_out, (uint8_t *)buf, size);
86
+ }
87
+
88
if (ret != size) {
89
goto err;
90
}
91
@@ -XXX,XX +XXX,XX @@ static void compare_pri_rs_finalize(SocketReadState *pri_rs)
92
compare_chr_send(s,
93
pri_rs->buf,
94
pri_rs->packet_len,
95
- pri_rs->vnet_hdr_len);
96
+ pri_rs->vnet_hdr_len,
97
+ false);
98
} else {
99
/* compare packet in the specified connection */
100
colo_compare_connection(conn, s);
101
@@ -XXX,XX +XXX,XX @@ static void colo_flush_packets(void *opaque, void *user_data)
102
compare_chr_send(s,
103
pkt->data,
104
pkt->size,
105
- pkt->vnet_hdr_len);
106
+ pkt->vnet_hdr_len,
107
+ false);
108
packet_destroy(pkt, NULL);
109
}
110
while (!g_queue_is_empty(&conn->secondary_list)) {
111
--
112
2.5.0
113
114
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <chen.zhang@intel.com>
2
1
3
This patch make colo-compare can send message to remote COLO frame(Xen) when occur checkpoint.
4
5
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
net/colo-compare.c | 54 ++++++++++++++++++++++++++++++++++++++++++++----------
9
1 file changed, 44 insertions(+), 10 deletions(-)
10
11
diff --git a/net/colo-compare.c b/net/colo-compare.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/net/colo-compare.c
14
+++ b/net/colo-compare.c
15
@@ -XXX,XX +XXX,XX @@ enum {
16
SECONDARY_IN,
17
};
18
19
-static void colo_compare_inconsistency_notify(void)
20
-{
21
- notifier_list_notify(&colo_compare_notifiers,
22
- migrate_get_current());
23
-}
24
25
static int compare_chr_send(CompareState *s,
26
const uint8_t *buf,
27
@@ -XXX,XX +XXX,XX @@ static int compare_chr_send(CompareState *s,
28
uint32_t vnet_hdr_len,
29
bool notify_remote_frame);
30
31
+static void notify_remote_frame(CompareState *s)
32
+{
33
+ char msg[] = "DO_CHECKPOINT";
34
+ int ret = 0;
35
+
36
+ ret = compare_chr_send(s, (uint8_t *)msg, strlen(msg), 0, true);
37
+ if (ret < 0) {
38
+ error_report("Notify Xen COLO-frame failed");
39
+ }
40
+}
41
+
42
+static void colo_compare_inconsistency_notify(CompareState *s)
43
+{
44
+ if (s->notify_dev) {
45
+ notify_remote_frame(s);
46
+ } else {
47
+ notifier_list_notify(&colo_compare_notifiers,
48
+ migrate_get_current());
49
+ }
50
+}
51
+
52
static gint seq_sorter(Packet *a, Packet *b, gpointer data)
53
{
54
struct tcp_hdr *atcp, *btcp;
55
@@ -XXX,XX +XXX,XX @@ sec:
56
qemu_hexdump((char *)spkt->data, stderr,
57
"colo-compare spkt", spkt->size);
58
59
- colo_compare_inconsistency_notify();
60
+ colo_compare_inconsistency_notify(s);
61
}
62
}
63
64
@@ -XXX,XX +XXX,XX @@ void colo_compare_unregister_notifier(Notifier *notify)
65
}
66
67
static int colo_old_packet_check_one_conn(Connection *conn,
68
- void *user_data)
69
+ CompareState *s)
70
{
71
GList *result = NULL;
72
int64_t check_time = REGULAR_PACKET_CHECK_MS;
73
@@ -XXX,XX +XXX,XX @@ static int colo_old_packet_check_one_conn(Connection *conn,
74
75
if (result) {
76
/* Do checkpoint will flush old packet */
77
- colo_compare_inconsistency_notify();
78
+ colo_compare_inconsistency_notify(s);
79
return 0;
80
}
81
82
@@ -XXX,XX +XXX,XX @@ static void colo_old_packet_check(void *opaque)
83
* If we find one old packet, stop finding job and notify
84
* COLO frame do checkpoint.
85
*/
86
- g_queue_find_custom(&s->conn_list, NULL,
87
+ g_queue_find_custom(&s->conn_list, s,
88
(GCompareFunc)colo_old_packet_check_one_conn);
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static void colo_compare_packet(CompareState *s, Connection *conn,
92
*/
93
trace_colo_compare_main("packet different");
94
g_queue_push_head(&conn->primary_list, pkt);
95
- colo_compare_inconsistency_notify();
96
+
97
+ colo_compare_inconsistency_notify(s);
98
break;
99
}
100
}
101
@@ -XXX,XX +XXX,XX @@ static void compare_sec_rs_finalize(SocketReadState *sec_rs)
102
103
static void compare_notify_rs_finalize(SocketReadState *notify_rs)
104
{
105
+ CompareState *s = container_of(notify_rs, CompareState, notify_rs);
106
+
107
/* Get Xen colo-frame's notify and handle the message */
108
+ char *data = g_memdup(notify_rs->buf, notify_rs->packet_len);
109
+ char msg[] = "COLO_COMPARE_GET_XEN_INIT";
110
+ int ret;
111
+
112
+ if (!strcmp(data, "COLO_USERSPACE_PROXY_INIT")) {
113
+ ret = compare_chr_send(s, (uint8_t *)msg, strlen(msg), 0, true);
114
+ if (ret < 0) {
115
+ error_report("Notify Xen COLO-frame INIT failed");
116
+ }
117
+ }
118
+
119
+ if (!strcmp(data, "COLO_CHECKPOINT")) {
120
+ /* colo-compare do checkpoint, flush pri packet and remove sec packet */
121
+ g_queue_foreach(&s->conn_list, colo_flush_packets, s);
122
+ }
123
}
124
125
/*
126
--
127
2.5.0
128
129
diff view generated by jsdifflib
Deleted patch
1
From: Zhang Chen <chen.zhang@intel.com>
2
1
3
We need to notify net filter to do checkpoint for Xen COLO, like KVM side.
4
5
Signed-off-by: Zhang Chen <chen.zhang@intel.com>
6
Signed-off-by: Jason Wang <jasowang@redhat.com>
7
---
8
migration/colo.c | 2 ++
9
1 file changed, 2 insertions(+)
10
11
diff --git a/migration/colo.c b/migration/colo.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/migration/colo.c
14
+++ b/migration/colo.c
15
@@ -XXX,XX +XXX,XX @@ ReplicationStatus *qmp_query_xen_replication_status(Error **errp)
16
void qmp_xen_colo_do_checkpoint(Error **errp)
17
{
18
replication_do_checkpoint_all(errp);
19
+ /* Notify all filters of all NIC to do checkpoint */
20
+ colo_notify_filters_event(COLO_EVENT_CHECKPOINT, errp);
21
}
22
#endif
23
24
--
25
2.5.0
26
27
diff view generated by jsdifflib