From nobody Mon Apr 13 02:02:06 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=1772718757; cv=none; d=zohomail.com; s=zohoarc; b=drAa5XboPCFCkBwpbDOz6hFmcqRDnOmkNEltuq7wmRAvuVGKWhcSrvkGJfe8a97DhnmNnfTLYwVQm/gk1ZIGkHc9D/1P78dy5MDii/e2Xh8hVJRi7FQbZec2+OC+t71Hz5PeSIhfOos/bNLNsvZwHLr8fn+cAd/SBXWJIjjQOb0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772718757; 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=naD83YlbZGL27ewgtMQ3AW6P3o75RusmiaznD0RxnhM=; b=WrLoNUBziqD7MarakR61tWxwRzP6j+ntU9JEjB2SYY1q/0NFlMIgAkdaYu6UiGUpRVeWs9ZIVfHR8PO/pjuRdZ4eB6b9enUxeBtQRWBgEYrSGYMThoI5Efu68wwVPN4qQUC8NulBNfCmk///dfPQ9EaV9oxmw7nvfcuZNHnDufc= 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 1772718757367106.45846248480711; Thu, 5 Mar 2026 05:52:37 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246665.1545777 (Exim 4.92) (envelope-from ) id 1vy97j-00009H-E3; Thu, 05 Mar 2026 13:52:19 +0000 Received: by outflank-mailman (output) from mailman id 1246665.1545777; Thu, 05 Mar 2026 13:52:19 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy97j-00009A-BL; Thu, 05 Mar 2026 13:52:19 +0000 Received: by outflank-mailman (input) for mailman id 1246665; Thu, 05 Mar 2026 13:52:18 +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 1vy97i-00008m-DD for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:52:18 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 85022a56-189a-11f1-9ccf-f158ae23cfc8; Thu, 05 Mar 2026 14:52:16 +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-out1.suse.de (Postfix) with ESMTPS id D1AC93F8EE; Thu, 5 Mar 2026 13:52:15 +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 B19693EA68; Thu, 5 Mar 2026 13:52:15 +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 bx85Ko+KqWlTTgAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:52:15 +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: 85022a56-189a-11f1-9ccf-f158ae23cfc8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718735; 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=naD83YlbZGL27ewgtMQ3AW6P3o75RusmiaznD0RxnhM=; b=VygA5v6MXLuua+lePOlwuediEZc3tkLnBhqqXs+sgQuVO8Bg2/VeOUKNjocjGp+y9+ZaDj 5D4XhXoAMIOz535DM0Q58UpbWbl1AHxlXSzNfaDG0NvLVJQfN3v5HwGBwrHLpqmGWpNGjv vnQzk2Xt1G6ZoyZ0B6ZV/s1xsZLJD4s= Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718735; 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=naD83YlbZGL27ewgtMQ3AW6P3o75RusmiaznD0RxnhM=; b=VygA5v6MXLuua+lePOlwuediEZc3tkLnBhqqXs+sgQuVO8Bg2/VeOUKNjocjGp+y9+ZaDj 5D4XhXoAMIOz535DM0Q58UpbWbl1AHxlXSzNfaDG0NvLVJQfN3v5HwGBwrHLpqmGWpNGjv vnQzk2Xt1G6ZoyZ0B6ZV/s1xsZLJD4s= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Julien Grall , Anthony PERARD Subject: [PATCH 01/11] tools/libs/store: add get- and set-quota related functions Date: Thu, 5 Mar 2026 14:51:58 +0100 Message-ID: <20260305135208.2208663-2-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-Spam-Score: -6.78 X-Spam-Level: X-Spamd-Result: default: False [-6.78 / 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.18)[-0.884]; 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-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1772718759169158500 Content-Type: text/plain; charset="utf-8" Add functions for getting and setting Xenstore quota to libxenstore: xs_get_quota_names(): get the names of the supported quota. xs_get_global_quota(): get the value of one global quota. xs_set_global_quota(): set the value of one global quota. xs_get_domain_quota(): get the value of one quota of a domain. xs_set_domain_quota(): set the value of one quota of a domain. Signed-off-by: Juergen Gross --- tools/include/xenstore.h | 19 ++++++ tools/libs/store/Makefile | 2 +- tools/libs/store/libxenstore.map | 8 +++ tools/libs/store/xs.c | 111 +++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 1 deletion(-) diff --git a/tools/include/xenstore.h b/tools/include/xenstore.h index 423422dc50..6b661e5895 100644 --- a/tools/include/xenstore.h +++ b/tools/include/xenstore.h @@ -277,6 +277,25 @@ bool xs_get_features_domain(struct xs_handle *h, unsig= ned int domid, bool xs_set_features_domain(struct xs_handle *h, unsigned int domid, unsigned int features); =20 +/* Get names of supported quota. */ +char **xs_get_quota_names(struct xs_handle *h, unsigned int *num); + +/* Get the value of one global quota. */ +bool xs_get_global_quota(struct xs_handle *h, char *quota, + unsigned int *value); + +/* Set the value of one global quota. */ +bool xs_set_global_quota(struct xs_handle *h, char *quota, + unsigned int value); + +/* Get the value of one domain quota. */ +bool xs_get_domain_quota(struct xs_handle *h, unsigned int domid, + char *quota, unsigned int *value); + +/* Set the value of one domain quota. */ +bool xs_set_domain_quota(struct xs_handle *h, unsigned int domid, + char *quota, unsigned int value); + char *xs_control_command(struct xs_handle *h, const char *cmd, void *data, unsigned int len); /* Deprecated: use xs_control_command() instead. */ diff --git a/tools/libs/store/Makefile b/tools/libs/store/Makefile index fed43b0008..b52d1f35ad 100644 --- a/tools/libs/store/Makefile +++ b/tools/libs/store/Makefile @@ -2,7 +2,7 @@ XEN_ROOT=3D$(CURDIR)/../../.. include $(XEN_ROOT)/tools/Rules.mk =20 MAJOR =3D 4 -MINOR =3D 1 +MINOR =3D 2 version-script :=3D libxenstore.map =20 ifeq ($(CONFIG_Linux),y) diff --git a/tools/libs/store/libxenstore.map b/tools/libs/store/libxenstor= e.map index cd9df86749..a08ddd549f 100644 --- a/tools/libs/store/libxenstore.map +++ b/tools/libs/store/libxenstore.map @@ -45,3 +45,11 @@ VERS_4.1 { xs_get_features_domain; xs_set_features_domain; } VERS_4.0; +VERS_4.2 { + global: + xs_get_quota_names; + xs_get_global_quota; + xs_set_global_quota; + xs_get_domain_quota; + xs_set_domain_quota; +} VERS_4.1; diff --git a/tools/libs/store/xs.c b/tools/libs/store/xs.c index 8f4b90a3cf..dda37f7526 100644 --- a/tools/libs/store/xs.c +++ b/tools/libs/store/xs.c @@ -1456,6 +1456,117 @@ bool xs_set_features_domain(struct xs_handle *h, un= signed int domid, return xs_bool(xs_talkv(h, iov, ARRAY_SIZE(iov), NULL)); } =20 +char **xs_get_quota_names(struct xs_handle *h, unsigned int *num) +{ + struct xsd_sockmsg msg =3D { .type =3D XS_GET_QUOTA }; + struct iovec iov[1]; + char **quota; + char *reply; + char *c; + unsigned int i; + + iov[0].iov_base =3D &msg; + iov[0].iov_len =3D sizeof(msg); + + reply =3D xs_talkv(h, iov, ARRAY_SIZE(iov), NULL); + if (!reply) + return NULL; + + *num =3D 1; + for (c =3D reply; *c; c++) + if (*c =3D=3D ' ') + (*num)++; + + quota =3D malloc(*num * sizeof(char *) + strlen(reply) + 1); + c =3D (char *)(quota + *num); + strcpy(c, reply); + for (i =3D 0; i < *num; i++) { + quota[i] =3D c; + c =3D strchr(c, ' '); + if (c) { + *c =3D 0; + c++; + } + } + + return quota; +} + +bool xs_get_global_quota(struct xs_handle *h, char *quota, + unsigned int *value) +{ + struct xsd_sockmsg msg =3D { .type =3D XS_GET_QUOTA }; + struct iovec iov[2]; + + iov[0].iov_base =3D &msg; + iov[0].iov_len =3D sizeof(msg); + iov[1].iov_base =3D quota; + iov[1].iov_len =3D strlen(quota) + 1; + + return xs_uint(xs_talkv(h, iov, ARRAY_SIZE(iov), NULL), value); +} + +bool xs_set_global_quota(struct xs_handle *h, char *quota, + unsigned int value) +{ + struct xsd_sockmsg msg =3D { .type =3D XS_SET_QUOTA }; + char val_str[MAX_STRLEN(value)]; + struct iovec iov[3]; + + snprintf(val_str, sizeof(val_str), "%u", value); + + iov[0].iov_base =3D &msg; + iov[0].iov_len =3D sizeof(msg); + iov[1].iov_base =3D quota; + iov[1].iov_len =3D strlen(quota) + 1; + iov[2].iov_base =3D val_str; + iov[2].iov_len =3D strlen(val_str) + 1; + + return xs_bool(xs_talkv(h, iov, ARRAY_SIZE(iov), NULL)); +} + +bool xs_get_domain_quota(struct xs_handle *h, unsigned int domid, + char *quota, unsigned int *value) +{ + struct xsd_sockmsg msg =3D { .type =3D XS_GET_QUOTA }; + char domid_str[MAX_STRLEN(domid)]; + struct iovec iov[3]; + + snprintf(domid_str, sizeof(domid_str), "%u", domid); + + iov[0].iov_base =3D &msg; + iov[0].iov_len =3D sizeof(msg); + iov[1].iov_base =3D domid_str; + iov[1].iov_len =3D strlen(domid_str) + 1; + iov[2].iov_base =3D quota; + iov[2].iov_len =3D strlen(quota) + 1; + + return xs_uint(xs_talkv(h, iov, ARRAY_SIZE(iov), NULL), value); +} + +bool xs_set_domain_quota(struct xs_handle *h, unsigned int domid, + char *quota, unsigned int value) +{ + struct xsd_sockmsg msg =3D { .type =3D XS_SET_QUOTA }; + char domid_str[MAX_STRLEN(domid)]; + char val_str[MAX_STRLEN(value)]; + struct iovec iov[4]; + + snprintf(domid_str, sizeof(domid_str), "%u", domid); + snprintf(val_str, sizeof(val_str), "%u", value); + + iov[0].iov_base =3D &msg; + iov[0].iov_len =3D sizeof(msg); + iov[1].iov_base =3D domid_str; + iov[1].iov_len =3D strlen(domid_str) + 1; + iov[2].iov_base =3D quota; + iov[2].iov_len =3D strlen(quota) + 1; + iov[3].iov_base =3D val_str; + iov[3].iov_len =3D strlen(val_str) + 1; + + return xs_bool(xs_talkv(h, iov, ARRAY_SIZE(iov), NULL)); +} + char *xs_control_command(struct xs_handle *h, const char *cmd, void *data, unsigned int len) { --=20 2.53.0 From nobody Mon Apr 13 02:02:06 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 From nobody Mon Apr 13 02:02:06 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=1772718766; cv=none; d=zohomail.com; s=zohoarc; b=HGU6zKus1183IyreWmHVqhMscV6GKrEzD/JR+IGdIR7cU0jGEnYpG9G3ZEeMkewFEUNX/lLeRmZkH3ARfoCSv6EwmYq/IlDpqBqYhLKH4gkP3GYQGFnDX+Uq1caIwMttCucQJ/6Qq4BPzPZC4c1a2/Y+Kpf3ujJ7tq9u1eT6DEA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772718766; 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=jjwrLXJ76lcdkEfVRZ/NYlU2XuS/dX5LsghDgLcjKFI=; b=j45K4gWjAqMtDDReShGWqfeDGPri5Fjhep693FGOyckoG4tQDOPaqtpaKTSCiGC8Qii8SgsSKO22kIWgANS3SjQsOBJn35tRyJkDmgnI44dqkXIYEMHNLL8izCf17Hs+mUIDdV7aK71SN/XxJy5GwPi8VKPWWVhkl7UzHv8oxI4= 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 1772718766334372.0873945401007; Thu, 5 Mar 2026 05:52:46 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246668.1545797 (Exim 4.92) (envelope-from ) id 1vy97t-0000kL-VL; Thu, 05 Mar 2026 13:52:29 +0000 Received: by outflank-mailman (output) from mailman id 1246668.1545797; Thu, 05 Mar 2026 13:52:29 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy97t-0000kE-ST; Thu, 05 Mar 2026 13:52:29 +0000 Received: by outflank-mailman (input) for mailman id 1246668; Thu, 05 Mar 2026 13:52:28 +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 1vy97s-0008Mq-Hu for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:52:28 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 8bc0ae45-189a-11f1-b164-2bf370ae4941; Thu, 05 Mar 2026 14:52:27 +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-out1.suse.de (Postfix) with ESMTPS id B596E3F81C; Thu, 5 Mar 2026 13:52:26 +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 942643EA76; Thu, 5 Mar 2026 13:52:26 +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 ihr/IpqKqWlwTgAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:52:26 +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: 8bc0ae45-189a-11f1-b164-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718747; 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=jjwrLXJ76lcdkEfVRZ/NYlU2XuS/dX5LsghDgLcjKFI=; b=WW5hCUJF2RbKUTrdp2XBfBvlZD2C+g7/HirdVoXWthwOXuyv9WRF2c0ZO+YVwGifjsDPVT 5mBsCYIb5uwbWelmDYzTAPfzD1VkZqy+shM/tHsvnR6Hupo6vVATSYH/M465w6D4CXwyDH V+8bWa+x2Q1pmi/UwGQwy/blGQOV7BU= Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718746; 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=jjwrLXJ76lcdkEfVRZ/NYlU2XuS/dX5LsghDgLcjKFI=; b=B/fb8AgINJwxqJ7DX8HAqVCjEjPowW5GiuHwhbxHf+bquF1jQH/3f1ueHNLfAWzmcGorTk b5KT17AsBdPluqaprR5WtwUOc7xtm5ek93qAawrFXgbFM9dWhqVq+c0Uh71toYkLQ0bGis YrTJcvbQfFebmrUS+R/HN8He2QK27Ss= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Julien Grall , Anthony PERARD Subject: [PATCH 03/11] tools/xenstored: rework hard_quotas and soft_quotas arrays Date: Thu, 5 Mar 2026 14:52:00 +0100 Message-ID: <20260305135208.2208663-4-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.963]; 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)[imap1.dmz-prg2.suse.org:helo,suse.com:mid,suse.com:email]; RCVD_TLS_ALL(0.00)[] X-Spam-Flag: NO X-Spam-Score: -6.79 X-Spam-Level: X-ZohoMail-DKIM: pass (identity @suse.com) (identity @suse.com) X-ZM-MESSAGEID: 1772718766736158500 Content-Type: text/plain; charset="utf-8" Instead of having one array for hard quotas and one for soft quotas, split them differently: have one array with the quota names and descriptions, and one with the quota values (soft and hard) and the maximum value so far. This is in preparation of supporting per-domain quotas, as the layout of the second array elements will be reused in the domain data. While at it add an accessor for getting a soft quota value, as this will be needed for per-domain quotas, too. Signed-off-by: Juergen Gross Reviewed-by: Anthony PERARD --- tools/xenstored/control.c | 24 ++++++++------- tools/xenstored/core.c | 33 +++++++++++--------- tools/xenstored/domain.c | 65 +++++++++++++++++++++------------------ tools/xenstored/domain.h | 15 +++++---- 4 files changed, 76 insertions(+), 61 deletions(-) diff --git a/tools/xenstored/control.c b/tools/xenstored/control.c index 2611a6fade..ca59d30d05 100644 --- a/tools/xenstored/control.c +++ b/tools/xenstored/control.c @@ -101,7 +101,7 @@ static int do_control_log(const void *ctx, struct conne= ction *conn, } =20 static int quota_show_current(const void *ctx, struct connection *conn, - const struct quota *quotas) + unsigned int idx) { char *resp; unsigned int i; @@ -111,11 +111,12 @@ static int quota_show_current(const void *ctx, struct= connection *conn, return ENOMEM; =20 for (i =3D 0; i < ACC_N; i++) { - if (!quotas[i].name) + if (!quota_adm[i].name || quotas[i].val[idx] =3D=3D Q_VAL_DISABLED) continue; resp =3D talloc_asprintf_append(resp, "%-17s: %8d %s\n", - quotas[i].name, quotas[i].val, - quotas[i].descr); + quota_adm[i].name, + quotas[i].val[idx], + quota_adm[i].descr); if (!resp) return ENOMEM; } @@ -126,7 +127,7 @@ static int quota_show_current(const void *ctx, struct c= onnection *conn, } =20 static int quota_set(const void *ctx, struct connection *conn, - const char **vec, int num, struct quota *quotas) + const char **vec, int num, unsigned int idx) { unsigned int i; int val; @@ -139,8 +140,9 @@ static int quota_set(const void *ctx, struct connection= *conn, return EINVAL; =20 for (i =3D 0; i < ACC_N; i++) { - if (quotas[i].name && !strcmp(vec[0], quotas[i].name)) { - quotas[i].val =3D val; + if (quota_adm[i].name && !strcmp(vec[0], quota_adm[i].name) && + quotas[i].val[idx] !=3D Q_VAL_DISABLED) { + quotas[i].val[idx] =3D val; send_ack(conn, XS_CONTROL); return 0; } @@ -178,10 +180,10 @@ static int do_control_quota(const void *ctx, struct c= onnection *conn, const char **vec, int num) { if (num =3D=3D 0) - return quota_show_current(ctx, conn, hard_quotas); + return quota_show_current(ctx, conn, Q_IDX_HARD); =20 if (!strcmp(vec[0], "set")) - return quota_set(ctx, conn, vec + 1, num - 1, hard_quotas); + return quota_set(ctx, conn, vec + 1, num - 1, Q_IDX_HARD); =20 if (!strcmp(vec[0], "max")) return quota_max(ctx, conn, vec + 1, num - 1); @@ -193,10 +195,10 @@ static int do_control_quota_s(const void *ctx, struct= connection *conn, const char **vec, int num) { if (num =3D=3D 0) - return quota_show_current(ctx, conn, soft_quotas); + return quota_show_current(ctx, conn, Q_IDX_SOFT); =20 if (!strcmp(vec[0], "set")) - return quota_set(ctx, conn, vec + 1, num - 1, soft_quotas); + return quota_set(ctx, conn, vec + 1, num - 1, Q_IDX_SOFT); =20 return EINVAL; } diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c index 5a4bf3e302..8a06b35808 100644 --- a/tools/xenstored/core.c +++ b/tools/xenstored/core.c @@ -2613,10 +2613,9 @@ static void set_timeout(const char *arg) barf("unknown timeout \"%s\"\n", arg); } =20 -static void set_quota(const char *arg, bool soft) +static void set_quota(const char *arg, unsigned int idx) { const char *eq =3D strchr(arg, '=3D'); - struct quota *q =3D soft ? soft_quotas : hard_quotas; unsigned int val; unsigned int i; =20 @@ -2625,8 +2624,9 @@ static void set_quota(const char *arg, bool soft) val =3D get_optval_uint(eq + 1); =20 for (i =3D 0; i < ACC_N; i++) { - if (what_matches(arg, q[i].name)) { - q[i].val =3D val; + if (what_matches(arg, quota_adm[i].name) && + quotas[i].val[idx] !=3D Q_VAL_DISABLED) { + quotas[i].val[idx] =3D val; return; } } @@ -2634,6 +2634,11 @@ static void set_quota(const char *arg, bool soft) barf("unknown quota \"%s\"\n", arg); } =20 +static void set_one_quota(const char *arg, unsigned int idx, enum accitem = what) +{ + quotas[what].val[idx] =3D get_optval_uint(arg); +} + /* Sorted by bit values of TRACE_* flags. Flag is (1u << index). */ const char *const trace_switches[] =3D { "obj", "io", "wrl", "acc", "tdb", @@ -2687,7 +2692,7 @@ int main(int argc, char *argv[]) options, NULL)) !=3D -1) { switch (opt) { case 'E': - hard_quotas[ACC_NODES].val =3D get_optval_uint(optarg); + set_one_quota(optarg, Q_IDX_HARD, ACC_NODES); break; case 'F': pidfile =3D optarg; @@ -2699,10 +2704,10 @@ int main(int argc, char *argv[]) dofork =3D false; break; case 'S': - hard_quotas[ACC_NODESZ].val =3D get_optval_uint(optarg); + set_one_quota(optarg, Q_IDX_HARD, ACC_NODESZ); break; case 't': - hard_quotas[ACC_TRANS].val =3D get_optval_uint(optarg); + set_one_quota(optarg, Q_IDX_HARD, ACC_TRANS); break; case 'T': tracefile =3D optarg; @@ -2715,22 +2720,22 @@ int main(int argc, char *argv[]) keep_orphans =3D true; break; case 'W': - hard_quotas[ACC_WATCH].val =3D get_optval_uint(optarg); + set_one_quota(optarg, Q_IDX_HARD, ACC_WATCH); break; case 'A': - hard_quotas[ACC_NPERM].val =3D get_optval_uint(optarg); + set_one_quota(optarg, Q_IDX_HARD, ACC_NPERM); break; case 'M': - hard_quotas[ACC_PATHLEN].val =3D get_optval_uint(optarg); - hard_quotas[ACC_PATHLEN].val =3D + set_one_quota(optarg, Q_IDX_HARD, ACC_PATHLEN); + quotas[ACC_PATHLEN].val[Q_IDX_HARD] =3D min((unsigned int)XENSTORE_REL_PATH_MAX, - hard_quotas[ACC_PATHLEN].val); + quotas[ACC_PATHLEN].val[Q_IDX_HARD]); break; case 'Q': - set_quota(optarg, false); + set_quota(optarg, Q_IDX_HARD); break; case 'q': - set_quota(optarg, true); + set_quota(optarg, Q_IDX_SOFT); break; case 'w': set_timeout(optarg); diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c index 1df9265ad5..acdcaa769e 100644 --- a/tools/xenstored/domain.c +++ b/tools/xenstored/domain.c @@ -51,60 +51,60 @@ static evtchn_port_t virq_port; =20 xenevtchn_handle *xce_handle =3D NULL; =20 -struct quota hard_quotas[ACC_N] =3D { +struct quotaadm quota_adm[ACC_N] =3D { [ACC_NODES] =3D { .name =3D "nodes", .descr =3D "Nodes per domain", - .val =3D 1000, }, [ACC_WATCH] =3D { .name =3D "watches", .descr =3D "Watches per domain", - .val =3D 128, }, [ACC_OUTST] =3D { .name =3D "outstanding", .descr =3D "Outstanding requests per domain", - .val =3D 20, }, [ACC_MEM] =3D { .name =3D "memory", - .descr =3D "Total Xenstore memory per domain (error level)", - .val =3D 2 * 1024 * 1024 + 512 * 1024, /* 2.5 MB */ + .descr =3D "Total Xenstore memory per domain", }, [ACC_TRANS] =3D { .name =3D "transactions", .descr =3D "Active transactions per domain", - .val =3D 10, }, [ACC_TRANSNODES] =3D { .name =3D "transaction-nodes", .descr =3D "Max. number of accessed nodes per transaction", - .val =3D 1024, }, [ACC_NPERM] =3D { .name =3D "node-permissions", .descr =3D "Max. number of permissions per node", - .val =3D 5, }, [ACC_PATHLEN] =3D { .name =3D "path-max", .descr =3D "Max. length of a node path", - .val =3D XENSTORE_REL_PATH_MAX, }, [ACC_NODESZ] =3D { .name =3D "node-size", .descr =3D "Max. size of a node", - .val =3D 2048, }, }; =20 -struct quota soft_quotas[ACC_N] =3D { - [ACC_MEM] =3D { - .name =3D "memory", - .descr =3D "Total Xenstore memory per domain (warning level)", - .val =3D 2 * 1024 * 1024, /* 2.0 MB */ +struct quota quotas[ACC_N] =3D { + [ACC_NODES] =3D { .val =3D { 1000, Q_VAL_DISABLED }, }, + [ACC_WATCH] =3D { .val =3D { 128, Q_VAL_DISABLED }, }, + [ACC_OUTST] =3D { .val =3D { 20, Q_VAL_DISABLED }, }, + [ACC_MEM] =3D { + .val =3D { 2 * 1024 * 1024 + 512 * 1024, /* 2.5 MB */ + 2 * 1024 * 1024 /* 2.0 MB */ }, }, + [ACC_TRANS] =3D { .val =3D { 10, Q_VAL_DISABLED }, }, + [ACC_TRANSNODES] =3D { .val =3D { 1024, Q_VAL_DISABLED }, }, + [ACC_NPERM] =3D { .val =3D { 5, Q_VAL_DISABLED }, }, + [ACC_PATHLEN] =3D { + .val =3D { XENSTORE_REL_PATH_MAX, Q_VAL_DISABLED }, + }, + [ACC_NODESZ] =3D { .val =3D { 2048, Q_VAL_DISABLED }, }, }; =20 typedef int32_t wrl_creditt; @@ -389,10 +389,15 @@ void wrl_apply_debit_trans_commit(struct connection *= conn) wrl_apply_debit_actual(conn->domain); } =20 +static unsigned int domain_get_soft_quota(struct domain *d, enum accitem w= hat) +{ + return quotas[what].val[Q_IDX_SOFT]; +} + static bool domain_check_quota_val(struct domain *d, enum accitem what, unsigned int val) { - unsigned int quota =3D hard_quotas[what].val; + unsigned int quota =3D quotas[what].val[Q_IDX_HARD]; =20 if (!quota || !domid_is_unprivileged(d->domid)) return false; @@ -765,10 +770,10 @@ int domain_get_quota(const void *ctx, struct connecti= on *conn, return ENOMEM; =20 for (i =3D 0; i < ACC_N; i++) { - if (!hard_quotas[i].name) + if (!quota_adm[i].name) continue; resp =3D talloc_asprintf_append(resp, "%-17s: %8u (max %8u)\n", - hard_quotas[i].name, + quota_adm[i].name, d->acc[i].val, d->acc[i].max); if (!resp) return ENOMEM; @@ -789,11 +794,10 @@ int domain_max_global_acc(const void *ctx, struct con= nection *conn) return ENOMEM; =20 for (i =3D 0; i < ACC_N; i++) { - if (!hard_quotas[i].name) + if (!quota_adm[i].name) continue; resp =3D talloc_asprintf_append(resp, "%-17s: %8u\n", - hard_quotas[i].name, - hard_quotas[i].max); + quota_adm[i].name, quotas[i].max); if (!resp) return ENOMEM; } @@ -1600,12 +1604,12 @@ static void domain_acc_valid_max(struct domain *d, = enum accitem what, unsigned int val) { assert(what < ARRAY_SIZE(d->acc)); - assert(what < ARRAY_SIZE(hard_quotas)); + assert(what < ARRAY_SIZE(quotas)); =20 if (val > d->acc[what].max) d->acc[what].max =3D val; - if (val > hard_quotas[what].max && domid_is_unprivileged(d->domid)) - hard_quotas[what].max =3D val; + if (val > quotas[what].max && domid_is_unprivileged(d->domid)) + quotas[what].max =3D val; } =20 static int domain_acc_add_valid(struct domain *d, enum accitem what, int a= dd) @@ -1742,7 +1746,7 @@ void domain_reset_global_acc(void) unsigned int i; =20 for (i =3D 0; i < ACC_N; i++) - hard_quotas[i].max =3D 0; + quotas[i].max =3D 0; =20 /* Set current max values seen. */ hashtable_iterate(domhash, domain_reset_global_acc_sub, NULL); @@ -1802,21 +1806,22 @@ static bool domain_chk_quota(struct connection *con= n, unsigned int mem) } =20 if (now - domain->mem_last_msg >=3D MEM_WARN_MINTIME_SEC) { + unsigned int soft_mem =3D domain_get_soft_quota(domain, ACC_MEM); + if (domain->hard_quota_reported) { domain->mem_last_msg =3D now; domain->hard_quota_reported =3D false; syslog(LOG_INFO, "Domain %u below hard memory quota again\n", domain->domid); } - if (mem >=3D soft_quotas[ACC_MEM].val && - soft_quotas[ACC_MEM].val && !domain->soft_quota_reported) { + if (mem >=3D soft_mem && soft_mem && + !domain->soft_quota_reported) { domain->mem_last_msg =3D now; domain->soft_quota_reported =3D true; syslog(LOG_WARNING, "Domain %u exceeds soft memory quota\n", domain->domid); } - if (mem < soft_quotas[ACC_MEM].val && - domain->soft_quota_reported) { + if (mem < soft_mem && domain->soft_quota_reported) { domain->mem_last_msg =3D now; domain->soft_quota_reported =3D false; syslog(LOG_INFO, "Domain %u below soft memory quota again\n", diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h index b229f6f4e0..a6db358fdc 100644 --- a/tools/xenstored/domain.h +++ b/tools/xenstored/domain.h @@ -40,15 +40,18 @@ enum accitem { ACC_N, /* Number of elements per domain. */ }; =20 -struct quota { +extern struct quotaadm { const char *name; const char *descr; - unsigned int val; - unsigned int max; -}; +} quota_adm[ACC_N]; =20 -extern struct quota hard_quotas[ACC_N]; -extern struct quota soft_quotas[ACC_N]; +extern struct quota { + unsigned int val[2]; +#define Q_IDX_HARD 0 +#define Q_IDX_SOFT 1 +#define Q_VAL_DISABLED UINT_MAX + unsigned int max; +} quotas[ACC_N]; =20 void handle_event(void); =20 --=20 2.53.0 From nobody Mon Apr 13 02:02:06 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=1772718769; cv=none; d=zohomail.com; s=zohoarc; b=O3x2Fz0J8kQgX2Tx0jLJHGQjKR2EzRc5sYl+gNKkmUWx06+W2uqJU9KTPwUo7fs4/FlxhNYMY5a/GzBN9mSiYBOnoHMfhTO5szO5hwDpPkQyQukr7e0hHvtdjv4SHRHofizSA/q7MKTljuuPaeeTXIN0dP4YI9hjrf6LAm2h+Bs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772718769; 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=Qd6amYjyhOJLEFPf+RpsHO3ExuRDdjesrhezg6H1Mlk=; b=dVcOGCq6HWn1BY7hbBqWGVSKPC4pQ3smRbid3dO7owSO0P4//0422IymyzSkGC2oxf7OGcCPN7nlzQLqJOTKBmenzjpzt/BPJ6+ndS0IRgFuuuKn6RXvf2OSyTfaYE9nPNCVtpEK0GUlB5l7txV8OtvDVSr1MU9OHFbRbF6MhAA= 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 1772718769795647.7545919566211; Thu, 5 Mar 2026 05:52:49 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246672.1545808 (Exim 4.92) (envelope-from ) id 1vy97z-00016n-7f; Thu, 05 Mar 2026 13:52:35 +0000 Received: by outflank-mailman (output) from mailman id 1246672.1545808; Thu, 05 Mar 2026 13:52:35 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy97z-00016c-2d; Thu, 05 Mar 2026 13:52:35 +0000 Received: by outflank-mailman (input) for mailman id 1246672; Thu, 05 Mar 2026 13:52:33 +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 1vy97x-0008Mq-Di for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:52:33 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 8eb9b55a-189a-11f1-b164-2bf370ae4941; Thu, 05 Mar 2026 14:52:32 +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-out1.suse.de (Postfix) with ESMTPS id 2D7F03ED7C; Thu, 5 Mar 2026 13:52:32 +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 0D11D3EA68; Thu, 5 Mar 2026 13:52:32 +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 UhAgAqCKqWl0TgAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:52:32 +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: 8eb9b55a-189a-11f1-b164-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718752; 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=Qd6amYjyhOJLEFPf+RpsHO3ExuRDdjesrhezg6H1Mlk=; b=BUNgof1yRMbXZPLtFr0mlbJ4W+odssS1nSsOsSdr9HWD54zQjx/twYgJACUW7C+J9NVv0/ 3tpZNRqR/+w/2Z+FEV5BJRlOtpE/zXiDzsPYVHAmyeFAUefpxyqOAgZbnMRiawMlWoevD0 phu2C9hM4VCXPdPQ3bM0ocuE5763JCo= Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718752; 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=Qd6amYjyhOJLEFPf+RpsHO3ExuRDdjesrhezg6H1Mlk=; b=BUNgof1yRMbXZPLtFr0mlbJ4W+odssS1nSsOsSdr9HWD54zQjx/twYgJACUW7C+J9NVv0/ 3tpZNRqR/+w/2Z+FEV5BJRlOtpE/zXiDzsPYVHAmyeFAUefpxyqOAgZbnMRiawMlWoevD0 phu2C9hM4VCXPdPQ3bM0ocuE5763JCo= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Julien Grall , Anthony PERARD Subject: [PATCH 04/11] tools/xenstored: add GLOBAL_QUOTA_DATA record for live update Date: Thu, 5 Mar 2026 14:52:01 +0100 Message-ID: <20260305135208.2208663-5-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-Spam-Score: -6.79 X-Spam-Level: X-Spamd-Result: default: False [-6.79 / 50.00]; REPLY(-4.00)[]; BAYES_HAM(-3.00)[100.00%]; MID_CONTAINS_FROM(1.00)[]; NEURAL_HAM_LONG(-1.00)[-1.000]; R_MISSING_CHARSET(0.50)[]; NEURAL_HAM_SHORT(-0.19)[-0.963]; MIME_GOOD(-0.10)[text/plain]; MIME_TRACE(0.00)[0:+]; FUZZY_RATELIMITED(0.00)[rspamd.com]; TO_MATCH_ENVRCPT_ALL(0.00)[]; DKIM_SIGNED(0.00)[suse.com:s=susede1]; ARC_NA(0.00)[]; RCVD_TLS_ALL(0.00)[]; RCPT_COUNT_THREE(0.00)[4]; FROM_HAS_DN(0.00)[]; TO_DN_SOME(0.00)[]; FROM_EQ_ENVFROM(0.00)[]; RCVD_VIA_SMTP_AUTH(0.00)[]; RCVD_COUNT_TWO(0.00)[2]; DBL_BLOCKED_OPENRESOLVER(0.00)[suse.com:mid,suse.com:email,imap1.dmz-prg2.suse.org:helo] X-Spam-Flag: NO X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1772718772060154100 Content-Type: text/plain; charset="utf-8" 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 --- 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 connectio= n *conn, return 0; } =20 +static bool parse_quota_name(const char *name, unsigned int *qidx, + unsigned int *idx) +{ + unsigned int q; + + if (strncmp(name, "soft-", 5)) { + *idx =3D Q_IDX_HARD; + } else { + *idx =3D Q_IDX_SOFT; + name +=3D 5; + } + for (q =3D 0; q < ACC_N; q++) { + if (quota_adm[q].name && !strcmp(quota_adm[q].name, name)) { + *qidx =3D 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 vo= id *state) } } =20 +static unsigned int get_quota_size(struct quota *quota, unsigned int *len) +{ + unsigned int q; + unsigned int n =3D 0; + + for (q =3D 0; q < ACC_N; q++) { + if (!quota_adm[q].name) + continue; + if (quota[q].val[Q_IDX_HARD] !=3D Q_VAL_DISABLED) { + n++; + *len +=3D strlen(quota_adm[q].name) + 1; + } + if (quota[q].val[Q_IDX_SOFT] !=3D Q_VAL_DISABLED) { + n++; + *len +=3D strlen(quota_adm[q].name) + 5 + 1; + } + } + + return n; +} + +static void build_quota_data(struct quota *quota, uint32_t *val, char *nam= e) +{ + unsigned int q; + unsigned int n =3D 0; + + for (q =3D 0; q < ACC_N; q++) { + if (!quota_adm[q].name) + continue; + if (quota[q].val[Q_IDX_HARD] !=3D Q_VAL_DISABLED) { + val[n++] =3D quota[q].val[Q_IDX_HARD]; + strcpy(name, quota_adm[q].name); + name +=3D strlen(name) + 1; + } + if (quota[q].val[Q_IDX_SOFT] !=3D Q_VAL_DISABLED) { + val[n++] =3D quota[q].val[Q_IDX_SOFT]; + strcpy(name, "soft-"); + strcpy(name + 5, quota_adm[q].name); + name +=3D 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 =3D 0; i < n; i++) { + if (!parse_quota_name(name, &q, &idx)) + quota[q].val[idx] =3D val[i]; + name +=3D strlen(name) + 1; + } +} + static int dump_state_domain(const void *k, void *v, void *arg) { struct domain *domain =3D v; @@ -2049,6 +2125,53 @@ void read_state_domain(const void *ctx, const void *= state, unsigned int version) domain->features =3D sd->features; } =20 +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 =3D sizeof(*glb); + size_t ret; + + n_quota =3D get_quota_size(quotas, &len); + len +=3D n_quota * sizeof(glb->quota_val[0]); + len =3D ROUNDUP(len, 3); + + record =3D talloc_size(NULL, len + sizeof(*head)); + if (!record) + return "Dump global quota allocation error"; + + head =3D record; + head->type =3D XS_STATE_TYPE_GLB_QUOTA; + head->length =3D len; + + glb =3D (struct xs_state_glb_quota *)(head + 1); + glb->n_dom_quota =3D n_quota; + glb->n_glob_quota =3D 0; + + build_quota_data(quotas, glb->quota_val, + (char *)(glb->quota_val + n_quota)); + + ret =3D fwrite(record, len + sizeof(*head), 1, fp); + + talloc_free(record); + + if (ret !=3D 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 =3D state; + unsigned int n_quota =3D glb->n_dom_quota + glb->n_glob_quota; + const char *name =3D (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); =20 const char *dump_state_connections(FILE *fp); const char *dump_state_domains(FILE *fp); +const char *dump_state_glb_quota(FILE *fp); =20 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); =20 struct hashtable *domain_check_acc_init(void); void domain_check_acc_add(const struct node *node, struct hashtable *domai= ns); 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, struc= t connection *conn) } =20 ret =3D dump_state_global(fp); + if (ret) + goto out; + ret =3D dump_state_glb_quota(fp); if (ret) goto out; ret =3D dump_state_connections(fp); --=20 2.53.0 From nobody Mon Apr 13 02:02:06 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 1772718776347112.80974848574454; Thu, 5 Mar 2026 05:52:56 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246681.1545818 (Exim 4.92) (envelope-from ) id 1vy984-0001aH-KE; Thu, 05 Mar 2026 13:52:40 +0000 Received: by outflank-mailman (output) from mailman id 1246681.1545818; Thu, 05 Mar 2026 13:52:40 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy984-0001ZW-Fu; Thu, 05 Mar 2026 13:52:40 +0000 Received: by outflank-mailman (input) for mailman id 1246681; Thu, 05 Mar 2026 13:52:39 +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 1vy983-00008m-Dt for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:52:39 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.223.130]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 91e25457-189a-11f1-9ccf-f158ae23cfc8; Thu, 05 Mar 2026 14:52:37 +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 958FC3ED7C; Thu, 5 Mar 2026 13:52:37 +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 756F13EA68; Thu, 5 Mar 2026 13:52:37 +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 TT6VG6WKqWmETgAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:52:37 +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: 91e25457-189a-11f1-9ccf-f158ae23cfc8 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 05/11] tools/xenstored: split acc[] array in struct domain Date: Thu, 5 Mar 2026 14:52:02 +0100 Message-ID: <20260305135208.2208663-6-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: 958FC3ED7C 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: 1772718776772158500 Content-Type: text/plain; charset="utf-8" Prepare using per-domain quota by splitting the acc[] array in struct domain into an array with the current accounting data, and an array of type struct quota for the per-domain quota and the seen max value of the domain. Signed-off-by: Juergen Gross Reviewed-by: Anthony PERARD --- tools/xenstored/domain.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c index 694ae58973..9bd3ac7aca 100644 --- a/tools/xenstored/domain.c +++ b/tools/xenstored/domain.c @@ -140,10 +140,8 @@ struct domain bool introduced; =20 /* Accounting data for this domain. */ - struct acc { - unsigned int val; - unsigned int max; - } acc[ACC_N]; + unsigned int acc_val[ACC_N]; + struct quota acc[ACC_N]; =20 /* Memory quota data for this domain. */ bool soft_quota_reported; @@ -410,7 +408,7 @@ bool domain_check_quota_add(struct domain *d, enum acci= tem what, int add) if (add < 0 || !d) return false; =20 - return domain_check_quota_val(d, what, d->acc[what].val + add); + return domain_check_quota_val(d, what, d->acc_val[what] + add); } =20 static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod) @@ -582,7 +580,7 @@ static int domain_tree_remove_sub(const void *ctx, stru= ct connection *conn, ret =3D WALK_TREE_SKIP_CHILDREN; } =20 - return domain->acc[ACC_NODES].val ? ret : WALK_TREE_SUCCESS_STOP; + return domain->acc_val[ACC_NODES] ? ret : WALK_TREE_SUCCESS_STOP; } =20 static void domain_tree_remove(struct domain *domain) @@ -590,7 +588,7 @@ static void domain_tree_remove(struct domain *domain) int ret; struct walk_funcs walkfuncs =3D { .enter =3D domain_tree_remove_sub }; =20 - if (domain->acc[ACC_NODES].val) { + if (domain->acc_val[ACC_NODES]) { ret =3D walk_node_tree(domain, NULL, "/", &walkfuncs, domain); if (ret =3D=3D WALK_TREE_ERROR_STOP) syslog(LOG_ERR, @@ -774,7 +772,7 @@ int domain_get_quota(const void *ctx, struct connection= *conn, continue; resp =3D talloc_asprintf_append(resp, "%-17s: %8u (max %8u)\n", quota_adm[i].name, - d->acc[i].val, d->acc[i].max); + d->acc_val[i], d->acc[i].max); if (!resp) return ENOMEM; } @@ -1637,10 +1635,10 @@ static int domain_acc_add_valid(struct domain *d, e= num accitem what, int add) { unsigned int val; =20 - assert(what < ARRAY_SIZE(d->acc)); + assert(what < ARRAY_SIZE(d->acc_val)); =20 - if ((add < 0 && -add > d->acc[what].val) || - (add > 0 && (INT_MAX - d->acc[what].val) < add)) { + if ((add < 0 && -add > d->acc_val[what]) || + (add > 0 && (INT_MAX - d->acc_val[what]) < add)) { /* * In a transaction when a node is being added/removed AND the * same node has been added/removed outside the transaction in @@ -1651,7 +1649,7 @@ static int domain_acc_add_valid(struct domain *d, enu= m accitem what, int add) return (add < 0) ? 0 : INT_MAX; } =20 - val =3D d->acc[what].val + add; + val =3D d->acc_val[what] + add; domain_acc_valid_max(d, what, val); =20 return val; @@ -1710,10 +1708,10 @@ static int domain_acc_add(struct connection *conn, = unsigned int domid, } =20 trace_acc("global change domid %u: what=3D%u %u add %d\n", domid, what, - d->acc[what].val, add); - d->acc[what].val =3D domain_acc_add_valid(d, what, add); + d->acc_val[what], add); + d->acc_val[what] =3D domain_acc_add_valid(d, what, add); =20 - return d->acc[what].val; + return d->acc_val[what]; } =20 void acc_drop(struct connection *conn) @@ -1757,7 +1755,7 @@ static int domain_reset_global_acc_sub(const void *k,= void *v, void *arg) unsigned int i; =20 for (i =3D 0; i < ACC_N; i++) - d->acc[i].max =3D d->acc[i].val; + d->acc[i].max =3D d->acc_val[i]; =20 return 0; } @@ -2193,7 +2191,7 @@ static int domain_check_acc_init_sub(const void *k, v= oid *v, void *arg) * If everything is correct incrementing the value for each node will * result in dom->nodes being 0 at the end. */ - dom->nodes =3D -d->acc[ACC_NODES].val; + dom->nodes =3D -d->acc_val[ACC_NODES]; =20 if (hashtable_add(domains, &dom->domid, dom)) { talloc_free(dom); @@ -2248,7 +2246,7 @@ static int domain_check_acc_cb(const void *k, void *v= , void *arg) if (!d) return 0; =20 - d->acc[ACC_NODES].val +=3D dom->nodes; + d->acc_val[ACC_NODES] +=3D dom->nodes; =20 return 0; } --=20 2.53.0 From nobody Mon Apr 13 02:02:06 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 From nobody Mon Apr 13 02:02:06 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=1772719080; cv=none; d=zohomail.com; s=zohoarc; b=VIcoChpW7AMTXsK3qD2RLC/k83PkN0F7Zc8pD+XTA474k5YnpvcW2tfqRvqsl7hBN6MsaD1xu8AddrVefbuxmyCmuSz09RVSOY2ehUaIBtkQ2EgkfvyhOvpAOvqYTNoJQLgwQ5jF8ZOKB3JixYN+UTrkN0sC3XZ9SuDIEZQcE4w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772719080; 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=r+4ZO/KspblmGGLhGlNMkeWiLuNQLDCEDNiLJzLmjPY=; b=S+jxkH/W2BRPxNaEj/xMRP4E32brHbv9Gk1QW4vMwiF430MaRfLbS4yZ62r/bEE5SMRCpMUoB9qv9aY7wKRRdLbfGEdrNV3AKQYz2k/juoJUAjrCh1g5i/76dfcUlgpQ0a4cCaBmWM9Qq+4FUpX9jePyabWF3jqIiUBR4H6YBVs= 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 1772719080194779.5193568060952; Thu, 5 Mar 2026 05:58:00 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246734.1545847 (Exim 4.92) (envelope-from ) id 1vy9Cs-00049t-LP; Thu, 05 Mar 2026 13:57:38 +0000 Received: by outflank-mailman (output) from mailman id 1246734.1545847; Thu, 05 Mar 2026 13:57:38 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy9Cs-00049m-I7; Thu, 05 Mar 2026 13:57:38 +0000 Received: by outflank-mailman (input) for mailman id 1246734; Thu, 05 Mar 2026 13:57:36 +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 1vy98F-00008m-5J for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:52:51 +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 98646d41-189a-11f1-9ccf-f158ae23cfc8; Thu, 05 Mar 2026 14:52:48 +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 748E75BEC7; Thu, 5 Mar 2026 13:52:48 +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 54D0A3EA76; Thu, 5 Mar 2026 13:52:48 +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 n8KnE7CKqWkMTwAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:52:48 +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: 98646d41-189a-11f1-9ccf-f158ae23cfc8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718768; 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=r+4ZO/KspblmGGLhGlNMkeWiLuNQLDCEDNiLJzLmjPY=; b=foug50Oxl/72LzeH5fthq6evZ/egSmCWIwtKH48ES5xxykx8PW6vFp7YvV9Mk5NBiS9sHD F5t+nvvLv8VTVuuis5HKMRGA1ne++NR0kV7fF4xsW49Erk9v25T3ITR9kxMCy/FKdwT1PN hJ0HsStVaIIJo4y2pRJUcrQrHmg4Wd4= Authentication-Results: smtp-out2.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718768; 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=r+4ZO/KspblmGGLhGlNMkeWiLuNQLDCEDNiLJzLmjPY=; b=foug50Oxl/72LzeH5fthq6evZ/egSmCWIwtKH48ES5xxykx8PW6vFp7YvV9Mk5NBiS9sHD F5t+nvvLv8VTVuuis5HKMRGA1ne++NR0kV7fF4xsW49Erk9v25T3ITR9kxMCy/FKdwT1PN hJ0HsStVaIIJo4y2pRJUcrQrHmg4Wd4= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Julien Grall , Anthony PERARD Subject: [PATCH 07/11] tools/xenstored: implement the GET/SET_QUOTA commands Date: Thu, 5 Mar 2026 14:52:04 +0100 Message-ID: <20260305135208.2208663-8-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.964]; 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: 1772719083626154100 Content-Type: text/plain; charset="utf-8" Add the implementation of the GET_QUOTA and SET_QUOTA wire commands. Signed-off-by: Juergen Gross --- tools/xenstored/core.c | 4 ++ tools/xenstored/domain.c | 106 +++++++++++++++++++++++++++++++++++++++ tools/xenstored/domain.h | 8 +++ 3 files changed, 118 insertions(+) diff --git a/tools/xenstored/core.c b/tools/xenstored/core.c index 8a06b35808..e283d47184 100644 --- a/tools/xenstored/core.c +++ b/tools/xenstored/core.c @@ -2034,6 +2034,10 @@ static struct { { "GET_FEATURE", do_get_feature, XS_FLAG_PRIV }, [XS_SET_FEATURE] =3D { "SET_FEATURE", do_set_feature, XS_FLAG_PRIV }, + [XS_GET_QUOTA] =3D + { "GET_QUOTA", do_get_quota, XS_FLAG_PRIV }, + [XS_SET_QUOTA] =3D + { "SET_QUOTA", do_set_quota, XS_FLAG_PRIV }, }; =20 static const char *sockmsg_string(enum xsd_sockmsg_type type) diff --git a/tools/xenstored/domain.c b/tools/xenstored/domain.c index 8e52351695..c0bc8a3eb7 100644 --- a/tools/xenstored/domain.c +++ b/tools/xenstored/domain.c @@ -1363,6 +1363,112 @@ static bool parse_quota_name(const char *name, unsi= gned int *qidx, return true; } =20 +int do_get_quota(const void *ctx, struct connection *conn, + struct buffered_data *in) +{ + const char *vec[2]; + unsigned int n_pars; + unsigned int domid; + unsigned int q; + unsigned int idx; + char *resp; + const char *name; + const struct quota *quota; + const struct domain *domain; + + n_pars =3D get_strings(in, vec, ARRAY_SIZE(vec)); + + if (n_pars > 2) + return EINVAL; + + if (n_pars =3D=3D 0) { + resp =3D talloc_asprintf(ctx, "%s", ""); + if (!resp) + return ENOMEM; + for (q =3D 0; q < ACC_N; q++) { + if (!quota_adm[q].name) + continue; + if (quotas[q].val[Q_IDX_HARD] !=3D Q_VAL_DISABLED) { + resp =3D talloc_asprintf_append(resp, "%s%s", + *resp ? " " : "", quota_adm[q].name); + if (!resp) + return ENOMEM; + } + if (quotas[q].val[Q_IDX_SOFT] !=3D Q_VAL_DISABLED) { + resp =3D talloc_asprintf_append(resp, "%ssoft-%s", + *resp ? " " : "", quota_adm[q].name); + if (!resp) + return ENOMEM; + } + } + } else { + if (n_pars =3D=3D 1) { + quota =3D quotas; + name =3D vec[0]; + } else { + domid =3D atoi(vec[0]); + domain =3D find_or_alloc_existing_domain(domid); + if (!domain) + return ENOENT; + quota =3D domain->acc; + name =3D vec[1]; + } + + if (parse_quota_name(name, &q, &idx)) + return EINVAL; + + resp =3D talloc_asprintf(ctx, "%u", quota[q].val[idx]); + if (!resp) + return ENOMEM; + } + + send_reply(conn, XS_GET_QUOTA, resp, strlen(resp) + 1); + + return 0; +} + +int do_set_quota(const void *ctx, struct connection *conn, + struct buffered_data *in) +{ + const char *vec[3]; + unsigned int n_pars; + unsigned int domid; + unsigned int q; + unsigned int idx; + const char *name; + unsigned int val; + struct quota *quota; + struct domain *domain; + + n_pars =3D get_strings(in, vec, ARRAY_SIZE(vec)); + + if (n_pars < 2 || n_pars > 3) + return EINVAL; + + if (n_pars =3D=3D 2) { + quota =3D quotas; + name =3D vec[0]; + val =3D atoi(vec[1]); + } else { + domid =3D atoi(vec[0]); + domain =3D find_or_alloc_existing_domain(domid); + if (!domain) + return ENOENT; + quota =3D domain->acc; + name =3D vec[1]; + val =3D atoi(vec[2]); + } + + if (parse_quota_name(name, &q, &idx)) + return EINVAL; + + quota[q].val[idx] =3D val; + + send_ack(conn, XS_SET_QUOTA); + + return 0; +} + static int close_xgt_handle(void *_handle) { xengnttab_close(*(xengnttab_handle **)_handle); diff --git a/tools/xenstored/domain.h b/tools/xenstored/domain.h index 62ce3b3166..6a06b0d1af 100644 --- a/tools/xenstored/domain.h +++ b/tools/xenstored/domain.h @@ -93,6 +93,14 @@ int do_get_feature(const void *ctx, struct connection *c= onn, int do_set_feature(const void *ctx, struct connection *conn, struct buffered_data *in); =20 +/* Get quota names or value */ +int do_get_quota(const void *ctx, struct connection *conn, + struct buffered_data *in); + +/* Set quota value */ +int do_set_quota(const void *ctx, struct connection *conn, + struct buffered_data *in); + void domain_early_init(void); void domain_init(int evtfd); void init_domains(bool live_update); --=20 2.53.0 From nobody Mon Apr 13 02:02:06 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=1772719105; cv=none; d=zohomail.com; s=zohoarc; b=Bu0z5bSJahZwufK9IQlnlEEZP3h4NQ+qQii2D9gtUkYv7Y2ecBEkKy3LzNkIpg6KZw1kxADiG3jzUmAi6m9kVHY7tT/A265ykepMPUV+BKdYTJAleaxg67DAoXaChp16i1dTRbxHZ/nc9fSeqNW5/jcB4QW6p9RG32hChE1HCg0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772719105; 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=OVzJ3vkzk9Kd/2UKnmB2k8cly65avjJkTaC6JZd+bg8=; b=NkY0Mi0XrUT+Oq7D9x75bQL8CbvZHY+5CwGeMEmRp0KLgOMvqPhg9AXgG4it5mPKdunPydvwT2rjqmDquqGpH+YqzRHz9cPUxpETuvtmwtPk0Nx96l7njhJaszdqMCnoEG9try2ljNsSMOHKkSRfpAZtDjVOzopgCE6GQIWBo3k= 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 1772719105442965.5674011843511; Thu, 5 Mar 2026 05:58:25 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246747.1545863 (Exim 4.92) (envelope-from ) id 1vy9DK-0004mk-9N; Thu, 05 Mar 2026 13:58:06 +0000 Received: by outflank-mailman (output) from mailman id 1246747.1545863; Thu, 05 Mar 2026 13:58:06 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy9DK-0004ln-3X; Thu, 05 Mar 2026 13:58:06 +0000 Received: by outflank-mailman (input) for mailman id 1246747; Thu, 05 Mar 2026 13:58:03 +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 1vy98K-00008m-OP for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:52:57 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [2a07:de40:b251:101:10:150:64:1]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 9bbd47c8-189a-11f1-9ccf-f158ae23cfc8; Thu, 05 Mar 2026 14:52:54 +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-out1.suse.de (Postfix) with ESMTPS id E26253F8B7; Thu, 5 Mar 2026 13:52:53 +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 BD3CA3EA68; Thu, 5 Mar 2026 13:52:53 +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 jhIiLbWKqWkWTwAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:52:53 +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: 9bbd47c8-189a-11f1-9ccf-f158ae23cfc8 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718774; 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=OVzJ3vkzk9Kd/2UKnmB2k8cly65avjJkTaC6JZd+bg8=; b=iKGXaH4Yp+kB1FiF6PRKGT2+/U1JBirZdLjmovQ8VwqOXgUSAPvePz1hqJ/UmwX53A0wfo cc8MYRfeXMocMiiSMH6DQNZnpNKAQr3eH/UXAtKe5Bz+sklgRvztjHfxqVlYcmiHz6MHAf xXkvIen6QoIVh2dIVwiGWgKWkoWAjAs= Authentication-Results: smtp-out1.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718773; 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=OVzJ3vkzk9Kd/2UKnmB2k8cly65avjJkTaC6JZd+bg8=; b=U+3yZC/uzXKjWhzK8thLKyTThh9gbe3VUgm/crOtHn49WnU6SlfsqSuXs4zWhbdI4d5Bkg 5E7mTdTRdJBAMHxM/sESqw/kvWlT5NGPcKq6bfLxKiM82/x+SIiGLawDUL1hXJCtG6mjwG RfX7PD9+RxFFkgh7YFXc8RRLry9O1L4= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Nick Rosbrook , George Dunlap , Anthony PERARD Subject: [PATCH 08/11] tools/libxl: add functions for retrieving and setting xenstore quota Date: Thu, 5 Mar 2026 14:52:05 +0100 Message-ID: <20260305135208.2208663-9-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.940]; 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_FIVE(0.00)[5]; 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) (identity @suse.com) X-ZM-MESSAGEID: 1772719107861154100 Content-Type: text/plain; charset="utf-8" Add some functions allowing to retrieve and set Xenstore quota (either global or domain specific). Signed-off-by: Juergen Gross Acked-by: Nick Rosbrook 0 { +cQuota :=3D (*[1<<28]C.libxl_xs_quota_item)(unsafe.Pointer(xc.quota))[:n:n] +x.Quota =3D make([]XsQuotaItem, n) +for i, v :=3D range cQuota { +if err :=3D x.Quota[i].fromC(&v); err !=3D nil { +return fmt.Errorf("converting field Quota: %v", err) } +} +} + + return nil} + +func (x *XsQuotaSet) toC(xc *C.libxl_xs_quota_set) (err error){defer func(= ){ +if err !=3D nil{ +C.libxl_xs_quota_set_dispose(xc)} +}() + +if numQuota :=3D len(x.Quota); numQuota > 0 { +xc.quota =3D (*C.libxl_xs_quota_item)(C.malloc(C.ulong(numQuota)*C.sizeof_= libxl_xs_quota_item)) +xc.num_quota =3D C.int(numQuota) +cQuota :=3D (*[1<<28]C.libxl_xs_quota_item)(unsafe.Pointer(xc.quota))[:num= Quota:numQuota] +for i,v :=3D range x.Quota { +if err :=3D v.toC(&cQuota[i]); err !=3D nil { +return fmt.Errorf("converting field Quota: %v", err) +} +} +} + + return nil + } + // NewDomainBuildInfo returns an instance of DomainBuildInfo initialized w= ith defaults. func NewDomainBuildInfo(dtype DomainType) (*DomainBuildInfo, error) { var ( diff --git a/tools/golang/xenlight/types.gen.go b/tools/golang/xenlight/typ= es.gen.go index ab9d4ca7b4..5393277190 100644 --- a/tools/golang/xenlight/types.gen.go +++ b/tools/golang/xenlight/types.gen.go @@ -543,6 +543,15 @@ Altp2MModeExternal Altp2MMode =3D 2 Altp2MModeLimited Altp2MMode =3D 3 ) =20 +type XsQuotaItem struct { +Name string +Val uint32 +} + +type XsQuotaSet struct { +Quota []XsQuotaItem +} + type DomainBuildInfo struct { MaxVcpus int AvailVcpus Bitmap diff --git a/tools/include/libxl.h b/tools/include/libxl.h index bc35e412da..a70d9d347f 100644 --- a/tools/include/libxl.h +++ b/tools/include/libxl.h @@ -1537,6 +1537,18 @@ void libxl_mac_copy(libxl_ctx *ctx, libxl_mac *dst, = const libxl_mac *src); */ #define LIBXL_HAVE_XEN_PLATFORM_PCI_BAR_UC =20 +/* + * LIBXL_HAVE_XENSTORE_QUOTA + * + * If this is defined the Xenstore quota related functions + * libxl_xsquota_global_get() + * libxl_xsquota_global_set() + * libxl_xsquota_domain_get() + * libxl_xsquota_domain_set() + * are available. + */ +#define LIBXL_HAVE_XENSTORE_QUOTA + typedef char **libxl_string_list; void libxl_string_list_dispose(libxl_string_list *sl); int libxl_string_list_length(const libxl_string_list *sl); @@ -3011,6 +3023,14 @@ static inline int libxl_qemu_monitor_command_0x04120= 0(libxl_ctx *ctx, #define libxl_qemu_monitor_command libxl_qemu_monitor_command_0x041200 #endif =20 +/* Get/set global and per-domain Xenstore quota. */ +int libxl_xsquota_global_get(libxl_ctx *ctx, libxl_xs_quota_set *q); +int libxl_xsquota_global_set(libxl_ctx *ctx, libxl_xs_quota_set *q); +int libxl_xsquota_domain_get(libxl_ctx *ctx, uint32_t domid, + libxl_xs_quota_set *q); +int libxl_xsquota_domain_set(libxl_ctx *ctx, uint32_t domid, + libxl_xs_quota_set *q); + #include =20 /* diff --git a/tools/libs/light/Makefile b/tools/libs/light/Makefile index bc60c46558..ca22a40c6c 100644 --- a/tools/libs/light/Makefile +++ b/tools/libs/light/Makefile @@ -106,6 +106,7 @@ OBJS-y +=3D libxl_pvcalls.o OBJS-y +=3D libxl_vsnd.o OBJS-y +=3D libxl_vkb.o OBJS-y +=3D libxl_virtio.o +OBJS-y +=3D libxl_xsquota.o OBJS-y +=3D libxl_genid.o OBJS-y +=3D _libxl_types.o OBJS-y +=3D libxl_flask.o diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_type= s.idl index d64a573ff3..c5ddc40f35 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -574,6 +574,15 @@ libxl_altp2m_mode =3D Enumeration("altp2m_mode", [ (3, "limited"), ], init_val =3D "LIBXL_ALTP2M_MODE_DISABLED") =20 +libxl_xs_quota_item =3D Struct("xs_quota_item", [ + ("name", string), + ("val", uint32), + ]) + +libxl_xs_quota_set =3D Struct("xs_quota_set", [ + ("quota", Array(libxl_xs_quota_item, "num_quota")) + ]) + libxl_domain_build_info =3D Struct("domain_build_info",[ ("max_vcpus", integer), ("avail_vcpus", libxl_bitmap), diff --git a/tools/libs/light/libxl_xsquota.c b/tools/libs/light/libxl_xsqu= ota.c new file mode 100644 index 0000000000..b9afa1c914 --- /dev/null +++ b/tools/libs/light/libxl_xsquota.c @@ -0,0 +1,102 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +/* Xenstore quota handling functions. */ + +#include "libxl_internal.h" + +static int get_quota(libxl_ctx *ctx, unsigned int domid, libxl_xs_quota_se= t *q, + bool (func)(struct xs_handle *h, unsigned int domid, + char *quota, unsigned int *value)) +{ + char **names; + unsigned int num, i; + int rc =3D 0; + GC_INIT(ctx); + + names =3D xs_get_quota_names(ctx->xsh, &num); + if (!names) { + /* Xenstore quota support is optional! */ + if (errno !=3D ENOSYS) + rc =3D ERROR_FAIL; + q->num_quota =3D 0; + goto out; + } + + q->num_quota =3D num; + q->quota =3D libxl__calloc(NOGC, num, sizeof(*q->quota)); + for (i =3D 0; i < num; i++) { + q->quota[i].name =3D libxl__strdup(NOGC, names[i]); + if (!func(ctx->xsh, domid, q->quota[i].name, &q->quota[i].val)) { + libxl_xs_quota_set_dispose(q); + rc =3D ERROR_FAIL; + break; + } + } + + free(names); + + out: + GC_FREE; + return rc; +} + +static int set_quota(libxl_ctx *ctx, unsigned int domid, libxl_xs_quota_se= t *q, + bool (func)(struct xs_handle *h, unsigned int domid, + char *quota, unsigned int value)) +{ + unsigned int i; + int rc =3D 0; + GC_INIT(ctx); + + for (i =3D 0; i < q->num_quota; i++) { + if (!func(ctx->xsh, domid, q->quota[i].name, q->quota[i].val)) { + rc =3D ERROR_FAIL; + break; + } + } + + GC_FREE; + return rc; +} + +static bool get_global_quota(struct xs_handle *h, unsigned int domid, + char *quota, unsigned int *value) +{ + return xs_get_global_quota(h, quota, value); +} + +int libxl_xsquota_global_get(libxl_ctx *ctx, libxl_xs_quota_set *q) +{ + return get_quota(ctx, 0, q, get_global_quota); +} + +static bool set_global_quota(struct xs_handle *h, unsigned int domid, + char *quota, unsigned int value) +{ + return xs_set_global_quota(h, quota, value); +} + +int libxl_xsquota_global_set(libxl_ctx *ctx, libxl_xs_quota_set *q) +{ + return set_quota(ctx, 0, q, set_global_quota);; +} + +int libxl_xsquota_domain_get(libxl_ctx *ctx, uint32_t domid, + libxl_xs_quota_set *q) +{ + return get_quota(ctx, domid, q, xs_get_domain_quota); +} + +int libxl_xsquota_domain_set(libxl_ctx *ctx, uint32_t domid, + libxl_xs_quota_set *q) +{ + return set_quota(ctx, domid, q, xs_set_domain_quota); +} + +/* + * Local variables: + * mode: C + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ --=20 2.53.0 From nobody Mon Apr 13 02:02:06 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=1772719098; cv=none; d=zohomail.com; s=zohoarc; b=eVjnSnhkRozB/CYgCxfL2J0Poba0GnEqO6mMmflgzuJIdR9b1rA/Gtm7RkZbuRkaHzFuesukOVLvOti66OJRM70wz44vpqXW6CsMWRbR56awpshW3lHmg8JcP8CyUsNa7GPrBCN7xWSBQeUVBVsUAlgKQmi0BfZJb7vElkg5mlw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1772719098; 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=+0vTnaLiNIbBDWIqxe6qxu0BI40b3mH2UzHvF/8/7sk=; b=BAfCrcV3t8mcnViLVpuEowIcpJXZyA8TG4E664zTMve62mpyeVQDGCUc3HiCdgLku1ymof7QpP4kKqAkJXIICyrsIEWdtIixqTQxqUEA9n//c4qdz5xLhGp5x6u72VY9qTN26EWz9SlcdF+y24fZCrGWJ+9VL89j4PDAG1+SMOk= 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 1772719098186339.1832445591956; Thu, 5 Mar 2026 05:58:18 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246746.1545858 (Exim 4.92) (envelope-from ) id 1vy9DJ-0004l1-Vv; Thu, 05 Mar 2026 13:58:05 +0000 Received: by outflank-mailman (output) from mailman id 1246746.1545858; Thu, 05 Mar 2026 13:58:05 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy9DJ-0004ks-TD; Thu, 05 Mar 2026 13:58:05 +0000 Received: by outflank-mailman (input) for mailman id 1246746; Thu, 05 Mar 2026 13:58:03 +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 1vy98P-0008Mq-P5 for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:53:01 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.223.131]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 9f7a8dd3-189a-11f1-b164-2bf370ae4941; Thu, 05 Mar 2026 14:53:00 +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 5CC845BDE2; Thu, 5 Mar 2026 13:52:59 +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 3790B3EA68; Thu, 5 Mar 2026 13:52:59 +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 AX2ADLuKqWkdTwAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:52:59 +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: 9f7a8dd3-189a-11f1-b164-2bf370ae4941 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718779; 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=+0vTnaLiNIbBDWIqxe6qxu0BI40b3mH2UzHvF/8/7sk=; b=klfusZ5eK/BCbJuwI8jkcOy1FBZfH3lLFFtXZ5cbMAIDCTV/fZ+HaE4DXwFtf6rfrk7mSW tY86rV0uUs+vbKeXv9rwhwHnlQn8kK6cIzwH+RjPXqK0Ar3Isc/qmA11M47kNVxMExrjeo cOfQPCSdK0HTgKIcZBzhYfrUi/Jnj4s= Authentication-Results: smtp-out2.suse.de; none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1772718779; 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=+0vTnaLiNIbBDWIqxe6qxu0BI40b3mH2UzHvF/8/7sk=; b=klfusZ5eK/BCbJuwI8jkcOy1FBZfH3lLFFtXZ5cbMAIDCTV/fZ+HaE4DXwFtf6rfrk7mSW tY86rV0uUs+vbKeXv9rwhwHnlQn8kK6cIzwH+RjPXqK0Ar3Isc/qmA11M47kNVxMExrjeo cOfQPCSdK0HTgKIcZBzhYfrUi/Jnj4s= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Nick Rosbrook , George Dunlap , Anthony PERARD Subject: [PATCH 09/11] tools/libxl: add support for xenstore quota in domain_config Date: Thu, 5 Mar 2026 14:52:06 +0100 Message-ID: <20260305135208.2208663-10-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)[99.99%]; NEURAL_HAM_LONG(-1.00)[-1.000]; MID_CONTAINS_FROM(1.00)[]; R_MISSING_CHARSET(0.50)[]; NEURAL_HAM_SHORT(-0.19)[-0.967]; 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_FIVE(0.00)[5]; 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: 1772719100417158500 Content-Type: text/plain; charset="utf-8" Add support for xenstore quota in the struct domain_config. Initially it will be used only for migration of a domain. Signed-off-by: Juergen Gross Acked-by: Nick Rosbrook xsh, domid, state->store_mfn, state->store_po= rt); =20 + if (info->xenstore_quota.num_quota) { + rc =3D libxl_xsquota_domain_set(ctx, domid, &info->xenstore_quota); + if (rc) { + LOGED(ERROR, domid, "Failed to set Xenstore quota"); + goto out; + } + } + out: free(vm_path); return rc; diff --git a/tools/libs/light/libxl_domain.c b/tools/libs/light/libxl_domai= n.c index 5be47f687f..86e43e7133 100644 --- a/tools/libs/light/libxl_domain.c +++ b/tools/libs/light/libxl_domain.c @@ -2533,6 +2533,16 @@ static void retrieve_domain_configuration_end(libxl_= _egc *egc, } } =20 + /* Xenstore quota */ + { + libxl_xs_quota_set_dispose(&d_config->b_info.xenstore_quota); + rc =3D libxl_xsquota_domain_get(CTX, domid, &d_config->b_info.xens= tore_quota); + if (rc) { + LOGD(ERROR, domid, "Fail to get xenstore quota"); + goto out; + } + } + /* Devices: disk, nic, vtpm, pcidev etc. */ =20 /* The MERGE macro implements following logic: diff --git a/tools/libs/light/libxl_types.idl b/tools/libs/light/libxl_type= s.idl index c5ddc40f35..ee8f89e462 100644 --- a/tools/libs/light/libxl_types.idl +++ b/tools/libs/light/libxl_types.idl @@ -760,6 +760,7 @@ libxl_domain_build_info =3D Struct("domain_build_info",[ ("vpmu", libxl_defbool), ("trap_unmapped_accesses", libxl_defbool), ("xenstore_feature_mask", uint32, {'init_val': '~0U'}), + ("xenstore_quota", libxl_xs_quota_set), =20 ], dir=3DDIR_IN, copy_deprecated_fn=3D"libxl__domain_build_info_copy_deprecated", --=20 2.53.0 From nobody Mon Apr 13 02:02:06 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 1772719099353611.6820343149838; Thu, 5 Mar 2026 05:58:19 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246748.1545868 (Exim 4.92) (envelope-from ) id 1vy9DK-0004t4-Hw; Thu, 05 Mar 2026 13:58:06 +0000 Received: by outflank-mailman (output) from mailman id 1246748.1545868; Thu, 05 Mar 2026 13:58:06 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy9DK-0004rp-Cg; Thu, 05 Mar 2026 13:58:06 +0000 Received: by outflank-mailman (input) for mailman id 1246748; Thu, 05 Mar 2026 13:58:04 +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 1vy98U-00008m-Nz for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:53:06 +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 a217b1b9-189a-11f1-9ccf-f158ae23cfc8; Thu, 05 Mar 2026 14:53:05 +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-out2.suse.de (Postfix) with ESMTPS id C4B155BDE2; Thu, 5 Mar 2026 13:53:04 +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 A8D5B3EA68; Thu, 5 Mar 2026 13:53:04 +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 Dg0lKMCKqWkmTwAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:53:04 +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: a217b1b9-189a-11f1-9ccf-f158ae23cfc8 Authentication-Results: smtp-out2.suse.de; none From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Anthony PERARD Subject: [PATCH 10/11] tools/xl: add xl commands for xenstore quota operations Date: Thu, 5 Mar 2026 14:52:07 +0100 Message-ID: <20260305135208.2208663-11-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-Server: rspamd2.dmz-prg2.suse.org X-Spamd-Result: default: False [-4.00 / 50.00]; REPLY(-4.00)[] X-Rspamd-Queue-Id: C4B155BDE2 X-Rspamd-Pre-Result: action=no action; module=replies; Message is reply to one we originated X-Rspamd-Action: no action X-Spam-Flag: NO X-Spam-Score: -4.00 X-Spam-Level: X-ZM-MESSAGEID: 1772719099675154100 Content-Type: text/plain; charset="utf-8" Add "xl xenstore-quota-get" and "xl xenstore-quota-set" commands for retrieving and setting global and per-domain Xenstore quota. Signed-off-by: Juergen Gross --- tools/xl/Makefile | 1 + tools/xl/xl.h | 2 + tools/xl/xl_cmdtable.c | 10 +++++ tools/xl/xl_parse.c | 25 ++++++++++++ tools/xl/xl_parse.h | 1 + tools/xl/xl_xsquota.c | 88 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 127 insertions(+) create mode 100644 tools/xl/xl_xsquota.c diff --git a/tools/xl/Makefile b/tools/xl/Makefile index 973ff0e1a2..e4eed8be13 100644 --- a/tools/xl/Makefile +++ b/tools/xl/Makefile @@ -24,6 +24,7 @@ XL_OBJS +=3D xl_sched.o xl_pci.o xl_vcpu.o xl_cdrom.o xl_= mem.o XL_OBJS +=3D xl_info.o xl_console.o xl_misc.o XL_OBJS +=3D xl_vmcontrol.o xl_saverestore.o xl_migrate.o XL_OBJS +=3D xl_vdispl.o xl_vsnd.o xl_vkb.o +XL_OBJS +=3D xl_xsquota.o =20 $(XL_OBJS): CFLAGS +=3D $(CFLAGS_libxentoollog) $(XL_OBJS): CFLAGS +=3D $(CFLAGS_XL) diff --git a/tools/xl/xl.h b/tools/xl/xl.h index 9000df00de..0efc07a6ba 100644 --- a/tools/xl/xl.h +++ b/tools/xl/xl.h @@ -217,6 +217,8 @@ int main_psr_mba_set(int argc, char **argv); int main_psr_mba_show(int argc, char **argv); #endif int main_qemu_monitor_command(int argc, char **argv); +int main_xsquota_get(int argc, char **argv); +int main_xsquota_set(int argc, char **argv); =20 void help(const char *command); =20 diff --git a/tools/xl/xl_cmdtable.c b/tools/xl/xl_cmdtable.c index 06a0039718..3de12b12ae 100644 --- a/tools/xl/xl_cmdtable.c +++ b/tools/xl/xl_cmdtable.c @@ -649,6 +649,16 @@ const struct cmd_spec cmd_table[] =3D { "-h print this help\n" }, #endif + { "xenstore-quota-get", + &main_xsquota_get, 0, 0, + "List global or domain specific Xenstore quota data", + "|-g", + }, + { "xenstore-quota-set", + &main_xsquota_set, 0, 1, + "Set global or domain specific Xenstore quota data", + "|-g =3D...", + }, }; =20 const int cmdtable_len =3D ARRAY_SIZE(cmd_table); diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 1a2ea8b5d5..934ad4eeef 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1314,6 +1314,31 @@ out: return ret; } =20 +int parse_xsquota_item(const char *buf, struct libxl_xs_quota_item *item) +{ + const char *eq; + char *endptr; + + eq =3D strchr(buf, '=3D'); + if (!eq) { + fprintf(stderr, "Quota specification \"%s\" lacks \"=3D\".\n", buf= ); + return ERROR_INVAL; + } + errno =3D 0; + item->name =3D strndup(buf, eq - buf); + if (!item->name) + return ERROR_NOMEM; + item->val =3D strtoul(eq + 1, &endptr, 0); + if (errno || !eq[1] || *endptr) { + fprintf(stderr, + "Quota specification \"%s\" uses illegal value \"%s\".\n", + buf, eq); + return ERROR_INVAL; + } + + return 0; +} + void parse_config_data(const char *config_source, const char *config_data, int config_len, diff --git a/tools/xl/xl_parse.h b/tools/xl/xl_parse.h index fe0d586cdd..57bb43a067 100644 --- a/tools/xl/xl_parse.h +++ b/tools/xl/xl_parse.h @@ -36,6 +36,7 @@ int parse_nic_config(libxl_device_nic *nic, XLU_Config **= config, char *token); int parse_vdispl_config(libxl_device_vdispl *vdispl, char *token); int parse_vsnd_item(libxl_device_vsnd *vsnd, const char *spec); int parse_vkb_config(libxl_device_vkb *vkb, char *token); +int parse_xsquota_item(const char *buf, struct libxl_xs_quota_item *item); =20 int match_option_size(const char *prefix, size_t len, char *arg, char **argopt); diff --git a/tools/xl/xl_xsquota.c b/tools/xl/xl_xsquota.c new file mode 100644 index 0000000000..eaf19feac8 --- /dev/null +++ b/tools/xl/xl_xsquota.c @@ -0,0 +1,88 @@ +/* SPDX-License-Identifier: LGPL-2.1-only */ + +#include +#include +#include +#include + +#include "xl.h" +#include "xl_utils.h" +#include "xl_parse.h" + +int main_xsquota_get(int argc, char **argv) +{ + libxl_xs_quota_set q; + unsigned int i; + int rc; + + if (argc !=3D 2) { + fprintf(stderr, "Domain or \"-g\" must be specified.\n"); + return EXIT_FAILURE; + } + + if (!strcmp(argv[1], "-g")) { + rc =3D libxl_xsquota_global_get(ctx, &q); + } else { + uint32_t domid =3D find_domain(argv[1]); + + rc =3D libxl_xsquota_domain_get(ctx, domid, &q); + } + + if (rc) { + fprintf(stderr, "Quota could not be obtained.\n"); + return EXIT_FAILURE; + } + + printf("Quota name Quota value\n"); + printf("--------------------------------\n"); + for (i =3D 0; i < q.num_quota; i++) + printf("%-20s %8u\n", q.quota[i].name, q.quota[i].val); + + libxl_xs_quota_set_dispose(&q); + + return EXIT_SUCCESS; +} + +int main_xsquota_set(int argc, char **argv) +{ + unsigned int i; + libxl_xs_quota_set q; + int rc =3D EXIT_FAILURE; + + if (argc < 3) { + fprintf(stderr, "Not enough parameters.\n"); + return EXIT_FAILURE; + } + + q.num_quota =3D argc - 2; + q.quota =3D calloc(q.num_quota, sizeof(*q.quota)); + if (!q.quota) { + fprintf(stderr, "Memory allocation failure!\n"); + goto err; + } + + for (i =3D 2; i < argc; i++) { + if (parse_xsquota_item(argv[i], q.quota + i - 2)) + goto err; + } + + if (!strcmp(argv[1], "-g")) { + rc =3D libxl_xsquota_global_set(ctx, &q); + } else { + uint32_t domid =3D find_domain(argv[1]); + + rc =3D libxl_xsquota_domain_set(ctx, domid, &q); + } + + if (rc) { + fprintf(stderr, "Quota could not be set.\n"); + rc =3D EXIT_FAILURE; + } else { + rc =3D EXIT_SUCCESS; + } + + err: + libxl_xs_quota_set_dispose(&q); + + return rc; +} --=20 2.53.0 From nobody Mon Apr 13 02:02:06 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 1772719107450767.4861789777042; Thu, 5 Mar 2026 05:58:27 -0800 (PST) Received: from list by lists.xenproject.org with outflank-mailman.1246751.1545888 (Exim 4.92) (envelope-from ) id 1vy9DL-0005QS-VK; Thu, 05 Mar 2026 13:58:07 +0000 Received: by outflank-mailman (output) from mailman id 1246751.1545888; Thu, 05 Mar 2026 13:58:07 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1vy9DL-0005PX-Pz; Thu, 05 Mar 2026 13:58:07 +0000 Received: by outflank-mailman (input) for mailman id 1246751; Thu, 05 Mar 2026 13:58:06 +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 1vy98a-00008m-2A for xen-devel@lists.xenproject.org; Thu, 05 Mar 2026 13:53:12 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [2a07:de40:b251:101:10:150:64:2]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id a554fb30-189a-11f1-9ccf-f158ae23cfc8; Thu, 05 Mar 2026 14:53:10 +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-out2.suse.de (Postfix) with ESMTPS id 37CAA5BD98; Thu, 5 Mar 2026 13:53:10 +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 1BB9B3EA68; Thu, 5 Mar 2026 13:53:10 +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 qQ2hBcaKqWktTwAAD6G6ig (envelope-from ); Thu, 05 Mar 2026 13:53:10 +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: a554fb30-189a-11f1-9ccf-f158ae23cfc8 Authentication-Results: smtp-out2.suse.de; none From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Anthony PERARD Subject: [PATCH 11/11] tools/xl: add support for xenstore quota setting via domain config Date: Thu, 5 Mar 2026 14:52:08 +0100 Message-ID: <20260305135208.2208663-12-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: 37CAA5BD98 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: 1772719108348158500 Content-Type: text/plain; charset="utf-8" Add a new "xenstore-quota" domain config parameter for setting the Xenstore quota of a new domain via a list of =3D items. Signed-off-by: Juergen Gross --- docs/man/xl.cfg.5.pod.in | 13 +++++++++++++ tools/xl/xl_parse.c | 23 ++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/docs/man/xl.cfg.5.pod.in b/docs/man/xl.cfg.5.pod.in index 27c455210b..3aac0bc4fb 100644 --- a/docs/man/xl.cfg.5.pod.in +++ b/docs/man/xl.cfg.5.pod.in @@ -748,6 +748,19 @@ via the B command in dom0. The default value is B<0xffffffff>, meaning that all possible Xenstore features are visible by the guest. =20 +=3Ditem B + +Specifies Xenstore quota values of the domain, overriding the default +values of Xenstore. + +Each B is a B=3DB specification. The suppor= ted +B identifiers can be obtained by the B +command. B is a non-negative integer. + +As per-domain Xenstore quota are an optional Xenstore feature, the +B config parameter may not be supported by all Xenstore +implementations. + =3Dback =20 =3Dhead2 Devices diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 934ad4eeef..06a5b60736 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1351,7 +1351,7 @@ void parse_config_data(const char *config_source, XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms, *usbctrls, *usbdevs, *p9devs, *vdispls, *pvcallsifs_dev= s; XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs, - *mca_caps, *smbios, *llc_colors; + *mca_caps, *smbios, *llc_colors, *xs_quota; int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian, num_mca_= caps; int num_smbios; int pci_power_mgmt =3D 0; @@ -1360,6 +1360,7 @@ void parse_config_data(const char *config_source, int pci_seize =3D 0; int i, e; int num_llc_colors; + int num_xs_quota; char *kernel_basename; =20 libxl_domain_create_info *c_info =3D &d_config->c_info; @@ -1467,6 +1468,26 @@ void parse_config_data(const char *config_source, if (!xlu_cfg_get_long (config, "xenstore_feature_mask", &l, 0)) b_info->xenstore_feature_mask =3D l; =20 + if (!xlu_cfg_get_list(config, "xenstore_quota", &xs_quota, &num_xs_quo= ta, 0)) { + b_info->xenstore_quota.num_quota =3D num_xs_quota; + b_info->xenstore_quota.quota =3D calloc(num_xs_quota, sizeof(* b_i= nfo->xenstore_quota.quota)); + if (b_info->xenstore_quota.quota =3D=3D NULL) { + fprintf(stderr, "unable to allocate memory for xenstore_quota\= n"); + exit(-1); + } + + for (i =3D 0; i < num_xs_quota; i++) { + buf =3D xlu_cfg_get_listitem(xs_quota, i); + if (!buf) { + fprintf(stderr, + "xl: Can't get element %d in Xenstore quota list\n= ", i); + exit(1); + } + if (parse_xsquota_item(buf, b_info->xenstore_quota.quota + i)) + exit(1); + } + } + libxl_domain_build_info_init_type(b_info, c_info->type); =20 if (b_info->type =3D=3D LIBXL_DOMAIN_TYPE_PVH) { --=20 2.53.0