diff options
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.patch | 93 |
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 + |