From nobody Mon Apr 13 03:41:43 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1772718761; cv=none; d=zohomail.com; s=zohoarc; b=gc7/Z6NJZ2HOthl6i5si7ztcBcvgzvbdYKDqJ5Mp/vUBqWydpkOYp3TCkkhhTfd5/lkFEWp/3SBi6PwHHMdsbu6BNVHLR2J7ivTJc0cAyBLPNpSrDxIkpNBzf5gJduTCpBtlXyGLah2+yVBm4LeMv5s4JkAa9KtOV+Q6i0zux4I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772718761; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=g9IGAHWgEG6DCdCIzvkRdi4JDcDDT2+/4tidv+QAPpw=; b=b0GlWi7qLF59teb1+MDnm/K2+mQHzmd/YE9snVtbObZNvyHvdXN3d6qfkH7/Wr1BZ5cNZ+nXNFyc40t5IwuTC4yzXJEYLi5NXYZM1qM8oVT8UlcU5ZS+khTGYm7FQvytR0oYWqMA0H/E2/IsTRsQcVMgY20G/MmplHMRUcA6WDI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1772718761819387.0667269660976; Thu, 5 Mar 2026 05:52:41 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246666.1545788 (Exim 4.92) (envelope-from ) id 1vy97o-0000Rd-Q1; Thu, 05 Mar 2026 13:52:24 +0000 Received: by outflank-mailman (output) from mailman id 1246666.1545788; Thu, 05 Mar 2026 13:52:24 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy97o-0000RL-Lp; Thu, 05 Mar 2026 13:52:24 +0000 Received: by outflank-mailman (input) for mailman id 1246666; Thu, 05 Mar 2026 13:52:23 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy97n-00008m-IK for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:52:23 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.223.131]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 8833b762-189a-11f1-9ccf-f158ae23cfc8; Thu, 05 Mar 2026 14:52:21 +0100 (CET) Received: from imap1.dmz-prg2.suse.org (unknown [10.150.64.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 48E335BD8E; Thu, 5 Mar 2026 13:52:21 +0000 (UTC) Received: from imap1.dmz-prg2.suse.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 25A873EA68; Thu, 5 Mar 2026 13:52:21 +0000 (UTC) Received: from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167]) by imap1.dmz-prg2.suse.org with ESMTPSA id qiwdCJWKqWlYTgAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:52:21 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 8833b762-189a-11f1-9ccf-f158ae23cfc8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718741; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g9IGAHWgEG6DCdCIzvkRdi4JDcDDT2+/4tidv+QAPpw=; b=GXk2ra0R2l0UyNGcqR1QsOjJOSvLHndSoaFtUNeNGDQVuPbluI6ANqX3N3c9hQzNG5kzxq LIn/mbbxy4VQlEJmnG49TBOry1E5/gw8tSYRUugBK4J9I1hi5Lwj2y8oubOzQ9JsIkFWsx OB0k8MKFzhWhcFoOGsmDu1HRbxcmqyg= Authentication-Results: smtp-out2.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718741; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=g9IGAHWgEG6DCdCIzvkRdi4JDcDDT2+/4tidv+QAPpw=; b=GXk2ra0R2l0UyNGcqR1QsOjJOSvLHndSoaFtUNeNGDQVuPbluI6ANqX3N3c9hQzNG5kzxq LIn/mbbxy4VQlEJmnG49TBOry1E5/gw8tSYRUugBK4J9I1hi5Lwj2y8oubOzQ9JsIkFWsx OB0k8MKFzhWhcFoOGsmDu1HRbxcmqyg= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Julien Grall , Anthony PERARD Subject: [PATCH 02/11] tools/xenstored: add central quota check functions Date: Thu, 5 Mar 2026 14:51:59 +0100 Message-ID: <20260305135208.2208663-3-jgross@suse.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260305135208.2208663-1-jgross@suse.com> References: <20260305135208.2208663-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Spamd-Result: default: False [-6.79 / 50.00]; REPLY(-4.00)[]; BAYES_HAM(-3.00)[100.00%]; NEURAL_HAM_LONG(-1.00)[-1.000]; MID_CONTAINS_FROM(1.00)[]; R_MISSING_CHARSET(0.50)[]; NEURAL_HAM_SHORT(-0.19)[-0.962]; MIME_GOOD(-0.10)[text/plain]; RCVD_COUNT_TWO(0.00)[2]; FROM_HAS_DN(0.00)[]; ARC_NA(0.00)[]; MIME_TRACE(0.00)[0:+]; TO_DN_SOME(0.00)[]; TO_MATCH_ENVRCPT_ALL(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; DKIM_SIGNED(0.00)[suse.com:s=susede1]; FUZZY_RATELIMITED(0.00)[rspamd.com]; RCPT_COUNT_THREE(0.00)[4]; DBL_BLOCKED_OPENRESOLVER(0.00)[suse.com:mid,suse.com:email,imap1.dmz-prg2.suse.org:helo]; RCVD_TLS_ALL(0.00)[] X-Spam-Flag: NO X-Spam-Score: -6.79 X-Spam-Level: X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1772718764111154100 Content-Type: text/plain; charset="utf-8" Add central functions for checking a value (either an absolute one or the current domain value plus an offset) against a specific quota. This is in preparation of introducing per-domain quota. The required changes allow to drop the "update" parameter from domain_nbentry_fix(). Signed-off-by: Juergen Gross Reviewed-by: Anthony PERARD --- tools/xenstored/core.c | 4 +- tools/xenstored/domain.c | 74 +++++++++++++++++------------------ tools/xenstored/domain.h | 7 ++-- tools/xenstored/transaction.c | 2 +- tools/xenstored/watch.c | 4 +- 5 files changed, 43 insertions(+), 48 deletions(-) diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c index d509736c32..5a4bf3e302 100644 --- a/tools/xenstored/core.c +++ b/tools/xenstored/core.c @@ -1538,7 +1538,7 @@ static struct node *create_node(struct connection *co= nn, const void *ctx, for (i =3D node; i; i =3D i->parent) { /* i->parent is set for each new node, so check quota. */ if (i->parent && - domain_nbentry(conn) >=3D hard_quotas[ACC_NODES].val) { + domain_check_quota_add(conn->domain, ACC_NODES, 1)) { ret =3D ENOSPC; goto err; } @@ -2320,7 +2320,7 @@ void setup_structure(bool live_update) manual_node("/tool/xenstored", NULL); manual_node("@releaseDomain", NULL); manual_node("@introduceDomain", NULL); - domain_nbentry_fix(priv_domid, 5, true); + domain_nbentry_fix(priv_domid, 5); } } =20 diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c index e453b3061f..1df9265ad5 100644 --- a/tools/xenstored/domain.c +++ b/tools/xenstored/domain.c @@ -389,6 +389,25 @@ void wrl_apply_debit_trans_commit(struct connection *c= onn) wrl_apply_debit_actual(conn->domain); } =20 +static bool domain_check_quota_val(struct domain *d, enum accitem what, + unsigned int val) +{ + unsigned int quota =3D hard_quotas[what].val; + + if (!quota || !domid_is_unprivileged(d->domid)) + return false; + + return val >=3D quota; +} + +bool domain_check_quota_add(struct domain *d, enum accitem what, int add) +{ + if (add < 0 || !d) + return false; + + return domain_check_quota_val(d, what, d->acc[what].val + add); +} + static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod) { return ((prod - cons) <=3D XENSTORE_RING_SIZE); @@ -490,10 +509,9 @@ static bool domain_can_read(struct connection *conn) if (domain_is_unprivileged(conn)) { if (domain->wrl_credit < 0) return false; - if (domain->acc[ACC_OUTST].val >=3D hard_quotas[ACC_OUTST].val) + if (domain_check_quota_add(domain, ACC_OUTST, 0)) return false; - if (domain->acc[ACC_MEM].val >=3D hard_quotas[ACC_MEM].val && - hard_quotas[ACC_MEM].val) + if (domain_check_quota_add(domain, ACC_MEM, 0)) return false; } =20 @@ -904,16 +922,20 @@ do { \ =20 int acc_fix_domains(struct list_head *head, bool chk_quota, bool update) { + struct domain *d; struct changed_domain *cd; - int cnt; =20 list_for_each_entry(cd, head, list) { - cnt =3D domain_nbentry_fix(cd->domid, cd->acc[ACC_NODES], update); - if (!update) { - if (chk_quota && cnt >=3D hard_quotas[ACC_NODES].val) - return ENOSPC; - if (cnt < 0) + if (update) { + domain_nbentry_fix(cd->domid, cd->acc[ACC_NODES]); + } else if (chk_quota) { + d =3D find_or_alloc_existing_domain(cd->domid); + + if (!d) return ENOMEM; + if (domain_check_quota_add(d, ACC_NODES, + cd->acc[ACC_NODES])) + return ENOSPC; } } =20 @@ -1732,7 +1754,7 @@ bool domain_max_chk(const struct connection *conn, en= um accitem what, if (!conn || !conn->domain) return false; =20 - if (domain_is_unprivileged(conn) && val > hard_quotas[what].val) + if (domain_check_quota_val(conn->domain, what, val)) return true; =20 domain_acc_valid_max(conn->domain, what, val); @@ -1752,21 +1774,9 @@ int domain_nbentry_dec(struct connection *conn, unsi= gned int domid) ? errno : 0; } =20 -int domain_nbentry_fix(unsigned int domid, int num, bool update) -{ - int ret; - - ret =3D domain_acc_add(NULL, domid, ACC_NODES, update ? num : 0, update); - if (ret < 0 || update) - return ret; - - return domid_is_unprivileged(domid) ? ret + num : 0; -} - -unsigned int domain_nbentry(struct connection *conn) +int domain_nbentry_fix(unsigned int domid, int num) { - return domain_is_unprivileged(conn) - ? domain_acc_add(conn, conn->id, ACC_NODES, 0, true) : 0; + return domain_acc_add(NULL, domid, ACC_NODES, num, true); } =20 static bool domain_chk_quota(struct connection *conn, unsigned int mem) @@ -1781,7 +1791,7 @@ static bool domain_chk_quota(struct connection *conn,= unsigned int mem) domain =3D conn->domain; now =3D time(NULL); =20 - if (mem >=3D hard_quotas[ACC_MEM].val && hard_quotas[ACC_MEM].val) { + if (domain_check_quota_val(domain, ACC_MEM, mem)) { if (domain->hard_quota_reported) return true; syslog(LOG_ERR, "Domain %u exceeds hard memory quota, Xenstore interface= to domain stalled\n", @@ -1857,13 +1867,6 @@ void domain_watch_dec(struct connection *conn) domain_acc_add(conn, conn->id, ACC_WATCH, -1, true); } =20 -int domain_watch(struct connection *conn) -{ - return (domain_is_unprivileged(conn)) - ? domain_acc_add(conn, conn->id, ACC_WATCH, 0, true) - : 0; -} - void domain_outstanding_inc(struct connection *conn) { domain_acc_add(conn, conn->id, ACC_OUTST, 1, true); @@ -1884,13 +1887,6 @@ void domain_transaction_dec(struct connection *conn) domain_acc_add(conn, conn->id, ACC_TRANS, -1, true); } =20 -unsigned int domain_transaction_get(struct connection *conn) -{ - return (domain_is_unprivileged(conn)) - ? domain_acc_add(conn, conn->id, ACC_TRANS, 0, true) - : 0; -} - const char *dump_state_connections(FILE *fp) { const char *ret =3D NULL; diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h index 28186ccac0..b229f6f4e0 100644 --- a/tools/xenstored/domain.h +++ b/tools/xenstored/domain.h @@ -113,8 +113,7 @@ int domain_alloc_permrefs(struct node_perms *perms); /* Quota manipulation */ int domain_nbentry_inc(struct connection *conn, unsigned int domid); int domain_nbentry_dec(struct connection *conn, unsigned int domid); -int domain_nbentry_fix(unsigned int domid, int num, bool update); -unsigned int domain_nbentry(struct connection *conn); +int domain_nbentry_fix(unsigned int domid, int num); int domain_memory_add(struct connection *conn, unsigned int domid, int mem, bool no_quota_check); =20 @@ -141,12 +140,10 @@ static inline void domain_memory_add_nochk(struct con= nection *conn, } void domain_watch_inc(struct connection *conn); void domain_watch_dec(struct connection *conn); -int domain_watch(struct connection *conn); void domain_outstanding_inc(struct connection *conn); void domain_outstanding_dec(struct connection *conn, unsigned int domid); void domain_transaction_inc(struct connection *conn); void domain_transaction_dec(struct connection *conn); -unsigned int domain_transaction_get(struct connection *conn); int domain_get_quota(const void *ctx, struct connection *conn, unsigned int domid); =20 @@ -161,6 +158,8 @@ int domain_max_global_acc(const void *ctx, struct conne= ction *conn); void domain_reset_global_acc(void); bool domain_max_chk(const struct connection *conn, enum accitem what, unsigned int val); +bool domain_check_quota_add(struct domain *d, enum accitem what, + int add); =20 extern long wrl_ntransactions; =20 diff --git a/tools/xenstored/transaction.c b/tools/xenstored/transaction.c index 167cd597fd..ccf93a1132 100644 --- a/tools/xenstored/transaction.c +++ b/tools/xenstored/transaction.c @@ -470,7 +470,7 @@ int do_transaction_start(const void *ctx, struct connec= tion *conn, if (conn->transaction) return EBUSY; =20 - if (domain_transaction_get(conn) > hard_quotas[ACC_TRANS].val) + if (domain_check_quota_add(conn->domain, ACC_TRANS, 1)) return ENOSPC; =20 /* Attach transaction to ctx for autofree until it's complete */ diff --git a/tools/xenstored/watch.c b/tools/xenstored/watch.c index b66a9f1a39..36e4d33f22 100644 --- a/tools/xenstored/watch.c +++ b/tools/xenstored/watch.c @@ -220,8 +220,8 @@ int do_watch(const void *ctx, struct connection *conn, = struct buffered_data *in) return EEXIST; } =20 - if (domain_watch(conn) > hard_quotas[ACC_WATCH].val) - return E2BIG; + if (domain_check_quota_add(conn->domain, ACC_WATCH, 1)) + return ENOSPC; =20 watch =3D add_watch(conn, vec[0], vec[1], relative, false); if (!watch) --=20 2.53.0