summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0090-tools-xenstore-don-t-buffer-multiple-identical-watch.patch')
-rw-r--r--0090-tools-xenstore-don-t-buffer-multiple-identical-watch.patch93
1 files changed, 93 insertions, 0 deletions
diff --git a/0090-tools-xenstore-don-t-buffer-multiple-identical-watch.patch b/0090-tools-xenstore-don-t-buffer-multiple-identical-watch.patch
new file mode 100644
index 0000000..305d8ac
--- /dev/null
+++ b/0090-tools-xenstore-don-t-buffer-multiple-identical-watch.patch
@@ -0,0 +1,93 @@
+From 97c251f953c58aec7620499ac12924054b7cd758 Mon Sep 17 00:00:00 2001
+From: Juergen Gross <jgross@suse.com>
+Date: Tue, 13 Sep 2022 07:35:08 +0200
+Subject: [PATCH 090/126] tools/xenstore: don't buffer multiple identical watch
+ events
+
+A guest not reading its Xenstore response buffer fast enough might
+pile up lots of Xenstore watch events buffered. Reduce the generated
+load by dropping new events which already have an identical copy
+pending.
+
+The special events "@..." are excluded from that handling as there are
+known use cases where the handler is relying on each event to be sent
+individually.
+
+This is part of XSA-326.
+
+Signed-off-by: Juergen Gross <jgross@suse.com>
+Reviewed-by: Julien Grall <jgrall@amazon.com>
+(cherry picked from commit b5c0bdb96d33e18c324c13d8e33c08732d77eaa2)
+---
+ tools/xenstore/xenstored_core.c | 20 +++++++++++++++++++-
+ tools/xenstore/xenstored_core.h | 3 +++
+ 2 files changed, 22 insertions(+), 1 deletion(-)
+
+diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
+index d871f217af9c..6ea06e20df91 100644
+--- a/tools/xenstore/xenstored_core.c
++++ b/tools/xenstore/xenstored_core.c
+@@ -882,6 +882,7 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
+ bdata->inhdr = true;
+ bdata->used = 0;
+ bdata->timeout_msec = 0;
++ bdata->watch_event = false;
+
+ if (len <= DEFAULT_BUFFER_SIZE)
+ bdata->buffer = bdata->default_buffer;
+@@ -914,7 +915,7 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type,
+ void send_event(struct buffered_data *req, struct connection *conn,
+ const char *path, const char *token)
+ {
+- struct buffered_data *bdata;
++ struct buffered_data *bdata, *bd;
+ unsigned int len;
+
+ len = strlen(path) + 1 + strlen(token) + 1;
+@@ -936,12 +937,29 @@ void send_event(struct buffered_data *req, struct connection *conn,
+ bdata->hdr.msg.type = XS_WATCH_EVENT;
+ bdata->hdr.msg.len = len;
+
++ /*
++ * Check whether an identical event is pending already.
++ * Special events are excluded from that check.
++ */
++ if (path[0] != '@') {
++ list_for_each_entry(bd, &conn->out_list, list) {
++ if (bd->watch_event && bd->hdr.msg.len == len &&
++ !memcmp(bdata->buffer, bd->buffer, len)) {
++ trace("dropping duplicate watch %s %s for domain %u\n",
++ path, token, conn->id);
++ talloc_free(bdata);
++ return;
++ }
++ }
++ }
++
+ if (timeout_watch_event_msec && domain_is_unprivileged(conn)) {
+ bdata->timeout_msec = get_now_msec() + timeout_watch_event_msec;
+ if (!conn->timeout_msec)
+ conn->timeout_msec = bdata->timeout_msec;
+ }
+
++ bdata->watch_event = true;
+ bdata->pend.req = req;
+ if (req)
+ req->pend.ref.event_cnt++;
+diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
+index fcb27399f116..afbd982c2654 100644
+--- a/tools/xenstore/xenstored_core.h
++++ b/tools/xenstore/xenstored_core.h
+@@ -62,6 +62,9 @@ struct buffered_data
+ /* Are we still doing the header? */
+ bool inhdr;
+
++ /* Is this a watch event? */
++ bool watch_event;
++
+ /* How far are we? */
+ unsigned int used;
+
+--
+2.37.4
+