All of lore.kernel.org
 help / color / mirror / Atom feed
From: Juergen Gross <jgross@suse.com>
To: xen-devel@lists.xenproject.org
Cc: Juergen Gross <jgross@suse.com>, Julien Grall <julien@xen.org>,
	Anthony PERARD <anthony.perard@vates.tech>
Subject: [PATCH 04/11] tools/xenstored: add GLOBAL_QUOTA_DATA record for live update
Date: Thu,  5 Mar 2026 14:52:01 +0100	[thread overview]
Message-ID: <20260305135208.2208663-5-jgross@suse.com> (raw)
In-Reply-To: <20260305135208.2208663-1-jgross@suse.com>

Communicate the global quota settings via the GLOBAL_QUOTA_DATA
record to the new Xenstore instance.

This avoids to lose global quota settings done via xenstore-control.

In theory it would be possible to drop any quota related command line
parameters in the live update case, but they don't do any harm, as
the record data is applied on top of the command line data.

For soft-quota just prepend "soft-" to the quota name.

Use sub-functions for building and analyzing the quota part of the
migration stream, as they will be reused for per-domain quotas.

Signed-off-by: Juergen Gross <jgross@suse.com>
---
 tools/xenstored/domain.c | 123 +++++++++++++++++++++++++++++++++++++++
 tools/xenstored/domain.h |   2 +
 tools/xenstored/lu.c     |   6 ++
 3 files changed, 131 insertions(+)

diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c
index acdcaa769e..694ae58973 100644
--- a/tools/xenstored/domain.c
+++ b/tools/xenstored/domain.c
@@ -1332,6 +1332,27 @@ int do_set_feature(const void *ctx, struct connection *conn,
 	return 0;
 }
 
+static bool parse_quota_name(const char *name, unsigned int *qidx,
+			     unsigned int *idx)
+{
+	unsigned int q;
+
+	if (strncmp(name, "soft-", 5)) {
+		*idx = Q_IDX_HARD;
+	} else {
+		*idx = Q_IDX_SOFT;
+		name += 5;
+	}
+	for (q = 0; q < ACC_N; q++) {
+		if (quota_adm[q].name && !strcmp(quota_adm[q].name, name)) {
+			*qidx = q;
+			return false;
+		}
+	}
+
+	return true;
+}
+
 static int close_xgt_handle(void *_handle)
 {
 	xengnttab_close(*(xengnttab_handle **)_handle);
@@ -2001,6 +2022,61 @@ void read_state_connection(const void *ctx, const void *state)
 	}
 }
 
+static unsigned int get_quota_size(struct quota *quota, unsigned int *len)
+{
+	unsigned int q;
+	unsigned int n = 0;
+
+	for (q = 0; q < ACC_N; q++) {
+		if (!quota_adm[q].name)
+			continue;
+		if (quota[q].val[Q_IDX_HARD] != Q_VAL_DISABLED) {
+			n++;
+			*len += strlen(quota_adm[q].name) + 1;
+		}
+		if (quota[q].val[Q_IDX_SOFT] != Q_VAL_DISABLED) {
+			n++;
+			*len += strlen(quota_adm[q].name) + 5 + 1;
+		}
+	}
+
+	return n;
+}
+
+static void build_quota_data(struct quota *quota, uint32_t *val, char *name)
+{
+	unsigned int q;
+	unsigned int n = 0;
+
+	for (q = 0; q < ACC_N; q++) {
+		if (!quota_adm[q].name)
+			continue;
+		if (quota[q].val[Q_IDX_HARD] != Q_VAL_DISABLED) {
+			val[n++] = quota[q].val[Q_IDX_HARD];
+			strcpy(name, quota_adm[q].name);
+			name += strlen(name) + 1;
+		}
+		if (quota[q].val[Q_IDX_SOFT] != Q_VAL_DISABLED) {
+			val[n++] = quota[q].val[Q_IDX_SOFT];
+			strcpy(name, "soft-");
+			strcpy(name + 5, quota_adm[q].name);
+			name += strlen(name) + 1;
+		}
+	}
+}
+
+static void parse_quota_data(const uint32_t *val, const char *name,
+			     unsigned int n, struct quota *quota)
+{
+	unsigned int i, q, idx;
+
+	for (i = 0; i < n; i++) {
+		if (!parse_quota_name(name, &q, &idx))
+			quota[q].val[idx] = val[i];
+		name += strlen(name) + 1;
+	}
+}
+
 static int dump_state_domain(const void *k, void *v, void *arg)
 {
 	struct domain *domain = v;
@@ -2049,6 +2125,53 @@ void read_state_domain(const void *ctx, const void *state, unsigned int version)
 		domain->features = sd->features;
 }
 
+const char *dump_state_glb_quota(FILE *fp)
+{
+	struct xs_state_record_header *head;
+	struct xs_state_glb_quota *glb;
+	void *record;
+	unsigned int n_quota;
+	unsigned int len = sizeof(*glb);
+	size_t ret;
+
+	n_quota = get_quota_size(quotas, &len);
+	len += n_quota * sizeof(glb->quota_val[0]);
+	len = ROUNDUP(len, 3);
+
+	record = talloc_size(NULL, len + sizeof(*head));
+	if (!record)
+		return "Dump global quota allocation error";
+
+	head = record;
+	head->type = XS_STATE_TYPE_GLB_QUOTA;
+	head->length = len;
+
+	glb = (struct xs_state_glb_quota *)(head + 1);
+	glb->n_dom_quota = n_quota;
+	glb->n_glob_quota = 0;
+
+	build_quota_data(quotas, glb->quota_val,
+			 (char *)(glb->quota_val + n_quota));
+
+	ret = fwrite(record, len + sizeof(*head), 1, fp);
+
+	talloc_free(record);
+
+	if (ret != 1 || dump_state_align(fp))
+		return "Dump global quota error";
+
+	return NULL;
+}
+
+void read_state_glb_quota(const void *ctx, const void *state)
+{
+	const struct xs_state_glb_quota *glb = state;
+	unsigned int n_quota = glb->n_dom_quota + glb->n_glob_quota;
+	const char *name = (const char *)(glb->quota_val + n_quota);
+
+	parse_quota_data(glb->quota_val, name, n_quota, quotas);
+}
+
 struct domain_acc {
 	unsigned int domid;
 	int nodes;
diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h
index a6db358fdc..62ce3b3166 100644
--- a/tools/xenstored/domain.h
+++ b/tools/xenstored/domain.h
@@ -173,10 +173,12 @@ void wrl_apply_debit_trans_commit(struct connection *conn);
 
 const char *dump_state_connections(FILE *fp);
 const char *dump_state_domains(FILE *fp);
+const char *dump_state_glb_quota(FILE *fp);
 
 void read_state_connection(const void *ctx, const void *state);
 void read_state_domain(const void *ctx, const void *state,
 		       unsigned int version);
+void read_state_glb_quota(const void *ctx, const void *state);
 
 struct hashtable *domain_check_acc_init(void);
 void domain_check_acc_add(const struct node *node, struct hashtable *domains);
diff --git a/tools/xenstored/lu.c b/tools/xenstored/lu.c
index fa8395eb1e..eaffdbc69e 100644
--- a/tools/xenstored/lu.c
+++ b/tools/xenstored/lu.c
@@ -192,6 +192,9 @@ void lu_read_state(void)
 		case XS_STATE_TYPE_DOMAIN:
 			read_state_domain(ctx, state.buf, version);
 			break;
+		case XS_STATE_TYPE_GLB_QUOTA:
+			read_state_glb_quota(ctx, state.buf);
+			break;
 		default:
 			xprintf("live-update: unknown state record %08x\n",
 				head.type);
@@ -319,6 +322,9 @@ static const char *lu_dump_state(const void *ctx, struct connection *conn)
 	}
 
 	ret = dump_state_global(fp);
+	if (ret)
+		goto out;
+	ret = dump_state_glb_quota(fp);
 	if (ret)
 		goto out;
 	ret = dump_state_connections(fp);
-- 
2.53.0



  parent reply	other threads:[~2026-03-05 13:52 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-05 13:51 [PATCH 00/11] tools: add support for per-domain xenstore quota Juergen Gross
2026-03-05 13:51 ` [PATCH 01/11] tools/libs/store: add get- and set-quota related functions Juergen Gross
2026-03-13 14:23   ` Anthony PERARD
2026-03-16  7:51     ` Jürgen Groß
2026-03-19 13:31       ` Anthony PERARD
2026-03-05 13:51 ` [PATCH 02/11] tools/xenstored: add central quota check functions Juergen Gross
2026-03-13 15:01   ` Anthony PERARD
2026-03-16  7:53     ` Jürgen Groß
2026-03-13 21:22   ` Jason Andryuk
2026-03-16  8:18     ` Jürgen Groß
2026-03-05 13:52 ` [PATCH 03/11] tools/xenstored: rework hard_quotas and soft_quotas arrays Juergen Gross
2026-03-13 16:09   ` Anthony PERARD
2026-03-05 13:52 ` Juergen Gross [this message]
2026-03-13 17:08   ` [PATCH 04/11] tools/xenstored: add GLOBAL_QUOTA_DATA record for live update Anthony PERARD
2026-03-16  8:15     ` Jürgen Groß
2026-03-18 12:16       ` Juergen Gross
2026-03-19 16:15         ` Anthony PERARD
2026-03-19 16:31           ` Jürgen Groß
2026-03-19 15:59       ` Anthony PERARD
2026-03-05 13:52 ` [PATCH 05/11] tools/xenstored: split acc[] array in struct domain Juergen Gross
2026-03-13 17:15   ` Anthony PERARD
2026-03-05 13:52 ` [PATCH 06/11] tools/xenstored: add infrastructure for per-domain quotas Juergen Gross
2026-03-13 17:32   ` Anthony PERARD
2026-03-16  8:17     ` Jürgen Groß
2026-03-05 13:52 ` [PATCH 07/11] tools/xenstored: implement the GET/SET_QUOTA commands Juergen Gross
2026-03-16 15:08   ` Anthony PERARD
2026-03-16 15:27     ` Juergen Gross
2026-03-19 16:47       ` Anthony PERARD
2026-03-20  6:36         ` Jürgen Groß
2026-03-05 13:52 ` [PATCH 08/11] tools/libxl: add functions for retrieving and setting xenstore quota Juergen Gross
2026-03-10 13:58   ` Nick Rosbrook
2026-03-19  9:11   ` Anthony PERARD
2026-03-19 11:00     ` Jürgen Groß
2026-03-05 13:52 ` [PATCH 09/11] tools/libxl: add support for xenstore quota in domain_config Juergen Gross
2026-03-10 13:57   ` Nick Rosbrook
2026-03-19  9:26   ` Anthony PERARD
2026-03-19 11:01     ` Jürgen Groß
2026-03-05 13:52 ` [PATCH 10/11] tools/xl: add xl commands for xenstore quota operations Juergen Gross
2026-03-19 12:37   ` Anthony PERARD
2026-03-19 13:06     ` Jürgen Groß
2026-03-05 13:52 ` [PATCH 11/11] tools/xl: add support for xenstore quota setting via domain config Juergen Gross
2026-03-19 13:06   ` Anthony PERARD
2026-03-19 13:11     ` Jürgen Groß

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260305135208.2208663-5-jgross@suse.com \
    --to=jgross@suse.com \
    --cc=anthony.perard@vates.tech \
    --cc=julien@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.