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; 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=fail(p=quarantine dis=quarantine) header.from=suse.com Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1772718777140201.16282419131903; Thu, 5 Mar 2026 05:52:57 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246687.1545827 (Exim 4.92) (envelope-from ) id 1vy988-00023M-R6; Thu, 05 Mar 2026 13:52:44 +0000 Received: by outflank-mailman (output) from mailman id 1246687.1545827; Thu, 05 Mar 2026 13:52:44 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy988-00023B-Nh; Thu, 05 Mar 2026 13:52:44 +0000 Received: by outflank-mailman (input) for mailman id 1246687; Thu, 05 Mar 2026 13:52:44 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy988-0008Mq-1F for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:52:44 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [2a07:de40:b251:101:10:150:64:1]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 95177d18-189a-11f1-b164-2bf370ae4941; Thu, 05 Mar 2026 14:52:43 +0100 (CET) Received: from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org [IPv6:2a07:de40:b281:104: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-out1.suse.de (Postfix) with ESMTPS id 0C8B83F925; Thu, 5 Mar 2026 13:52:43 +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 DF2243EA68; Thu, 5 Mar 2026 13:52:42 +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 QQRMNaqKqWkITwAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:52:42 +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: 95177d18-189a-11f1-b164-2bf370ae4941 Authentication-Results: smtp-out1.suse.de; none From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Julien Grall , Anthony PERARD Subject: [PATCH 06/11] tools/xenstored: add infrastructure for per-domain quotas Date: Thu, 5 Mar 2026 14:52:03 +0100 Message-ID: <20260305135208.2208663-7-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-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-Rspamd-Queue-Id: 0C8B83F925 X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-Rspamd-Action: no action X-Spam-Score: -4.00 X-Spam-Level: X-Spam-Flag: NO X-Spamd-Result: default: False [-4.00 / 50.00]; REPLY(-4.00)[] X-Rspamd-Server: rspamd1.dmz-prg2.suse.org X-ZM-MESSAGEID: 1772718780218154100 Content-Type: text/plain; charset="utf-8" Add the needed structures and helper functions for supporting quotas per domain. Signed-off-by: Juergen Gross Reviewed-by: Anthony PERARD --- tools/xenstored/domain.c | 59 ++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c index 9bd3ac7aca..8e52351695 100644 --- a/tools/xenstored/domain.c +++ b/tools/xenstored/domain.c @@ -389,6 +389,9 @@ void wrl_apply_debit_trans_commit(struct connection *co= nn) =20 static unsigned int domain_get_soft_quota(struct domain *d, enum accitem w= hat) { + if (d && d->acc[what].val[Q_IDX_SOFT] !=3D Q_VAL_DISABLED) + return d->acc[what].val[Q_IDX_SOFT]; + return quotas[what].val[Q_IDX_SOFT]; } =20 @@ -397,6 +400,9 @@ static bool domain_check_quota_val(struct domain *d, en= um accitem what, { unsigned int quota =3D quotas[what].val[Q_IDX_HARD]; =20 + if (d->acc[what].val[Q_IDX_HARD] !=3D Q_VAL_DISABLED) + quota =3D d->acc[what].val[Q_IDX_HARD]; + if (!quota || !domid_is_unprivileged(d->domid)) return false; =20 @@ -809,6 +815,7 @@ static struct domain *alloc_domain(const void *context,= unsigned int domid, uint64_t unique_id) { struct domain *domain; + unsigned int q; =20 domain =3D talloc_zero(context, struct domain); if (!domain) { @@ -822,6 +829,11 @@ static struct domain *alloc_domain(const void *context= , unsigned int domid, domain->introduced =3D false; domain->features =3D XENSTORE_FEATURES; =20 + for (q =3D 0; q < ACC_N; q++) { + domain->acc[q].val[Q_IDX_HARD] =3D quotas[q].val[Q_IDX_HARD]; + domain->acc[q].val[Q_IDX_SOFT] =3D quotas[q].val[Q_IDX_SOFT]; + } + if (hashtable_add(domhash, &domain->domid, domain)) { talloc_free(domain); errno =3D ENOMEM; @@ -2079,25 +2091,38 @@ static int dump_state_domain(const void *k, void *v= , void *arg) { struct domain *domain =3D v; FILE *fp =3D arg; - struct xs_state_domain sd; - struct xs_state_record_header head; - - head.type =3D XS_STATE_TYPE_DOMAIN; - head.length =3D sizeof(sd); - memset(&sd, 0, sizeof(sd)); - sd.domain_id =3D domain->domid; + struct xs_state_domain *sd; + struct xs_state_record_header *head; + void *record; + unsigned int n_quota; + unsigned int len =3D sizeof(*sd); + size_t ret; =20 - if (lu_status->version > 1) - sd.features =3D domain->features; + n_quota =3D get_quota_size(domain->acc, &len); + len +=3D n_quota * sizeof(sd->quota_val[0]); + len =3D ROUNDUP(len, 3); =20 - if (fwrite(&head, sizeof(head), 1, fp) !=3D 1) - return 1; - if (fwrite(&sd, sizeof(sd), 1, fp) !=3D 1) - return 1; - if (dump_state_align(fp)) + record =3D talloc_size(NULL, len + sizeof(*head)); + if (!record) return 1; =20 - return 0; + head =3D record; + head->type =3D XS_STATE_TYPE_DOMAIN; + head->length =3D len; + + sd =3D (struct xs_state_domain *)(head + 1); + sd->domain_id =3D domain->domid; + sd->n_quota =3D n_quota; + sd->features =3D (lu_status->version > 1) ? domain->features : 0; + + build_quota_data(domain->acc, sd->quota_val, + (char *)(sd->quota_val + n_quota)); + + ret =3D fwrite(record, len + sizeof(*head), 1, fp); + + talloc_free(record); + + return (ret !=3D 1 || dump_state_align(fp)) ? 1 : 0; } =20 const char *dump_state_domains(FILE *fp) @@ -2114,6 +2139,8 @@ void read_state_domain(const void *ctx, const void *s= tate, unsigned int version) { const struct xs_state_domain *sd =3D state; struct domain *domain; + unsigned int n_quota =3D sd->n_quota; + const char *name =3D (const char *)(sd->quota_val + n_quota); =20 domain =3D find_domain_struct(sd->domain_id); if (!domain) @@ -2121,6 +2148,8 @@ void read_state_domain(const void *ctx, const void *s= tate, unsigned int version) =20 if (version > 1) domain->features =3D sd->features; + + parse_quota_data(sd->quota_val, name, n_quota, domain->acc); } =20 const char *dump_state_glb_quota(FILE *fp) --=20 2.53.0