summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0095-tools-xenstore-add-infrastructure-to-keep-track-of-p.patch')
-rw-r--r--0095-tools-xenstore-add-infrastructure-to-keep-track-of-p.patch289
1 files changed, 0 insertions, 289 deletions
diff --git a/0095-tools-xenstore-add-infrastructure-to-keep-track-of-p.patch b/0095-tools-xenstore-add-infrastructure-to-keep-track-of-p.patch
deleted file mode 100644
index f826f80..0000000
--- a/0095-tools-xenstore-add-infrastructure-to-keep-track-of-p.patch
+++ /dev/null
@@ -1,289 +0,0 @@
-From aa29eb624797fb6825e4a23071c88417672868a4 Mon Sep 17 00:00:00 2001
-From: Juergen Gross <jgross@suse.com>
-Date: Tue, 13 Sep 2022 07:35:09 +0200
-Subject: [PATCH 095/126] tools/xenstore: add infrastructure to keep track of
- per domain memory usage
-
-The amount of memory a domain can consume in Xenstore is limited by
-various quota today, but even with sane quota a domain can still
-consume rather large memory quantities.
-
-Add the infrastructure for keeping track of the amount of memory a
-domain is consuming in Xenstore. Note that this is only the memory a
-domain has direct control over, so any internal administration data
-needed by Xenstore only is not being accounted for.
-
-There are two quotas defined: a soft quota which will result in a
-warning issued via syslog() when it is exceeded, and a hard quota
-resulting in a stop of accepting further requests or watch events as
-long as the hard quota would be violated by accepting those.
-
-Setting any of those quotas to 0 will disable it.
-
-As default values use 2MB per domain for the soft limit (this basically
-covers the allowed case to create 1000 nodes needing 2kB each), and
-2.5MB for the hard limit.
-
-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 0d4a8ec7a93faedbe54fd197db146de628459e77)
----
- tools/xenstore/xenstored_core.c | 30 ++++++++--
- tools/xenstore/xenstored_core.h | 2 +
- tools/xenstore/xenstored_domain.c | 93 +++++++++++++++++++++++++++++++
- tools/xenstore/xenstored_domain.h | 20 +++++++
- 4 files changed, 139 insertions(+), 6 deletions(-)
-
-diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
-index 51af74390cbe..eeb0d893e8c3 100644
---- a/tools/xenstore/xenstored_core.c
-+++ b/tools/xenstore/xenstored_core.c
-@@ -109,6 +109,8 @@ int quota_nb_perms_per_node = 5;
- int quota_trans_nodes = 1024;
- int quota_max_path_len = XENSTORE_REL_PATH_MAX;
- int quota_req_outstanding = 20;
-+int quota_memory_per_domain_soft = 2 * 1024 * 1024; /* 2 MB */
-+int quota_memory_per_domain_hard = 2 * 1024 * 1024 + 512 * 1024; /* 2.5 MB */
-
- unsigned int timeout_watch_event_msec = 20000;
-
-@@ -2304,7 +2306,14 @@ static void usage(void)
- " quotas are:\n"
- " transaction-nodes: number of accessed node per\n"
- " transaction\n"
-+" memory: total used memory per domain for nodes,\n"
-+" transactions, watches and requests, above\n"
-+" which Xenstore will stop talking to domain\n"
- " outstanding: number of outstanding requests\n"
-+" -q, --quota-soft <what>=<nb> set a soft quota <what> to the value <nb>,\n"
-+" causing a warning to be issued via syslog() if the\n"
-+" limit is violated, allowed quotas are:\n"
-+" memory: see above\n"
- " -w, --timeout <what>=<seconds> set the timeout in seconds for <what>,\n"
- " allowed timeout candidates are:\n"
- " watch-event: time a watch-event is kept pending\n"
-@@ -2331,6 +2340,7 @@ static struct option options[] = {
- { "perm-nb", 1, NULL, 'A' },
- { "path-max", 1, NULL, 'M' },
- { "quota", 1, NULL, 'Q' },
-+ { "quota-soft", 1, NULL, 'q' },
- { "timeout", 1, NULL, 'w' },
- { "no-recovery", 0, NULL, 'R' },
- { "internal-db", 0, NULL, 'I' },
-@@ -2379,7 +2389,7 @@ static void set_timeout(const char *arg)
- barf("unknown timeout \"%s\"\n", arg);
- }
-
--static void set_quota(const char *arg)
-+static void set_quota(const char *arg, bool soft)
- {
- const char *eq = strchr(arg, '=');
- int val;
-@@ -2387,11 +2397,16 @@ static void set_quota(const char *arg)
- if (!eq)
- barf("quotas must be specified via <what>=<nb>\n");
- val = get_optval_int(eq + 1);
-- if (what_matches(arg, "outstanding"))
-+ if (what_matches(arg, "outstanding") && !soft)
- quota_req_outstanding = val;
-- else if (what_matches(arg, "transaction-nodes"))
-+ else if (what_matches(arg, "transaction-nodes") && !soft)
- quota_trans_nodes = val;
-- else
-+ else if (what_matches(arg, "memory")) {
-+ if (soft)
-+ quota_memory_per_domain_soft = val;
-+ else
-+ quota_memory_per_domain_hard = val;
-+ } else
- barf("unknown quota \"%s\"\n", arg);
- }
-
-@@ -2409,7 +2424,7 @@ int main(int argc, char *argv[])
- orig_argc = argc;
- orig_argv = argv;
-
-- while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:M:Q:T:RVW:w:U",
-+ while ((opt = getopt_long(argc, argv, "DE:F:HNPS:t:A:M:Q:q:T:RVW:w:U",
- options, NULL)) != -1) {
- switch (opt) {
- case 'D':
-@@ -2459,7 +2474,10 @@ int main(int argc, char *argv[])
- quota_max_path_len);
- break;
- case 'Q':
-- set_quota(optarg);
-+ set_quota(optarg, false);
-+ break;
-+ case 'q':
-+ set_quota(optarg, true);
- break;
- case 'w':
- set_timeout(optarg);
-diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
-index 459698d8407a..2fb37dbfe847 100644
---- a/tools/xenstore/xenstored_core.h
-+++ b/tools/xenstore/xenstored_core.h
-@@ -263,6 +263,8 @@ extern int priv_domid;
- extern int quota_nb_entry_per_domain;
- extern int quota_req_outstanding;
- extern int quota_trans_nodes;
-+extern int quota_memory_per_domain_soft;
-+extern int quota_memory_per_domain_hard;
-
- extern unsigned int timeout_watch_event_msec;
-
-diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c
-index 0dd75a6a2194..ec542df6a67e 100644
---- a/tools/xenstore/xenstored_domain.c
-+++ b/tools/xenstore/xenstored_domain.c
-@@ -76,6 +76,13 @@ struct domain
- /* number of entry from this domain in the store */
- int nbentry;
-
-+ /* Amount of memory allocated for this domain. */
-+ int memory;
-+ bool soft_quota_reported;
-+ bool hard_quota_reported;
-+ time_t mem_last_msg;
-+#define MEM_WARN_MINTIME_SEC 10
-+
- /* number of watch for this domain */
- int nbwatch;
-
-@@ -296,6 +303,9 @@ bool domain_can_read(struct connection *conn)
- return false;
- if (conn->domain->nboutstanding >= quota_req_outstanding)
- return false;
-+ if (conn->domain->memory >= quota_memory_per_domain_hard &&
-+ quota_memory_per_domain_hard)
-+ return false;
- }
-
- if (conn->is_ignored)
-@@ -956,6 +966,89 @@ int domain_entry(struct connection *conn)
- : 0;
- }
-
-+static bool domain_chk_quota(struct domain *domain, int mem)
-+{
-+ time_t now;
-+
-+ if (!domain || !domid_is_unprivileged(domain->domid) ||
-+ (domain->conn && domain->conn->is_ignored))
-+ return false;
-+
-+ now = time(NULL);
-+
-+ if (mem >= quota_memory_per_domain_hard &&
-+ quota_memory_per_domain_hard) {
-+ if (domain->hard_quota_reported)
-+ return true;
-+ syslog(LOG_ERR, "Domain %u exceeds hard memory quota, Xenstore interface to domain stalled\n",
-+ domain->domid);
-+ domain->mem_last_msg = now;
-+ domain->hard_quota_reported = true;
-+ return true;
-+ }
-+
-+ if (now - domain->mem_last_msg >= MEM_WARN_MINTIME_SEC) {
-+ if (domain->hard_quota_reported) {
-+ domain->mem_last_msg = now;
-+ domain->hard_quota_reported = false;
-+ syslog(LOG_INFO, "Domain %u below hard memory quota again\n",
-+ domain->domid);
-+ }
-+ if (mem >= quota_memory_per_domain_soft &&
-+ quota_memory_per_domain_soft &&
-+ !domain->soft_quota_reported) {
-+ domain->mem_last_msg = now;
-+ domain->soft_quota_reported = true;
-+ syslog(LOG_WARNING, "Domain %u exceeds soft memory quota\n",
-+ domain->domid);
-+ }
-+ if (mem < quota_memory_per_domain_soft &&
-+ domain->soft_quota_reported) {
-+ domain->mem_last_msg = now;
-+ domain->soft_quota_reported = false;
-+ syslog(LOG_INFO, "Domain %u below soft memory quota again\n",
-+ domain->domid);
-+ }
-+
-+ }
-+
-+ return false;
-+}
-+
-+int domain_memory_add(unsigned int domid, int mem, bool no_quota_check)
-+{
-+ struct domain *domain;
-+
-+ domain = find_domain_struct(domid);
-+ if (domain) {
-+ /*
-+ * domain_chk_quota() will print warning and also store whether
-+ * the soft/hard quota has been hit. So check no_quota_check
-+ * *after*.
-+ */
-+ if (domain_chk_quota(domain, domain->memory + mem) &&
-+ !no_quota_check)
-+ return ENOMEM;
-+ domain->memory += mem;
-+ } else {
-+ /*
-+ * The domain the memory is to be accounted for should always
-+ * exist, as accounting is done either for a domain related to
-+ * the current connection, or for the domain owning a node
-+ * (which is always existing, as the owner of the node is
-+ * tested to exist and replaced by domid 0 if not).
-+ * So not finding the related domain MUST be an error in the
-+ * data base.
-+ */
-+ errno = ENOENT;
-+ corrupt(NULL, "Accounting called for non-existing domain %u\n",
-+ domid);
-+ return ENOENT;
-+ }
-+
-+ return 0;
-+}
-+
- void domain_watch_inc(struct connection *conn)
- {
- if (!conn || !conn->domain)
-diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h
-index cce13d14f016..571aa46d158e 100644
---- a/tools/xenstore/xenstored_domain.h
-+++ b/tools/xenstore/xenstored_domain.h
-@@ -65,6 +65,26 @@ int domain_entry_inc(struct connection *conn, struct node *);
- void domain_entry_dec(struct connection *conn, struct node *);
- int domain_entry_fix(unsigned int domid, int num, bool update);
- int domain_entry(struct connection *conn);
-+int domain_memory_add(unsigned int domid, int mem, bool no_quota_check);
-+
-+/*
-+ * domain_memory_add_chk(): to be used when memory quota should be checked.
-+ * Not to be used when specifying a negative mem value, as lowering the used
-+ * memory should always be allowed.
-+ */
-+static inline int domain_memory_add_chk(unsigned int domid, int mem)
-+{
-+ return domain_memory_add(domid, mem, false);
-+}
-+/*
-+ * domain_memory_add_nochk(): to be used when memory quota should not be
-+ * checked, e.g. when lowering memory usage, or in an error case for undoing
-+ * a previous memory adjustment.
-+ */
-+static inline void domain_memory_add_nochk(unsigned int domid, int mem)
-+{
-+ domain_memory_add(domid, mem, true);
-+}
- void domain_watch_inc(struct connection *conn);
- void domain_watch_dec(struct connection *conn);
- int domain_watch(struct connection *conn);
---
-2.37.4
-