From patchwork Tue Nov 1 16:04:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027135 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0E423C4332F for ; Tue, 1 Nov 2022 16:04:49 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435037.688019 (Exim 4.92) (envelope-from ) id 1optkf-0003Ys-Sj; Tue, 01 Nov 2022 16:04:33 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435037.688019; Tue, 01 Nov 2022 16:04:33 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1optkf-0003Yl-QB; Tue, 01 Nov 2022 16:04:33 +0000 Received: by outflank-mailman (input) for mailman id 435037; Tue, 01 Nov 2022 16:04:31 +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 1optkd-0003Iv-R5 for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:04:31 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [2001:67c:2178:6::1c]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id de8dce0d-59fe-11ed-91b5-6bf2151ebd3b; Tue, 01 Nov 2022 17:04:31 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id C8C1822566; Tue, 1 Nov 2022 16:04:30 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 99B781346F; Tue, 1 Nov 2022 16:04:30 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id yt4pJI5DYWMlcgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:04:30 +0000 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: de8dce0d-59fe-11ed-91b5-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318670; 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=ClK+S4fe5XoEXGnmTytfGm/UdGaWd4a4uXnR/ciAATo=; b=WMGNJh12bIYiZ3wI7cv2gXwEYFjkKcD1gXNtYdWxfxaXL/kQI0nRODknx7zA9E/mJNMdWw AbYTfI8vpU9MlilXn7mveQ2OoEBHanYIDRq60xbbXbcQVTsV+HNrzd/AVWCfnPwYBicJr7 oLOfTYleBpgd/t4E6+CAHPOFD71dXfk= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 01/12] tools/xenstore: manage per-transaction domain accounting data in an array Date: Tue, 1 Nov 2022 17:04:11 +0100 Message-Id: <20221101160422.7212-2-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 In order to prepare keeping accounting data in an array instead of using independent fields, switch the struct changed_domain accounting data to that scheme, for now only using an array with one element. In order to be able to extend this scheme add the needed indexing enum to xenstored_domain.h. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_domain.c | 17 +++++++++-------- tools/xenstore/xenstored_domain.h | 5 +++++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 582b78b0ee..399fc920bb 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -99,8 +99,8 @@ struct changed_domain /* Identifier of the changed domain. */ unsigned int domid; - /* Amount by which this domain's nbentry field has changed. */ - int nbentry; + /* Accounting data. */ + int acc[ACC_TR_N]; }; static struct hashtable *domhash; @@ -558,7 +558,7 @@ int acc_fix_domains(struct list_head *head, bool update) int cnt; list_for_each_entry(cd, head, list) { - cnt = domain_nbentry_fix(cd->domid, cd->nbentry, update); + cnt = domain_nbentry_fix(cd->domid, cd->acc[ACC_NODES], update); if (!update) { if (cnt >= quota_nb_entry_per_domain) return ENOSPC; @@ -603,8 +603,8 @@ static struct changed_domain *acc_get_changed_domain(const void *ctx, return cd; } -static int acc_add_dom_nbentry(const void *ctx, struct list_head *head, int val, - unsigned int domid) +static int acc_add_changed_dom(const void *ctx, struct list_head *head, + unsigned int what, int val, unsigned int domid) { struct changed_domain *cd; @@ -613,9 +613,9 @@ static int acc_add_dom_nbentry(const void *ctx, struct list_head *head, int val, return 0; errno = 0; - cd->nbentry += val; + cd->acc[what] += val; - return cd->nbentry; + return cd->acc[what]; } static void domain_conn_reset(struct domain *domain) @@ -1076,7 +1076,8 @@ static int domain_nbentry_add(struct connection *conn, unsigned int domid, if (conn && conn->transaction) { head = transaction_get_changed_domains(conn->transaction); - ret = acc_add_dom_nbentry(conn->transaction, head, add, domid); + ret = acc_add_changed_dom(conn->transaction, head, ACC_NODES, + add, domid); if (errno) { fail_transaction(conn->transaction); return -1; diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index dc4660861e..124b9e1b1e 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -19,6 +19,11 @@ #ifndef _XENSTORED_DOMAIN_H #define _XENSTORED_DOMAIN_H +enum { + ACC_NODES, + ACC_TR_N /* Number of elements per transaction and domain. */ +}; + void handle_event(void); void check_domains(void); From patchwork Tue Nov 1 16:04:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027136 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 77E05C43217 for ; Tue, 1 Nov 2022 16:04:49 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435038.688031 (Exim 4.92) (envelope-from ) id 1optkk-0003rH-8z; Tue, 01 Nov 2022 16:04:38 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435038.688031; Tue, 01 Nov 2022 16:04: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 1optkk-0003rA-5R; Tue, 01 Nov 2022 16:04:38 +0000 Received: by outflank-mailman (input) for mailman id 435038; Tue, 01 Nov 2022 16:04:37 +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 1optkj-0003qE-Np for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:04:37 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id e1e10eb0-59fe-11ed-8fd0-01056ac49cbb; Tue, 01 Nov 2022 17:04:36 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 608D722537; Tue, 1 Nov 2022 16:04:36 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 3284A1346F; Tue, 1 Nov 2022 16:04:36 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id FaD6CpRDYWMycgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:04:36 +0000 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: e1e10eb0-59fe-11ed-8fd0-01056ac49cbb DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318676; 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=uACmj/0xjTQgTK11Nj7tD8GLil4Q1EMyFQ4FTisl410=; b=uj9PoVHih8X6+Qj6VH/DwWL2AaF+jbV6F7rDsIC7Wrng93xyqd1PKALhdxtngFvQjBs2f/ CO5e2/D1/HR+nmExURebiOErvwazI8xu0mVvczMlySOixcYn4zeIZRy2fR3xqH9j0lVUtY SlfuZUueJSi9PG3PgmQ/HdohGNjAxOA= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 02/12] tools/xenstore: introduce accounting data array for per-domain values Date: Tue, 1 Nov 2022 17:04:12 +0100 Message-Id: <20221101160422.7212-3-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 Introduce the scheme of an accounting data array for per-domain accounting data and use it initially for the number of nodes owned by a domain. Make the accounting data type to be unsigned int, as no data is allowed to be negative at any time. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_domain.c | 55 ++++++++++++++++++++----------- tools/xenstore/xenstored_domain.h | 5 +-- 2 files changed, 38 insertions(+), 22 deletions(-) diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 399fc920bb..9591a19189 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -69,8 +69,8 @@ struct domain /* Has domain been officially introduced? */ bool introduced; - /* number of entry from this domain in the store */ - int nbentry; + /* Accounting data for this domain. */ + unsigned int acc[ACC_N]; /* Amount of memory allocated for this domain. */ int memory; @@ -246,7 +246,7 @@ static int domain_tree_remove_sub(const void *ctx, struct connection *conn, if (keep_orphans) { set_tdb_key(node->name, &key); - domain->nbentry--; + domain_nbentry_dec(NULL, domain->domid); node->perms.p[0].id = priv_domid; node->acc.memory = 0; domain_nbentry_inc(NULL, priv_domid); @@ -270,7 +270,7 @@ static int domain_tree_remove_sub(const void *ctx, struct connection *conn, ret = WALK_TREE_SKIP_CHILDREN; } - return domain->nbentry > 0 ? ret : WALK_TREE_SUCCESS_STOP; + return domain->acc[ACC_NODES] ? ret : WALK_TREE_SUCCESS_STOP; } static void domain_tree_remove(struct domain *domain) @@ -278,7 +278,7 @@ static void domain_tree_remove(struct domain *domain) int ret; struct walk_funcs walkfuncs = { .enter = domain_tree_remove_sub }; - if (domain->nbentry > 0) { + if (domain->acc[ACC_NODES]) { ret = walk_node_tree(domain, NULL, "/", &walkfuncs, domain); if (ret == WALK_TREE_ERROR_STOP) syslog(LOG_ERR, @@ -441,7 +441,7 @@ int domain_get_quota(const void *ctx, struct connection *conn, resp = talloc_asprintf_append(resp, "%-16s: %8d\n", #t, e); \ if (!resp) return ENOMEM - ent(nodes, d->nbentry); + ent(nodes, d->acc[ACC_NODES]); ent(watches, d->nbwatch); ent(transactions, ta); ent(outstanding, d->nboutstanding); @@ -1050,8 +1050,21 @@ int domain_adjust_node_perms(struct node *node) return 0; } -static int domain_nbentry_add(struct connection *conn, unsigned int domid, - int add, bool dom_exists) +static int domain_acc_add_chk(struct domain *d, unsigned int what, int add, + unsigned int domid) +{ + if ((add < 0 && -add > d->acc[what]) || + (d->acc[what] + add) > INT_MAX) { + syslog(LOG_ERR, "Accounting error: domain %u type %u val %u\n", + domid, what, d->acc[what] + add); + return (add < 0) ? 0 : INT_MAX; + } + + return d->acc[what] + add; +} + +static int domain_acc_add(struct connection *conn, unsigned int domid, + unsigned int what, int add, bool dom_exists) { struct domain *d; struct list_head *head; @@ -1074,47 +1087,49 @@ static int domain_nbentry_add(struct connection *conn, unsigned int domid, } } - if (conn && conn->transaction) { + if (conn && conn->transaction && what < ACC_TR_N) { head = transaction_get_changed_domains(conn->transaction); - ret = acc_add_changed_dom(conn->transaction, head, ACC_NODES, + ret = acc_add_changed_dom(conn->transaction, head, what, add, domid); if (errno) { fail_transaction(conn->transaction); return -1; } - return d->nbentry + ret; + return domain_acc_add_chk(d, what, ret, domid); } - d->nbentry += add; + d->acc[what] = domain_acc_add_chk(d, what, add, domid); - return d->nbentry; + return d->acc[what]; } int domain_nbentry_inc(struct connection *conn, unsigned int domid) { - return (domain_nbentry_add(conn, domid, 1, false) < 0) ? errno : 0; + return (domain_acc_add(conn, domid, ACC_NODES, 1, false) < 0) + ? errno : 0; } int domain_nbentry_dec(struct connection *conn, unsigned int domid) { - return (domain_nbentry_add(conn, domid, -1, true) < 0) ? errno : 0; + return (domain_acc_add(conn, domid, ACC_NODES, -1, true) < 0) + ? errno : 0; } int domain_nbentry_fix(unsigned int domid, int num, bool update) { int ret; - ret = domain_nbentry_add(NULL, domid, update ? num : 0, update); + ret = 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; } -int domain_nbentry(struct connection *conn) +unsigned int domain_nbentry(struct connection *conn) { return domain_is_unprivileged(conn) - ? domain_nbentry_add(conn, conn->id, 0, true) : 0; + ? domain_acc_add(conn, conn->id, ACC_NODES, 0, true) : 0; } static bool domain_chk_quota(struct domain *domain, int mem) @@ -1591,7 +1606,7 @@ static int domain_check_acc_init_sub(void *k, void *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 = -d->nbentry; + dom->nodes = -d->acc[ACC_NODES]; if (!hashtable_insert(domains, &dom->domid, dom)) { talloc_free(dom); @@ -1646,7 +1661,7 @@ static int domain_check_acc_sub(void *k, void *v, void *arg) if (!d) return 0; - d->nbentry += dom->nodes; + d->acc[ACC_NODES] += dom->nodes; return 0; } diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index 124b9e1b1e..d2563d33e7 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -21,7 +21,8 @@ enum { ACC_NODES, - ACC_TR_N /* Number of elements per transaction and domain. */ + ACC_TR_N, /* Number of elements per transaction and domain. */ + ACC_N = ACC_TR_N /* Number of elements per domain. */ }; void handle_event(void); @@ -72,7 +73,7 @@ int domain_alloc_permrefs(struct node_perms *perms); 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); -int domain_nbentry(struct connection *conn); +unsigned int domain_nbentry(struct connection *conn); int domain_memory_add(unsigned int domid, int mem, bool no_quota_check); /* From patchwork Tue Nov 1 16:04:13 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027138 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4E7ABC433FE for ; Tue, 1 Nov 2022 16:04:55 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435039.688042 (Exim 4.92) (envelope-from ) id 1optkq-0004Ck-JH; Tue, 01 Nov 2022 16:04:44 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435039.688042; Tue, 01 Nov 2022 16:04: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 1optkq-0004Cb-Ei; Tue, 01 Nov 2022 16:04:44 +0000 Received: by outflank-mailman (input) for mailman id 435039; Tue, 01 Nov 2022 16:04:43 +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 1optkp-0003Iv-1P for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:04:43 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [2001:67c:2178:6::1d]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id e530adac-59fe-11ed-91b5-6bf2151ebd3b; Tue, 01 Nov 2022 17:04:42 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id E95211F8CA; Tue, 1 Nov 2022 16:04:41 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id BEE201346F; Tue, 1 Nov 2022 16:04:41 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ZO9nLZlDYWNBcgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:04:41 +0000 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: e530adac-59fe-11ed-91b5-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318681; 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=k+yCodySqCz3qBnau8fT3yGc+modYKUB87SWoIcrsUE=; b=qLOvDUMdu/eNdUOlaVuZeksxGBpQy7T0s2ZoHdhSU+mP1cuepJC/vojdBUpunc/xzli7Qn kvrCi27DyXKX2ZwH3YWn41Mk4sOjGEQY9wlhdLXXs9yAKZ3IIRKsRO7n741jPdYi053M98 O26ySAu668YmT+PUDi0bk/1KpFO87v4= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 03/12] tools/xenstore: add framework to commit accounting data on success only Date: Tue, 1 Nov 2022 17:04:13 +0100 Message-Id: <20221101160422.7212-4-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 Instead of modifying accounting data and undo those modifications in case of an error during further processing, add a framework for collecting the needed changes and commit them only when the whole operation has succeeded. This scheme can reuse large parts of the per transaction accounting. The changed_domain handling can be reused, but the array size of the accounting data should be possible to be different for both use cases. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_core.c | 5 +++ tools/xenstore/xenstored_core.h | 3 ++ tools/xenstore/xenstored_domain.c | 61 ++++++++++++++++++++++++++++--- tools/xenstore/xenstored_domain.h | 5 ++- 4 files changed, 67 insertions(+), 7 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index ea0e6292d3..d437149622 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -1027,6 +1027,9 @@ static void send_error(struct connection *conn, int error) break; } } + + acc_drop(conn); + send_reply(conn, XS_ERROR, xsd_errors[i].errstring, strlen(xsd_errors[i].errstring) + 1); } @@ -1064,6 +1067,7 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type, } conn->in = NULL; + acc_commit(conn); /* Update relevant header fields and fill in the message body. */ bdata->hdr.msg.type = type; @@ -2186,6 +2190,7 @@ struct connection *new_connection(const struct interface_funcs *funcs) new->is_stalled = false; new->transaction_started = 0; INIT_LIST_HEAD(&new->out_list); + INIT_LIST_HEAD(&new->acc_list); INIT_LIST_HEAD(&new->ref_list); INIT_LIST_HEAD(&new->watches); INIT_LIST_HEAD(&new->transaction_list); diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index c85b15515c..8223a49354 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -139,6 +139,9 @@ struct connection struct list_head out_list; uint64_t timeout_msec; + /* Not yet committed accounting data (valid if in != NULL). */ + struct list_head acc_list; + /* Referenced requests no longer pending. */ struct list_head ref_list; diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 9591a19189..7988125f71 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -100,7 +100,7 @@ struct changed_domain unsigned int domid; /* Accounting data. */ - int acc[ACC_TR_N]; + int acc[]; }; static struct hashtable *domhash; @@ -585,6 +585,7 @@ static struct changed_domain *acc_find_changed_domain(struct list_head *head, static struct changed_domain *acc_get_changed_domain(const void *ctx, struct list_head *head, + unsigned int acc_sz, unsigned int domid) { struct changed_domain *cd; @@ -593,7 +594,7 @@ static struct changed_domain *acc_get_changed_domain(const void *ctx, if (cd) return cd; - cd = talloc_zero(ctx, struct changed_domain); + cd = talloc_zero_size(ctx, sizeof(*cd) + acc_sz * sizeof(cd->acc[0])); if (!cd) return NULL; @@ -604,11 +605,12 @@ static struct changed_domain *acc_get_changed_domain(const void *ctx, } static int acc_add_changed_dom(const void *ctx, struct list_head *head, - unsigned int what, int val, unsigned int domid) + unsigned int acc_sz, unsigned int what, + int val, unsigned int domid) { struct changed_domain *cd; - cd = acc_get_changed_domain(ctx, head, domid); + cd = acc_get_changed_domain(ctx, head, acc_sz, domid); if (!cd) return 0; @@ -1067,6 +1069,7 @@ static int domain_acc_add(struct connection *conn, unsigned int domid, unsigned int what, int add, bool dom_exists) { struct domain *d; + struct changed_domain *cd; struct list_head *head; int ret; @@ -1087,10 +1090,26 @@ static int domain_acc_add(struct connection *conn, unsigned int domid, } } + /* Temporary accounting data until final commit? */ + if (conn && conn->in && what < ACC_REQ_N) { + /* Consider transaction local data. */ + ret = 0; + if (conn->transaction && what < ACC_TR_N) { + head = transaction_get_changed_domains( + conn->transaction); + cd = acc_find_changed_domain(head, domid); + if (cd) + ret = cd->acc[what]; + } + ret += acc_add_changed_dom(conn->in, &conn->acc_list, ACC_REQ_N, + what, add, domid); + return errno ? -1 : domain_acc_add_chk(d, what, ret, domid); + } + if (conn && conn->transaction && what < ACC_TR_N) { head = transaction_get_changed_domains(conn->transaction); - ret = acc_add_changed_dom(conn->transaction, head, what, - add, domid); + ret = acc_add_changed_dom(conn->transaction, head, ACC_TR_N, + what, add, domid); if (errno) { fail_transaction(conn->transaction); return -1; @@ -1103,6 +1122,36 @@ static int domain_acc_add(struct connection *conn, unsigned int domid, return d->acc[what]; } +void acc_drop(struct connection *conn) +{ + struct changed_domain *cd; + + while ((cd = list_top(&conn->acc_list, struct changed_domain, list))) { + list_del(&cd->list); + talloc_free(cd); + } +} + +void acc_commit(struct connection *conn) +{ + struct changed_domain *cd; + struct buffered_data *in = conn->in; + unsigned int what; + + conn->in = NULL; /* Avoid recursion. */ + while ((cd = list_top(&conn->acc_list, struct changed_domain, list))) { + list_del(&cd->list); + for (what = 0; what < ACC_REQ_N; what++) + if (cd->acc[what]) + domain_acc_add(conn, cd->domid, what, + cd->acc[what], true); + + talloc_free(cd); + } + + conn->in = in; +} + int domain_nbentry_inc(struct connection *conn, unsigned int domid) { return (domain_acc_add(conn, domid, ACC_NODES, 1, false) < 0) diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index d2563d33e7..9959b2f2e4 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -20,7 +20,8 @@ #define _XENSTORED_DOMAIN_H enum { - ACC_NODES, + ACC_REQ_N, /* Number of elements per request and domain. */ + ACC_NODES = ACC_REQ_N, ACC_TR_N, /* Number of elements per transaction and domain. */ ACC_N = ACC_TR_N /* Number of elements per domain. */ }; @@ -103,6 +104,8 @@ void domain_outstanding_domid_dec(unsigned int domid); int domain_get_quota(const void *ctx, struct connection *conn, unsigned int domid); int acc_fix_domains(struct list_head *head, bool update); +void acc_drop(struct connection *conn); +void acc_commit(struct connection *conn); /* Write rate limiting */ From patchwork Tue Nov 1 16:04:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027139 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 73971C433FE for ; Tue, 1 Nov 2022 16:04:58 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435040.688052 (Exim 4.92) (envelope-from ) id 1optkv-0004bL-QR; Tue, 01 Nov 2022 16:04:49 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435040.688052; Tue, 01 Nov 2022 16:04:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1optkv-0004bC-N6; Tue, 01 Nov 2022 16:04:49 +0000 Received: by outflank-mailman (input) for mailman id 435040; Tue, 01 Nov 2022 16:04:48 +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 1optku-0003Iv-Co for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:04:48 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id e8823555-59fe-11ed-91b5-6bf2151ebd3b; Tue, 01 Nov 2022 17:04:47 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 7F0B61F8CA; Tue, 1 Nov 2022 16:04:47 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 522971346F; Tue, 1 Nov 2022 16:04:47 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id ivTHEp9DYWNLcgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:04:47 +0000 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: e8823555-59fe-11ed-91b5-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318687; 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=6FDt15mfZEArmZvoJOo527N0gTwrSVu9AiSo1IvcHbc=; b=OBcPfXbw3m0lmkiUREpm5sJR19ZG/eacbsBhCZcnY8iexXdGYYqawa9dUTtz+/8rbhWov1 jF5bHeVmyybe+d6pQEHVYFf4zJlygeMK/dl22cEIpWFBOcRQqEsyd7BPs5zrKIYvlzwEI9 UX7+V6eyWAg6OajcKpEZkAuh/SwNk8k= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 04/12] tools/xenstore: use accounting buffering for node accounting Date: Tue, 1 Nov 2022 17:04:14 +0100 Message-Id: <20221101160422.7212-5-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 Add the node accounting to the accounting information buffering in order to avoid having to undo it in case of failure. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_core.c | 21 ++------------------- tools/xenstore/xenstored_domain.h | 4 ++-- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index d437149622..7bf56b4d38 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -1442,7 +1442,6 @@ static void destroy_node_rm(struct connection *conn, struct node *node) static int destroy_node(struct connection *conn, struct node *node) { destroy_node_rm(conn, node); - domain_nbentry_dec(conn, node->perms.p[0].id); /* * It is not possible to easily revert the changes in a transaction. @@ -1788,27 +1787,11 @@ static int do_set_perms(const void *ctx, struct connection *conn, old_perms = node->perms; domain_nbentry_dec(conn, node->perms.p[0].id); node->perms = perms; - if (domain_nbentry_inc(conn, node->perms.p[0].id)) { - node->perms = old_perms; - /* - * This should never fail because we had a reference on the - * domain before and Xenstored is single-threaded. - */ - domain_nbentry_inc(conn, node->perms.p[0].id); + if (domain_nbentry_inc(conn, node->perms.p[0].id)) return ENOMEM; - } - if (write_node(conn, node, false)) { - int saved_errno = errno; - - domain_nbentry_dec(conn, node->perms.p[0].id); - node->perms = old_perms; - /* No failure possible as above. */ - domain_nbentry_inc(conn, node->perms.p[0].id); - - errno = saved_errno; + if (write_node(conn, node, false)) return errno; - } fire_watches(conn, ctx, name, node, false, &old_perms); send_ack(conn, XS_SET_PERMS); diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index 9959b2f2e4..ead3893fc1 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -20,9 +20,9 @@ #define _XENSTORED_DOMAIN_H enum { + ACC_NODES, ACC_REQ_N, /* Number of elements per request and domain. */ - ACC_NODES = ACC_REQ_N, - ACC_TR_N, /* Number of elements per transaction and domain. */ + ACC_TR_N = ACC_REQ_N, /* Number of elements per transaction and domain. */ ACC_N = ACC_TR_N /* Number of elements per domain. */ }; From patchwork Tue Nov 1 16:04:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027140 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 92F0EC4332F for ; Tue, 1 Nov 2022 16:05:07 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435043.688064 (Exim 4.92) (envelope-from ) id 1optl2-00057x-4a; Tue, 01 Nov 2022 16:04:56 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435043.688064; Tue, 01 Nov 2022 16:04:56 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1optl2-00057l-0B; Tue, 01 Nov 2022 16:04:56 +0000 Received: by outflank-mailman (input) for mailman id 435043; Tue, 01 Nov 2022 16:04:54 +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 1optl0-0003Iv-5z for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:04:54 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id ebd36167-59fe-11ed-91b5-6bf2151ebd3b; Tue, 01 Nov 2022 17:04:53 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 14A7522596; Tue, 1 Nov 2022 16:04:53 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id DBD221346F; Tue, 1 Nov 2022 16:04:52 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id GnhUNKRDYWNTcgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:04:52 +0000 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: ebd36167-59fe-11ed-91b5-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318693; 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=Qf00sJCUn8cU2FKlLsp6pVr2UdbMy6ENU4LwBge1Np0=; b=hdulCi7uTtTnAszmoYhK0f/1OtmncZ4daLLxDHNKt/jg9OBRsVIPXqUdpeB4uvXcDXGIQ3 7a4k+eKsRPEtt6U/H695wIHSIPY5zP8rY1htNucTJr4Ng4Isq/nauUubWzZCTY5SRxLn0A mMcUsVU99orEBOipxZvbaKjPcgZjWY4= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 05/12] tools/xenstore: add current connection to domain_memory_add() parameters Date: Tue, 1 Nov 2022 17:04:15 +0100 Message-Id: <20221101160422.7212-6-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 In order to enable switching memory accounting to the generic array based accounting, add the current connection to the parameters of domain_memory_add(). This requires to add the connection to some other functions, too. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_core.c | 28 ++++++++++++++++------------ tools/xenstore/xenstored_domain.c | 3 ++- tools/xenstore/xenstored_domain.h | 14 +++++++++----- tools/xenstore/xenstored_watch.c | 11 ++++++----- 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 7bf56b4d38..8b8900b77c 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -246,7 +246,8 @@ static void free_buffered_data(struct buffered_data *out, } } - domain_memory_add_nochk(conn->id, -out->hdr.msg.len - sizeof(out->hdr)); + domain_memory_add_nochk(conn, conn->id, + -out->hdr.msg.len - sizeof(out->hdr)); if (out->hdr.msg.type == XS_WATCH_EVENT) { req = out->pend.req; @@ -631,24 +632,25 @@ int do_tdb_write(struct connection *conn, TDB_DATA *key, TDB_DATA *data, * nodes to new owners. */ if (old_acc.memory) - domain_memory_add_nochk(old_domid, + domain_memory_add_nochk(conn, old_domid, -old_acc.memory - key->dsize); - ret = domain_memory_add(new_domid, data->dsize + key->dsize, - no_quota_check); + ret = domain_memory_add(conn, new_domid, + data->dsize + key->dsize, no_quota_check); if (ret) { /* Error path, so no quota check. */ if (old_acc.memory) - domain_memory_add_nochk(old_domid, + domain_memory_add_nochk(conn, old_domid, old_acc.memory + key->dsize); return ret; } /* TDB should set errno, but doesn't even set ecode AFAICT. */ if (tdb_store(tdb_ctx, *key, *data, TDB_REPLACE) != 0) { - domain_memory_add_nochk(new_domid, -data->dsize - key->dsize); + domain_memory_add_nochk(conn, new_domid, + -data->dsize - key->dsize); /* Error path, so no quota check. */ if (old_acc.memory) - domain_memory_add_nochk(old_domid, + domain_memory_add_nochk(conn, old_domid, old_acc.memory + key->dsize); errno = EIO; return errno; @@ -683,7 +685,7 @@ int do_tdb_delete(struct connection *conn, TDB_DATA *key, if (acc->memory) { domid = get_acc_domid(conn, key, acc->domid); - domain_memory_add_nochk(domid, -acc->memory - key->dsize); + domain_memory_add_nochk(conn, domid, -acc->memory - key->dsize); } return 0; @@ -1056,11 +1058,13 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type, if (len <= DEFAULT_BUFFER_SIZE) { bdata->buffer = bdata->default_buffer; /* Don't check quota, path might be used for returning error. */ - domain_memory_add_nochk(conn->id, len + sizeof(bdata->hdr)); + domain_memory_add_nochk(conn, conn->id, + len + sizeof(bdata->hdr)); } else { bdata->buffer = talloc_array(bdata, char, len); if (!bdata->buffer || - domain_memory_add_chk(conn->id, len + sizeof(bdata->hdr))) { + domain_memory_add_chk(conn, conn->id, + len + sizeof(bdata->hdr))) { send_error(conn, ENOMEM); return; } @@ -1126,7 +1130,7 @@ void send_event(struct buffered_data *req, struct connection *conn, } } - if (domain_memory_add_chk(conn->id, len + sizeof(bdata->hdr))) { + if (domain_memory_add_chk(conn, conn->id, len + sizeof(bdata->hdr))) { talloc_free(bdata); return; } @@ -3287,7 +3291,7 @@ static void add_buffered_data(struct buffered_data *bdata, * be smaller. So ignore it. The limit will be applied for any resource * after the state has been fully restored. */ - domain_memory_add_nochk(conn->id, len + sizeof(bdata->hdr)); + domain_memory_add_nochk(conn, conn->id, len + sizeof(bdata->hdr)); } void read_state_buffered_data(const void *ctx, struct connection *conn, diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 7988125f71..1407ff9e36 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -1230,7 +1230,8 @@ static bool domain_chk_quota(struct domain *domain, int mem) return false; } -int domain_memory_add(unsigned int domid, int mem, bool no_quota_check) +int domain_memory_add(struct connection *conn, unsigned int domid, int mem, + bool no_quota_check) { struct domain *domain; diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index ead3893fc1..565b47b17b 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -75,25 +75,29 @@ 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_memory_add(unsigned int domid, int mem, bool no_quota_check); +int domain_memory_add(struct connection *conn, unsigned int domid, int mem, + bool no_quota_check); /* * domain_memory_add_chk(): to be used when memory quota should be checked. * Not to be used when specifying a negative mem value, as lowering the used * memory should always be allowed. */ -static inline int domain_memory_add_chk(unsigned int domid, int mem) +static inline int domain_memory_add_chk(struct connection *conn, + unsigned int domid, int mem) { - return domain_memory_add(domid, mem, false); + return domain_memory_add(conn, domid, mem, false); } + /* * domain_memory_add_nochk(): to be used when memory quota should not be * checked, e.g. when lowering memory usage, or in an error case for undoing * a previous memory adjustment. */ -static inline void domain_memory_add_nochk(unsigned int domid, int mem) +static inline void domain_memory_add_nochk(struct connection *conn, + unsigned int domid, int mem) { - domain_memory_add(domid, mem, true); + domain_memory_add(conn, domid, mem, true); } void domain_watch_inc(struct connection *conn); void domain_watch_dec(struct connection *conn); diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index 8bed967c56..ed742de936 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -199,7 +199,7 @@ static struct watch *add_watch(struct connection *conn, char *path, char *token, watch->token = talloc_strdup(watch, token); if (!watch->node || !watch->token) goto nomem; - if (domain_memory_add(conn->id, strlen(path) + strlen(token), + if (domain_memory_add(conn, conn->id, strlen(path) + strlen(token), no_quota_check)) goto nomem; @@ -274,8 +274,9 @@ int do_unwatch(const void *ctx, struct connection *conn, list_for_each_entry(watch, &conn->watches, list) { if (streq(watch->node, node) && streq(watch->token, vec[1])) { list_del(&watch->list); - domain_memory_add_nochk(conn->id, -strlen(watch->node) - - strlen(watch->token)); + domain_memory_add_nochk(conn, conn->id, + -strlen(watch->node) - + strlen(watch->token)); talloc_free(watch); domain_watch_dec(conn); send_ack(conn, XS_UNWATCH); @@ -291,8 +292,8 @@ void conn_delete_all_watches(struct connection *conn) while ((watch = list_top(&conn->watches, struct watch, list))) { list_del(&watch->list); - domain_memory_add_nochk(conn->id, -strlen(watch->node) - - strlen(watch->token)); + domain_memory_add_nochk(conn, conn->id, -strlen(watch->node) - + strlen(watch->token)); talloc_free(watch); domain_watch_dec(conn); } From patchwork Tue Nov 1 16:04:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027141 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 62E95C433FE for ; Tue, 1 Nov 2022 16:05:10 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435050.688075 (Exim 4.92) (envelope-from ) id 1optl7-0005dG-IK; Tue, 01 Nov 2022 16:05:01 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435050.688075; Tue, 01 Nov 2022 16:05:01 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1optl7-0005d1-EP; Tue, 01 Nov 2022 16:05:01 +0000 Received: by outflank-mailman (input) for mailman id 435050; Tue, 01 Nov 2022 16:05:00 +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 1optl6-0003qE-Hh for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:05:00 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id ef24b16f-59fe-11ed-8fd0-01056ac49cbb; Tue, 01 Nov 2022 17:04:58 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 9FC0C225B2; Tue, 1 Nov 2022 16:04:58 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 744B31346F; Tue, 1 Nov 2022 16:04:58 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id KboXG6pDYWNXcgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:04:58 +0000 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: ef24b16f-59fe-11ed-8fd0-01056ac49cbb DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318698; 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=7vX06iot/jRh0KmEBI3quz+d8jYTOyvXE2YRmnqLSRs=; b=PC0WXAhF8kSh9wd8H8fXBg8r06PyMz/pWBW4ErY1m+NNfOyJUsnTgFf7ToZFvipTBY6/3W BAeF3S2d7gNdx1TlbvJjSEutukEsk6sI4e6GMPb/6/zJ+pn5nh8na+ceGZ294D4LVY6Brq KosNKnN6Ijjt1zzrH9P3xBqRmz8W0cg= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 06/12] tools/xenstore: use accounting data array for per-domain values Date: Tue, 1 Nov 2022 17:04:16 +0100 Message-Id: <20221101160422.7212-7-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 Add the accounting of per-domain usage of Xenstore memory, watches, and outstanding requests to the array based mechanism. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_core.c | 8 +-- tools/xenstore/xenstored_domain.c | 111 +++++++++++------------------- tools/xenstore/xenstored_domain.h | 10 +-- 3 files changed, 52 insertions(+), 77 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 8b8900b77c..7bd83a0eaf 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -255,7 +255,7 @@ static void free_buffered_data(struct buffered_data *out, req->pend.ref.event_cnt--; if (!req->pend.ref.event_cnt && !req->on_out_list) { if (req->on_ref_list) { - domain_outstanding_domid_dec( + domain_outstanding_dec(conn, req->pend.ref.domid); list_del(&req->list); } @@ -271,7 +271,7 @@ static void free_buffered_data(struct buffered_data *out, out->on_ref_list = true; return; } else - domain_outstanding_dec(conn); + domain_outstanding_dec(conn, conn->id); talloc_free(out); } @@ -1081,7 +1081,7 @@ void send_reply(struct connection *conn, enum xsd_sockmsg_type type, /* Queue for later transmission. */ list_add_tail(&bdata->list, &conn->out_list); bdata->on_out_list = true; - domain_outstanding_inc(conn); + domain_outstanding_inc(conn, conn->id); } /* @@ -3285,7 +3285,7 @@ static void add_buffered_data(struct buffered_data *bdata, * request have been delivered. */ if (bdata->hdr.msg.type != XS_WATCH_EVENT) - domain_outstanding_inc(conn); + domain_outstanding_inc(conn, conn->id); /* * We are restoring the state after Live-Update and the new quota may * be smaller. So ignore it. The limit will be applied for any resource diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 1407ff9e36..cb2a78b597 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -72,19 +72,12 @@ struct domain /* Accounting data for this domain. */ unsigned int acc[ACC_N]; - /* Amount of memory allocated for this domain. */ - int memory; + /* Memory quota data for this domain. */ bool soft_quota_reported; bool hard_quota_reported; time_t mem_last_msg; #define MEM_WARN_MINTIME_SEC 10 - /* number of watch for this domain */ - int nbwatch; - - /* Number of outstanding requests. */ - int nboutstanding; - /* write rate limit */ wrl_creditt wrl_credit; /* [ -wrl_config_writecost, +_dburst ] */ struct wrl_timestampt wrl_timestamp; @@ -200,14 +193,15 @@ static bool domain_can_write(struct connection *conn) static bool domain_can_read(struct connection *conn) { - struct xenstore_domain_interface *intf = conn->domain->interface; + struct domain *domain = conn->domain; + struct xenstore_domain_interface *intf = domain->interface; if (domain_is_unprivileged(conn)) { - if (conn->domain->wrl_credit < 0) + if (domain->wrl_credit < 0) return false; - if (conn->domain->nboutstanding >= quota_req_outstanding) + if (domain->acc[ACC_OUTST] >= quota_req_outstanding) return false; - if (conn->domain->memory >= quota_memory_per_domain_hard && + if (domain->acc[ACC_MEM] >= quota_memory_per_domain_hard && quota_memory_per_domain_hard) return false; } @@ -442,10 +436,10 @@ int domain_get_quota(const void *ctx, struct connection *conn, if (!resp) return ENOMEM ent(nodes, d->acc[ACC_NODES]); - ent(watches, d->nbwatch); + ent(watches, d->acc[ACC_WATCH]); ent(transactions, ta); - ent(outstanding, d->nboutstanding); - ent(memory, d->memory); + ent(outstanding, d->acc[ACC_OUTST]); + ent(memory, d->acc[ACC_MEM]); #undef ent @@ -1181,14 +1175,16 @@ unsigned int domain_nbentry(struct connection *conn) ? domain_acc_add(conn, conn->id, ACC_NODES, 0, true) : 0; } -static bool domain_chk_quota(struct domain *domain, int mem) +static bool domain_chk_quota(struct connection *conn, unsigned int mem) { time_t now; + struct domain *domain; - if (!domain || !domid_is_unprivileged(domain->domid) || - (domain->conn && domain->conn->is_ignored)) + if (!conn || !domid_is_unprivileged(conn->id) || + conn->is_ignored) return false; + domain = conn->domain; now = time(NULL); if (mem >= quota_memory_per_domain_hard && @@ -1233,80 +1229,57 @@ static bool domain_chk_quota(struct domain *domain, int mem) int domain_memory_add(struct connection *conn, unsigned int domid, int mem, bool no_quota_check) { - struct domain *domain; + int ret; - domain = find_domain_struct(domid); - if (domain) { - /* - * domain_chk_quota() will print warning and also store whether - * the soft/hard quota has been hit. So check no_quota_check - * *after*. - */ - if (domain_chk_quota(domain, domain->memory + mem) && - !no_quota_check) - return ENOMEM; - domain->memory += mem; - } else { - /* - * The domain the memory is to be accounted for should always - * exist, as accounting is done either for a domain related to - * the current connection, or for the domain owning a node - * (which is always existing, as the owner of the node is - * tested to exist and deleted or replaced by domid 0 if not). - * So not finding the related domain MUST be an error in the - * data base. - */ - errno = ENOENT; - corrupt(NULL, "Accounting called for non-existing domain %u\n", - domid); - return ENOENT; - } + ret = domain_acc_add(conn, domid, ACC_MEM, 0, true); + if (ret < 0) + return -ret; + + /* + * domain_chk_quota() will print warning and also store whether the + * soft/hard quota has been hit. So check no_quota_check *after*. + */ + if (domain_chk_quota(conn, ret + mem) && !no_quota_check) + return ENOMEM; + + /* + * The domain the memory is to be accounted for should always exist, + * as accounting is done either for a domain related to the current + * connection, or for the domain owning a node (which is always + * existing, as the owner of the node is tested to exist and deleted + * or replaced by domid 0 if not). + * So not finding the related domain MUST be an error in the data base. + */ + domain_acc_add(conn, domid, ACC_MEM, mem, true); return 0; } void domain_watch_inc(struct connection *conn) { - if (!conn || !conn->domain) - return; - conn->domain->nbwatch++; + domain_acc_add(conn, conn->id, ACC_WATCH, 1, true); } void domain_watch_dec(struct connection *conn) { - if (!conn || !conn->domain) - return; - if (conn->domain->nbwatch) - conn->domain->nbwatch--; + domain_acc_add(conn, conn->id, ACC_WATCH, -1, true); } int domain_watch(struct connection *conn) { return (domain_is_unprivileged(conn)) - ? conn->domain->nbwatch + ? domain_acc_add(conn, conn->id, ACC_WATCH, 0, true) : 0; } -void domain_outstanding_inc(struct connection *conn) +void domain_outstanding_inc(struct connection *conn, unsigned int domid) { - if (!conn || !conn->domain) - return; - conn->domain->nboutstanding++; + domain_acc_add(conn, domid, ACC_OUTST, 1, true); } -void domain_outstanding_dec(struct connection *conn) +void domain_outstanding_dec(struct connection *conn, unsigned int domid) { - if (!conn || !conn->domain) - return; - conn->domain->nboutstanding--; -} - -void domain_outstanding_domid_dec(unsigned int domid) -{ - struct domain *d = find_domain_by_domid(domid); - - if (d) - d->nboutstanding--; + domain_acc_add(conn, domid, ACC_OUTST, -1, true); } static wrl_creditt wrl_config_writecost = WRL_FACTOR; diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index 565b47b17b..91db3342c4 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -23,7 +23,10 @@ enum { ACC_NODES, ACC_REQ_N, /* Number of elements per request and domain. */ ACC_TR_N = ACC_REQ_N, /* Number of elements per transaction and domain. */ - ACC_N = ACC_TR_N /* Number of elements per domain. */ + ACC_WATCH = ACC_TR_N, + ACC_OUTST, + ACC_MEM, + ACC_N /* Number of elements per domain. */ }; void handle_event(void); @@ -102,9 +105,8 @@ static inline void domain_memory_add_nochk(struct connection *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); -void domain_outstanding_domid_dec(unsigned int domid); +void domain_outstanding_inc(struct connection *conn, unsigned int domid); +void domain_outstanding_dec(struct connection *conn, unsigned int domid); int domain_get_quota(const void *ctx, struct connection *conn, unsigned int domid); int acc_fix_domains(struct list_head *head, bool update); From patchwork Tue Nov 1 16:04:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027142 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C6D9DC433FE for ; Tue, 1 Nov 2022 16:05:17 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435051.688086 (Exim 4.92) (envelope-from ) id 1optlC-0006AS-Sf; Tue, 01 Nov 2022 16:05:06 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435051.688086; Tue, 01 Nov 2022 16:05: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 1optlC-0006AH-OV; Tue, 01 Nov 2022 16:05:06 +0000 Received: by outflank-mailman (input) for mailman id 435051; Tue, 01 Nov 2022 16:05:05 +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 1optlB-0003Iv-3U for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:05:05 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f272fb8f-59fe-11ed-91b5-6bf2151ebd3b; Tue, 01 Nov 2022 17:05:04 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 32067225A4; Tue, 1 Nov 2022 16:05:04 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 09D721346F; Tue, 1 Nov 2022 16:05:04 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id wBs4AbBDYWNscgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:05:04 +0000 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: f272fb8f-59fe-11ed-91b5-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318704; 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=pLiRR0HBtiamzqwHIKj4WOLeWu1RXT2UzX7ss3KrLTA=; b=nuqhTHY6cfBGrDX1oNGxGEioxVSe59cEhTzjpZyRyj647EtN9moepmFnXlUcFvwV3zbSPr 8pLi6DXUvjiycifxvRsy39jxSf0Xs7dOjvL3wAbaHVGUgX9IEdr5jeTpuYXgyWyXvrrmZF 61S8l7QC8vFF5r34cLi0tTppF8/n3oU= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 07/12] tools/xenstore: add accounting trace support Date: Tue, 1 Nov 2022 17:04:17 +0100 Message-Id: <20221101160422.7212-8-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 Add a new trace switch "acc" and the related trace calls. The "acc" switch is off per default. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_core.c | 2 +- tools/xenstore/xenstored_core.h | 1 + tools/xenstore/xenstored_domain.c | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 7bd83a0eaf..be3c2aba77 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -2737,7 +2737,7 @@ static void set_quota(const char *arg, bool soft) /* Sorted by bit values of TRACE_* flags. Flag is (1u << index). */ const char *trace_switches[] = { - "obj", "io", "wrl", + "obj", "io", "wrl", "acc", NULL }; diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index 8223a49354..e17bd4c268 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -294,6 +294,7 @@ extern unsigned int trace_flags; #define TRACE_OBJ 0x00000001 #define TRACE_IO 0x00000002 #define TRACE_WRL 0x00000004 +#define TRACE_ACC 0x00000008 extern const char *trace_switches[]; int set_trace_switch(const char *arg); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index cb2a78b597..2420fbff31 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -546,6 +546,12 @@ static struct domain *find_domain_by_domid(unsigned int domid) return (d && d->introduced) ? d : NULL; } +#define trace_acc(...) \ +do { \ + if (trace_flags & TRACE_ACC) \ + trace("acc: " __VA_ARGS__); \ +} while (0) + int acc_fix_domains(struct list_head *head, bool update) { struct changed_domain *cd; @@ -609,6 +615,8 @@ static int acc_add_changed_dom(const void *ctx, struct list_head *head, return 0; errno = 0; + trace_acc("local change domid %u: what=%u %d add %d\n", domid, what, + cd->acc[what], val); cd->acc[what] += val; return cd->acc[what]; @@ -1111,6 +1119,8 @@ static int domain_acc_add(struct connection *conn, unsigned int domid, return domain_acc_add_chk(d, what, ret, domid); } + trace_acc("global change domid %u: what=%u %u add %d\n", domid, what, + d->acc[what], add); d->acc[what] = domain_acc_add_chk(d, what, add, domid); return d->acc[what]; From patchwork Tue Nov 1 16:04:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027148 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3BF85C43217 for ; Tue, 1 Nov 2022 16:15:22 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435075.688130 (Exim 4.92) (envelope-from ) id 1optuz-0001mY-Oi; Tue, 01 Nov 2022 16:15:13 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435075.688130; Tue, 01 Nov 2022 16:15:13 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1optuz-0001mR-LO; Tue, 01 Nov 2022 16:15:13 +0000 Received: by outflank-mailman (input) for mailman id 435075; Tue, 01 Nov 2022 16:15:12 +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 1optlG-0003qE-OW for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:05:10 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [2001:67c:2178:6::1d]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f5c39eb7-59fe-11ed-8fd0-01056ac49cbb; Tue, 01 Nov 2022 17:05:10 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id BA5F31F8CA; Tue, 1 Nov 2022 16:05:09 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 8DBAA1346F; Tue, 1 Nov 2022 16:05:09 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 2go9IbVDYWN/cgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:05:09 +0000 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: f5c39eb7-59fe-11ed-8fd0-01056ac49cbb DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318709; 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=Ex16tXxYUWTa8wrIuGo+oPYlqG5C+9YpA2AwG1Rpfyo=; b=nAw8jCn3lUB78s8xN/MoFeZL168qrdvi58IqMzzBHtTRXHhYLxtvbatvLdAKqR9tR0BHtE lK1tK/LEfJoB893kvzMcdn1/5jqwfiVaOBv8nbik6SdPv74yvepZQ/FUAZyK6F08DV8e9T ASWkrIEbIbZl2/ULG09qwkASkcwtqRM= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 08/12] tools/xenstore: add TDB access trace support Date: Tue, 1 Nov 2022 17:04:18 +0100 Message-Id: <20221101160422.7212-9-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 Add a new trace switch "tdb" and the related trace calls. The "tdb" switch is off per default. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_core.c | 8 +++++++- tools/xenstore/xenstored_core.h | 6 ++++++ tools/xenstore/xenstored_transaction.c | 7 ++++++- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index be3c2aba77..f07398e2cf 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -589,6 +589,8 @@ static void get_acc_data(TDB_DATA *key, struct node_account_data *acc) if (old_data.dptr == NULL) { acc->memory = 0; } else { + trace_tdb("read %s size %zu\n", key->dptr, + old_data.dsize + key->dsize); hdr = (void *)old_data.dptr; acc->memory = old_data.dsize; acc->domid = hdr->perms[0].id; @@ -655,6 +657,7 @@ int do_tdb_write(struct connection *conn, TDB_DATA *key, TDB_DATA *data, errno = EIO; return errno; } + trace_tdb("store %s size %zu\n", key->dptr, data->dsize + key->dsize); if (acc) { /* Don't use new_domid, as it might be a transaction node. */ @@ -682,6 +685,7 @@ int do_tdb_delete(struct connection *conn, TDB_DATA *key, errno = EIO; return errno; } + trace_tdb("delete %s\n", key->dptr); if (acc->memory) { domid = get_acc_domid(conn, key, acc->domid); @@ -731,6 +735,8 @@ struct node *read_node(struct connection *conn, const void *ctx, goto error; } + trace_tdb("read %s size %zu\n", key.dptr, data.dsize + key.dsize); + node->parent = NULL; talloc_steal(node, data.dptr); @@ -2737,7 +2743,7 @@ static void set_quota(const char *arg, bool soft) /* Sorted by bit values of TRACE_* flags. Flag is (1u << index). */ const char *trace_switches[] = { - "obj", "io", "wrl", "acc", + "obj", "io", "wrl", "acc", "tdb", NULL }; diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index e17bd4c268..d3a17a6ce1 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -295,8 +295,14 @@ extern unsigned int trace_flags; #define TRACE_IO 0x00000002 #define TRACE_WRL 0x00000004 #define TRACE_ACC 0x00000008 +#define TRACE_TDB 0x00000010 extern const char *trace_switches[]; int set_trace_switch(const char *arg); +#define trace_tdb(...) \ +do { \ + if (trace_flags & TRACE_TDB) \ + trace("tdb: " __VA_ARGS__); \ +} while (0) extern TDB_CONTEXT *tdb_ctx; extern int dom0_domid; diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c index 1aa9d3cb3d..19a1175d1b 100644 --- a/tools/xenstore/xenstored_transaction.c +++ b/tools/xenstore/xenstored_transaction.c @@ -366,8 +366,11 @@ static int finalize_transaction(struct connection *conn, if (tdb_error(tdb_ctx) != TDB_ERR_NOEXIST) return EIO; gen = NO_GENERATION; - } else + } else { + trace_tdb("read %s size %zu\n", key.dptr, + key.dsize + data.dsize); gen = hdr->generation; + } talloc_free(data.dptr); if (i->generation != gen) return EAGAIN; @@ -391,6 +394,8 @@ static int finalize_transaction(struct connection *conn, set_tdb_key(i->trans_name, &ta_key); data = tdb_fetch(tdb_ctx, ta_key); if (data.dptr) { + trace_tdb("read %s size %zu\n", ta_key.dptr, + ta_key.dsize + data.dsize); hdr = (void *)data.dptr; hdr->generation = ++generation; *is_corrupt |= do_tdb_write(conn, &key, &data, From patchwork Tue Nov 1 16:04:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027149 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AF0B3C4332F for ; Tue, 1 Nov 2022 16:15:23 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435080.688143 (Exim 4.92) (envelope-from ) id 1optv0-0001wV-Ls; Tue, 01 Nov 2022 16:15:14 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435080.688143; Tue, 01 Nov 2022 16:15:14 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1optv0-0001ue-D9; Tue, 01 Nov 2022 16:15:14 +0000 Received: by outflank-mailman (input) for mailman id 435080; Tue, 01 Nov 2022 16:15:13 +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 1optlM-0003Iv-CR for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:05:16 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f918903b-59fe-11ed-91b5-6bf2151ebd3b; Tue, 01 Nov 2022 17:05:15 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 5201822350; Tue, 1 Nov 2022 16:05:15 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 242691346F; Tue, 1 Nov 2022 16:05:15 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id cuN+B7tDYWOJcgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:05:15 +0000 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: f918903b-59fe-11ed-91b5-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318715; 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=zlr1bEVW5zM00uivxYgahU2VVqHYofX1SXVVdA6eJyo=; b=PonLWqrEzh/61QWbp7+LdC4rt+JYU/gOL/wCJ+WSpOQQ7MS0UwzaLyZWEl8QS2Cec1Lnli s8ZJSKP1Mwp2isKS03VYfcaOXqqLXskRXqLe8hqecz0MQyKElcCmssD6pcvtkmBkPRUww2 J8vTE8YLaOEmvmuTqB/AEpSTxNpPRuk= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 09/12] tools/xenstore: switch transaction accounting to generic accounting Date: Tue, 1 Nov 2022 17:04:19 +0100 Message-Id: <20221101160422.7212-10-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 As transaction accounting is active for unprivileged domains only, it can easily be added to the generic per-domain accounting. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_core.c | 3 +-- tools/xenstore/xenstored_core.h | 1 - tools/xenstore/xenstored_domain.c | 21 ++++++++++++++++++--- tools/xenstore/xenstored_domain.h | 4 ++++ tools/xenstore/xenstored_transaction.c | 12 +++++------- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index f07398e2cf..f5933a900a 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -2074,7 +2074,7 @@ static void consider_message(struct connection *conn) * stalled. This will ignore new requests until Live-Update happened * or it was aborted. */ - if (lu_is_pending() && conn->transaction_started == 0 && + if (lu_is_pending() && conn->ta_start_time == 0 && conn->in->hdr.msg.type == XS_TRANSACTION_START) { trace("Delaying transaction start for connection %p req_id %u\n", conn, conn->in->hdr.msg.req_id); @@ -2181,7 +2181,6 @@ struct connection *new_connection(const struct interface_funcs *funcs) new->funcs = funcs; new->is_ignored = false; new->is_stalled = false; - new->transaction_started = 0; INIT_LIST_HEAD(&new->out_list); INIT_LIST_HEAD(&new->acc_list); INIT_LIST_HEAD(&new->ref_list); diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index d3a17a6ce1..f51b8d1839 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -151,7 +151,6 @@ struct connection /* List of in-progress transactions. */ struct list_head transaction_list; uint32_t next_transaction_id; - unsigned int transaction_started; time_t ta_start_time; /* List of delayed requests. */ diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 2420fbff31..274ea72741 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -421,12 +421,10 @@ int domain_get_quota(const void *ctx, struct connection *conn, { struct domain *d = find_domain_struct(domid); char *resp; - int ta; if (!d) return ENOENT; - ta = d->conn ? d->conn->transaction_started : 0; resp = talloc_asprintf(ctx, "Domain %u:\n", domid); if (!resp) return ENOMEM; @@ -437,7 +435,7 @@ int domain_get_quota(const void *ctx, struct connection *conn, ent(nodes, d->acc[ACC_NODES]); ent(watches, d->acc[ACC_WATCH]); - ent(transactions, ta); + ent(transactions, d->acc[ACC_TRANS]); ent(outstanding, d->acc[ACC_OUTST]); ent(memory, d->acc[ACC_MEM]); @@ -1292,6 +1290,23 @@ void domain_outstanding_dec(struct connection *conn, unsigned int domid) domain_acc_add(conn, domid, ACC_OUTST, -1, true); } +void domain_transaction_inc(struct connection *conn) +{ + domain_acc_add(conn, conn->id, ACC_TRANS, 1, true); +} + +void domain_transaction_dec(struct connection *conn) +{ + domain_acc_add(conn, conn->id, ACC_TRANS, -1, true); +} + +unsigned int domain_transaction_get(struct connection *conn) +{ + return (domain_is_unprivileged(conn)) + ? domain_acc_add(conn, conn->id, ACC_TRANS, 0, true) + : 0; +} + static wrl_creditt wrl_config_writecost = WRL_FACTOR; static wrl_creditt wrl_config_rate = WRL_RATE * WRL_FACTOR; static wrl_creditt wrl_config_dburst = WRL_DBURST * WRL_FACTOR; diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index 91db3342c4..5005850dd3 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -26,6 +26,7 @@ enum { ACC_WATCH = ACC_TR_N, ACC_OUTST, ACC_MEM, + ACC_TRANS, ACC_N /* Number of elements per domain. */ }; @@ -107,6 +108,9 @@ void domain_watch_dec(struct connection *conn); int domain_watch(struct connection *conn); void domain_outstanding_inc(struct connection *conn, unsigned int domid); 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); int acc_fix_domains(struct list_head *head, bool update); diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c index 19a1175d1b..ce6a12b576 100644 --- a/tools/xenstore/xenstored_transaction.c +++ b/tools/xenstore/xenstored_transaction.c @@ -471,8 +471,7 @@ int do_transaction_start(const void *ctx, struct connection *conn, if (conn->transaction) return EBUSY; - if (domain_is_unprivileged(conn) && - conn->transaction_started > quota_max_transaction) + if (domain_transaction_get(conn) > quota_max_transaction) return ENOSPC; /* Attach transaction to ctx for autofree until it's complete */ @@ -497,9 +496,9 @@ int do_transaction_start(const void *ctx, struct connection *conn, list_add_tail(&trans->list, &conn->transaction_list); talloc_steal(conn, trans); talloc_set_destructor(trans, destroy_transaction); - if (!conn->transaction_started) + if (!conn->ta_start_time) conn->ta_start_time = time(NULL); - conn->transaction_started++; + domain_transaction_inc(conn); wrl_ntransactions++; snprintf(id_str, sizeof(id_str), "%u", trans->id); @@ -524,8 +523,8 @@ int do_transaction_end(const void *ctx, struct connection *conn, conn->transaction = NULL; list_del(&trans->list); - conn->transaction_started--; - if (!conn->transaction_started) + domain_transaction_dec(conn); + if (list_empty(&conn->transaction_list)) conn->ta_start_time = 0; /* Attach transaction to ctx for auto-cleanup */ @@ -576,7 +575,6 @@ void conn_delete_all_transactions(struct connection *conn) assert(conn->transaction == NULL); - conn->transaction_started = 0; conn->ta_start_time = 0; } From patchwork Tue Nov 1 16:04:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027146 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 362B9C4332F for ; Tue, 1 Nov 2022 16:15:20 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435071.688118 (Exim 4.92) (envelope-from ) id 1optuy-0001Rh-9n; Tue, 01 Nov 2022 16:15:12 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435071.688118; Tue, 01 Nov 2022 16:15:12 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1optuy-0001RW-5v; Tue, 01 Nov 2022 16:15:12 +0000 Received: by outflank-mailman (input) for mailman id 435071; Tue, 01 Nov 2022 16:15:11 +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 1optlS-0003qE-Ba for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:05:22 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id fc7b1ad5-59fe-11ed-8fd0-01056ac49cbb; Tue, 01 Nov 2022 17:05:21 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 05F921F8CA; Tue, 1 Nov 2022 16:05:21 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id B58871346F; Tue, 1 Nov 2022 16:05:20 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 73wIK8BDYWOYcgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:05:20 +0000 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: fc7b1ad5-59fe-11ed-8fd0-01056ac49cbb DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318721; 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=2q+bzKJwqxVNaXxCMgH7XK7Vg2XGJN/yW7eJYqIUWtA=; b=kY9fUxff56SHHUTCsUXg+fjZsQukQrKVZpMqHwqzdq8HqER9E7HL3At5QCPyST88IXUfjo O33Af+MmYBz/w+Tkmqq25S/0X7Fb7NtA7tMs9TFuQ0dRBY9RsOjDd6sS8VsCrHaiP+FWsH /PMee7RLt/5ql+Kfq1I7Ydh19dVxTl4= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Andrew Cooper , George Dunlap , Jan Beulich , Julien Grall , Stefano Stabellini , Wei Liu , Anthony PERARD Subject: [PATCH 10/12] tools/xenstore: remember global and per domain max accounting values Date: Tue, 1 Nov 2022 17:04:20 +0100 Message-Id: <20221101160422.7212-11-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 Add saving the maximum values of the different accounting data seen per domain and (for unprivileged domains) globally, and print those values via the xenstore-control quota command. Add a sub-command for resetting the global maximum values seen. This should help for a decision how to set the related quotas. Signed-off-by: Juergen Gross --- docs/misc/xenstore.txt | 5 +- tools/xenstore/xenstored_control.c | 22 ++++++- tools/xenstore/xenstored_domain.c | 102 +++++++++++++++++++++++------ tools/xenstore/xenstored_domain.h | 2 + 4 files changed, 109 insertions(+), 22 deletions(-) diff --git a/docs/misc/xenstore.txt b/docs/misc/xenstore.txt index 9db0385120..da47d7bb16 100644 --- a/docs/misc/xenstore.txt +++ b/docs/misc/xenstore.txt @@ -415,7 +415,7 @@ CONTROL |[|] print| print to syslog (xenstore runs as daemon) or to console (xenstore runs as stubdom) - quota|[set |] + quota|[set ||max [-r]] without parameters: print the current quota settings with "set ": set the quota to new value (The admin should make sure all the domain usage is @@ -424,6 +424,9 @@ CONTROL |[|] violating the new quota setting isn't increased further) with "": print quota related accounting data for the domain + with "max [-r]": show global per-domain maximum values of all + unprivileged domains, optionally reset the values by adding + "-r" quota-soft|[set ] like the "quota" command, but for soft-quota. trace|[+|-] diff --git a/tools/xenstore/xenstored_control.c b/tools/xenstore/xenstored_control.c index 0a985a1faa..23098917ec 100644 --- a/tools/xenstore/xenstored_control.c +++ b/tools/xenstore/xenstored_control.c @@ -306,6 +306,22 @@ static int quota_get(const void *ctx, struct connection *conn, return domain_get_quota(ctx, conn, atoi(vec[0])); } +static int quota_max(const void *ctx, struct connection *conn, + char **vec, int num) +{ + if (num > 1) + return EINVAL; + + if (num == 1) { + if (!strcmp(vec[0], "-r")) + domain_reset_global_acc(); + else + return EINVAL; + } + + return domain_max_global_acc(ctx, conn); +} + static int do_control_quota(const void *ctx, struct connection *conn, char **vec, int num) { @@ -315,6 +331,9 @@ static int do_control_quota(const void *ctx, struct connection *conn, if (!strcmp(vec[0], "set")) return quota_set(ctx, conn, vec + 1, num - 1, hard_quotas); + if (!strcmp(vec[0], "max")) + return quota_max(ctx, conn, vec + 1, num - 1); + return quota_get(ctx, conn, vec, num); } @@ -978,7 +997,8 @@ static struct cmd_s cmds[] = { { "memreport", do_control_memreport, "[]" }, #endif { "print", do_control_print, "" }, - { "quota", do_control_quota, "[set |]" }, + { "quota", do_control_quota, + "[set ||max [-r]]" }, { "quota-soft", do_control_quota_s, "[set ]" }, { "help", do_control_help, "" }, }; diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 274ea72741..6464362299 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -43,6 +43,8 @@ static evtchn_port_t virq_port; xenevtchn_handle *xce_handle = NULL; +static unsigned int acc_global_max[ACC_N]; + struct domain { /* The id of this domain */ @@ -70,7 +72,10 @@ struct domain bool introduced; /* Accounting data for this domain. */ - unsigned int acc[ACC_N]; + struct acc { + unsigned int val; + unsigned int max; + } acc[ACC_N]; /* Memory quota data for this domain. */ bool soft_quota_reported; @@ -199,9 +204,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] >= quota_req_outstanding) + if (domain->acc[ACC_OUTST].val >= quota_req_outstanding) return false; - if (domain->acc[ACC_MEM] >= quota_memory_per_domain_hard && + if (domain->acc[ACC_MEM].val >= quota_memory_per_domain_hard && quota_memory_per_domain_hard) return false; } @@ -264,7 +269,7 @@ static int domain_tree_remove_sub(const void *ctx, struct connection *conn, ret = WALK_TREE_SKIP_CHILDREN; } - return domain->acc[ACC_NODES] ? ret : WALK_TREE_SUCCESS_STOP; + return domain->acc[ACC_NODES].val ? ret : WALK_TREE_SUCCESS_STOP; } static void domain_tree_remove(struct domain *domain) @@ -272,7 +277,7 @@ static void domain_tree_remove(struct domain *domain) int ret; struct walk_funcs walkfuncs = { .enter = domain_tree_remove_sub }; - if (domain->acc[ACC_NODES]) { + if (domain->acc[ACC_NODES].val) { ret = walk_node_tree(domain, NULL, "/", &walkfuncs, domain); if (ret == WALK_TREE_ERROR_STOP) syslog(LOG_ERR, @@ -430,14 +435,41 @@ int domain_get_quota(const void *ctx, struct connection *conn, return ENOMEM; #define ent(t, e) \ - resp = talloc_asprintf_append(resp, "%-16s: %8d\n", #t, e); \ + resp = talloc_asprintf_append(resp, "%-16s: %8u (max: %8u\n", #t, \ + d->acc[e].val, d->acc[e].max); \ + if (!resp) return ENOMEM + + ent(nodes, ACC_NODES); + ent(watches, ACC_WATCH); + ent(transactions, ACC_TRANS); + ent(outstanding, ACC_OUTST); + ent(memory, ACC_MEM); + +#undef ent + + send_reply(conn, XS_CONTROL, resp, strlen(resp) + 1); + + return 0; +} + +int domain_max_global_acc(const void *ctx, struct connection *conn) +{ + char *resp; + + resp = talloc_asprintf(ctx, "Max. seen accounting values:\n"); + if (!resp) + return ENOMEM; + +#define ent(t, e) \ + resp = talloc_asprintf_append(resp, "%-16s: %8u\n", #t, \ + acc_global_max[e]); \ if (!resp) return ENOMEM - ent(nodes, d->acc[ACC_NODES]); - ent(watches, d->acc[ACC_WATCH]); - ent(transactions, d->acc[ACC_TRANS]); - ent(outstanding, d->acc[ACC_OUTST]); - ent(memory, d->acc[ACC_MEM]); + ent(nodes, ACC_NODES); + ent(watches, ACC_WATCH); + ent(transactions, ACC_TRANS); + ent(outstanding, ACC_OUTST); + ent(memory, ACC_MEM); #undef ent @@ -1055,14 +1087,22 @@ int domain_adjust_node_perms(struct node *node) static int domain_acc_add_chk(struct domain *d, unsigned int what, int add, unsigned int domid) { - if ((add < 0 && -add > d->acc[what]) || - (d->acc[what] + add) > INT_MAX) { + unsigned int val; + + if ((add < 0 && -add > d->acc[what].val) || + (d->acc[what].val + add) > INT_MAX) { syslog(LOG_ERR, "Accounting error: domain %u type %u val %u\n", - domid, what, d->acc[what] + add); + domid, what, d->acc[what].val + add); return (add < 0) ? 0 : INT_MAX; } - return d->acc[what] + add; + val = d->acc[what].val + add; + if (val > d->acc[what].max) + d->acc[what].max = val; + if (val > acc_global_max[what] && domid_is_unprivileged(domid)) + acc_global_max[what] = val; + + return val; } static int domain_acc_add(struct connection *conn, unsigned int domid, @@ -1118,10 +1158,10 @@ static int domain_acc_add(struct connection *conn, unsigned int domid, } trace_acc("global change domid %u: what=%u %u add %d\n", domid, what, - d->acc[what], add); - d->acc[what] = domain_acc_add_chk(d, what, add, domid); + d->acc[what].val, add); + d->acc[what].val = domain_acc_add_chk(d, what, add, domid); - return d->acc[what]; + return d->acc[what].val; } void acc_drop(struct connection *conn) @@ -1154,6 +1194,28 @@ void acc_commit(struct connection *conn) conn->in = in; } +static int domain_reset_global_acc_sub(void *k, void *v, void *arg) +{ + struct domain *d = v; + unsigned int i; + + for (i = 0; i < ACC_N; i++) + d->acc[i].max = d->acc[i].val; + + return 0; +} + +void domain_reset_global_acc(void) +{ + unsigned int i; + + for (i = 0; i < ACC_N; i++) + acc_global_max[i] = 0; + + /* Set current max values seen. */ + hashtable_iterate(domhash, domain_reset_global_acc_sub, NULL); +} + int domain_nbentry_inc(struct connection *conn, unsigned int domid) { return (domain_acc_add(conn, domid, ACC_NODES, 1, false) < 0) @@ -1654,7 +1716,7 @@ static int domain_check_acc_init_sub(void *k, void *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 = -d->acc[ACC_NODES]; + dom->nodes = -d->acc[ACC_NODES].val; if (!hashtable_insert(domains, &dom->domid, dom)) { talloc_free(dom); @@ -1709,7 +1771,7 @@ static int domain_check_acc_sub(void *k, void *v, void *arg) if (!d) return 0; - d->acc[ACC_NODES] += dom->nodes; + d->acc[ACC_NODES].val += dom->nodes; return 0; } diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index 5005850dd3..b5f0b9a591 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -116,6 +116,8 @@ int domain_get_quota(const void *ctx, struct connection *conn, int acc_fix_domains(struct list_head *head, bool update); void acc_drop(struct connection *conn); void acc_commit(struct connection *conn); +int domain_max_global_acc(const void *ctx, struct connection *conn); +void domain_reset_global_acc(void); /* Write rate limiting */ From patchwork Tue Nov 1 16:04:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027151 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1DE2FC433FE for ; Tue, 1 Nov 2022 16:15:29 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435086.688169 (Exim 4.92) (envelope-from ) id 1optv6-00030w-FG; Tue, 01 Nov 2022 16:15:20 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435086.688169; Tue, 01 Nov 2022 16:15:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1optv6-000309-8K; Tue, 01 Nov 2022 16:15:20 +0000 Received: by outflank-mailman (input) for mailman id 435086; Tue, 01 Nov 2022 16:15: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 1optlX-0003qE-QV for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:05:27 +0000 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id ffceadcf-59fe-11ed-8fd0-01056ac49cbb; Tue, 01 Nov 2022 17:05:26 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 94E931F8CA; Tue, 1 Nov 2022 16:05:26 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 6AB141346F; Tue, 1 Nov 2022 16:05:26 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id GmSiGMZDYWOlcgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:05:26 +0000 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: ffceadcf-59fe-11ed-8fd0-01056ac49cbb DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318726; 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=cBkIMfoGbobN/afNSIa7avOizbXZzmTA3t+O9pWgXaQ=; b=kVOwyFJo3DnA+kTKMB5lSEkk6JlHtyREiXQqjwTuXmAoM+NmioSa5IpPJWNdzigKshqSNa 83hAf7HwzIrLjJjIdEUM9Iwp/QdIgj5LccahQ/cioWnP0VJVa4w6vBaVcPr+zjTZhSInnz qfiwgba3DMNIokcjJM/jNt6N2AcqQL0= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 11/12] tools/xenstore: use generic accounting for remaining quotas Date: Tue, 1 Nov 2022 17:04:21 +0100 Message-Id: <20221101160422.7212-12-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 The maxrequests, node size, number of node permissions, and path length quota are a little bit special, as they are either active in transactions only (maxrequests), or they are just per item instead of count values. Nevertheless being able to know the maximum number of those quota related values per domain would be beneficial, so add them to the generic accounting. The per domain value will never show current numbers other than zero, but the maximum number seen can be gathered the same way as the number of nodes during a transaction. To be able to use the const qualifier for a new function switch domain_is_unprivileged() to take a const pointer, too. Signed-off-by: Juergen Gross --- tools/xenstore/xenstored_core.c | 14 +++++------ tools/xenstore/xenstored_core.h | 2 +- tools/xenstore/xenstored_domain.c | 34 +++++++++++++++++++++----- tools/xenstore/xenstored_domain.h | 6 +++++ tools/xenstore/xenstored_transaction.c | 4 +-- tools/xenstore/xenstored_watch.c | 2 +- 6 files changed, 45 insertions(+), 17 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index f5933a900a..af16b18692 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -799,8 +799,8 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node, + node->perms.num * sizeof(node->perms.p[0]) + node->datalen + node->childlen; - if (!no_quota_check && domain_is_unprivileged(conn) && - data.dsize >= quota_max_entry_size) { + if (domain_max_chk(conn, ACC_NODESZ, data.dsize, quota_max_entry_size) + && !no_quota_check) { errno = ENOSPC; return errno; } @@ -956,7 +956,7 @@ static struct node *get_node(struct connection *conn, { struct node *node; - if (!name || !is_valid_nodename(name)) { + if (!name || !is_valid_nodename(conn, name)) { errno = EINVAL; return NULL; } @@ -1172,7 +1172,7 @@ static bool valid_chars(const char *node) "0123456789-/_@") == strlen(node)); } -bool is_valid_nodename(const char *node) +bool is_valid_nodename(const struct connection *conn, const char *node) { int local_off = 0; unsigned int domid; @@ -1192,7 +1192,8 @@ bool is_valid_nodename(const char *node) if (sscanf(node, "/local/domain/%5u/%n", &domid, &local_off) != 1) local_off = 0; - if (strlen(node) > local_off + quota_max_path_len) + if (domain_max_chk(conn, ACC_PATHLEN, strlen(node) - local_off, + quota_max_path_len)) return false; return valid_chars(node); @@ -1766,8 +1767,7 @@ static int do_set_perms(const void *ctx, struct connection *conn, return EINVAL; perms.num--; - if (domain_is_unprivileged(conn) && - perms.num > quota_nb_perms_per_node) + if (domain_max_chk(conn, ACC_NPERM, perms.num, quota_nb_perms_per_node)) return ENOSPC; permstr = in->buffer + strlen(in->buffer) + 1; diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index f51b8d1839..752c69d80f 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -252,7 +252,7 @@ void check_store(void); void corrupt(struct connection *conn, const char *fmt, ...); /* Is this a valid node name? */ -bool is_valid_nodename(const char *node); +bool is_valid_nodename(const struct connection *conn, const char *node); /* Get name of parent node. */ char *get_parent(const void *ctx, const char *node); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 6464362299..2b4a551df5 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -435,7 +435,7 @@ int domain_get_quota(const void *ctx, struct connection *conn, return ENOMEM; #define ent(t, e) \ - resp = talloc_asprintf_append(resp, "%-16s: %8u (max: %8u\n", #t, \ + resp = talloc_asprintf_append(resp, "%-17s: %8u (max: %8u\n", #t, \ d->acc[e].val, d->acc[e].max); \ if (!resp) return ENOMEM @@ -444,6 +444,7 @@ int domain_get_quota(const void *ctx, struct connection *conn, ent(transactions, ACC_TRANS); ent(outstanding, ACC_OUTST); ent(memory, ACC_MEM); + ent(transaction-nodes, ACC_TRANSNODES); #undef ent @@ -461,7 +462,7 @@ int domain_max_global_acc(const void *ctx, struct connection *conn) return ENOMEM; #define ent(t, e) \ - resp = talloc_asprintf_append(resp, "%-16s: %8u\n", #t, \ + resp = talloc_asprintf_append(resp, "%-17s: %8u\n", #t, \ acc_global_max[e]); \ if (!resp) return ENOMEM @@ -470,6 +471,7 @@ int domain_max_global_acc(const void *ctx, struct connection *conn) ent(transactions, ACC_TRANS); ent(outstanding, ACC_OUTST); ent(memory, ACC_MEM); + ent(transaction-nodes, ACC_TRANSNODES); #undef ent @@ -1084,6 +1086,15 @@ int domain_adjust_node_perms(struct node *node) return 0; } +static void domain_acc_chk_max(struct domain *d, unsigned int what, + unsigned int val, unsigned int domid) +{ + if (val > d->acc[what].max) + d->acc[what].max = val; + if (val > acc_global_max[what] && domid_is_unprivileged(domid)) + acc_global_max[what] = val; +} + static int domain_acc_add_chk(struct domain *d, unsigned int what, int add, unsigned int domid) { @@ -1097,10 +1108,7 @@ static int domain_acc_add_chk(struct domain *d, unsigned int what, int add, } val = d->acc[what].val + add; - if (val > d->acc[what].max) - d->acc[what].max = val; - if (val > acc_global_max[what] && domid_is_unprivileged(domid)) - acc_global_max[what] = val; + domain_acc_chk_max(d, what, val, domid); return val; } @@ -1216,6 +1224,20 @@ void domain_reset_global_acc(void) hashtable_iterate(domhash, domain_reset_global_acc_sub, NULL); } +bool domain_max_chk(const struct connection *conn, unsigned int what, + unsigned int val, unsigned int quota) +{ + if (!conn || !conn->domain) + return false; + + if (domain_is_unprivileged(conn) && val > quota) + return true; + + domain_acc_chk_max(conn->domain, what, val, conn->id); + + return false; +} + int domain_nbentry_inc(struct connection *conn, unsigned int domid) { return (domain_acc_add(conn, domid, ACC_NODES, 1, false) < 0) diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index b5f0b9a591..2bf9b0d87b 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -27,6 +27,10 @@ enum { ACC_OUTST, ACC_MEM, ACC_TRANS, + ACC_TRANSNODES, + ACC_NPERM, + ACC_PATHLEN, + ACC_NODESZ, ACC_N /* Number of elements per domain. */ }; @@ -118,6 +122,8 @@ void acc_drop(struct connection *conn); void acc_commit(struct connection *conn); int domain_max_global_acc(const void *ctx, struct connection *conn); void domain_reset_global_acc(void); +bool domain_max_chk(const struct connection *conn, unsigned int what, + unsigned int val, unsigned int quota); /* Write rate limiting */ diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c index ce6a12b576..7967770ca2 100644 --- a/tools/xenstore/xenstored_transaction.c +++ b/tools/xenstore/xenstored_transaction.c @@ -244,8 +244,8 @@ int access_node(struct connection *conn, struct node *node, i = find_accessed_node(trans, node->name); if (!i) { - if (trans->nodes >= quota_trans_nodes && - domain_is_unprivileged(conn)) { + if (domain_max_chk(conn, ACC_TRANSNODES, trans->nodes + 1, + quota_trans_nodes)) { ret = ENOSPC; goto err; } diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index ed742de936..4deef21c4c 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -176,7 +176,7 @@ static int check_watch_path(struct connection *conn, const void *ctx, *path = canonicalize(conn, ctx, *path); if (!*path) return errno; - if (!is_valid_nodename(*path)) + if (!is_valid_nodename(conn, *path)) goto inval; } From patchwork Tue Nov 1 16:04:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 13027152 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 57350C43219 for ; Tue, 1 Nov 2022 16:15:30 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.435087.688174 (Exim 4.92) (envelope-from ) id 1optv6-00038n-V9; Tue, 01 Nov 2022 16:15:20 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 435087.688174; Tue, 01 Nov 2022 16:15:20 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1optv6-00037A-NQ; Tue, 01 Nov 2022 16:15:20 +0000 Received: by outflank-mailman (input) for mailman id 435087; Tue, 01 Nov 2022 16:15: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 1optld-0003qE-V6 for xen-devel@lists.xenproject.org; Tue, 01 Nov 2022 16:05:34 +0000 Received: from smtp-out1.suse.de (smtp-out1.suse.de [195.135.220.28]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 0326622c-59ff-11ed-8fd0-01056ac49cbb; Tue, 01 Nov 2022 17:05:32 +0100 (CET) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out1.suse.de (Postfix) with ESMTPS id 344CD22855; Tue, 1 Nov 2022 16:05:32 +0000 (UTC) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 025091346F; Tue, 1 Nov 2022 16:05:31 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id kIjAOstDYWOtcgAAMHmgww (envelope-from ); Tue, 01 Nov 2022 16:05:31 +0000 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: 0326622c-59ff-11ed-8fd0-01056ac49cbb DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1667318732; 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=0ANLKSke6vhgVX7TFChLAMcfhP/HS68oLDqQfBRqxvs=; b=rfXvg3NnnZu9ba/ny/OPhhE/cKOHWynnq6Z0JAJNPgUm9MPiitfffik1p/prIvGWpnoc01 HMsr3+BuHawMxILbTEuO/FFs7f3gLh/3pLy9nSqsRE5Rg0g+oZ0jBE0smCW1YKxWTeTMfk R35x2KZ/vfiWPAx0pvmTniJHHEX6hUA= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH 12/12] tools/xenstore: switch quota management to be table based Date: Tue, 1 Nov 2022 17:04:22 +0100 Message-Id: <20221101160422.7212-13-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20221101160422.7212-1-jgross@suse.com> References: <20221101160422.7212-1-jgross@suse.com> MIME-Version: 1.0 Instead of having individual quota variables switch to a table based approach like the generic accounting. Include all the related data in the same table and add accessor functions. This enables to use the command line --quota parameter for setting all possible quota values, keeping the previous parameters for compatibility. Signed-off-by: Juergen Gross --- V2: - new patch One further remark: it would be rather easy to add soft-quota for all the other quotas (similar to the memory one). This could be used as an early warning for the need to raise global quota. --- tools/xenstore/xenstored_control.c | 43 ++------ tools/xenstore/xenstored_core.c | 85 ++++++++-------- tools/xenstore/xenstored_core.h | 10 -- tools/xenstore/xenstored_domain.c | 130 +++++++++++++++++-------- tools/xenstore/xenstored_domain.h | 12 ++- tools/xenstore/xenstored_transaction.c | 5 +- tools/xenstore/xenstored_watch.c | 2 +- 7 files changed, 154 insertions(+), 133 deletions(-) diff --git a/tools/xenstore/xenstored_control.c b/tools/xenstore/xenstored_control.c index 23098917ec..bfaba0a854 100644 --- a/tools/xenstore/xenstored_control.c +++ b/tools/xenstore/xenstored_control.c @@ -221,35 +221,6 @@ static int do_control_trace(const void *ctx, struct connection *conn, return 0; } -struct quota { - const char *name; - int *quota; - const char *descr; -}; - -static const struct quota hard_quotas[] = { - { "nodes", "a_nb_entry_per_domain, "Nodes per domain" }, - { "watches", "a_nb_watch_per_domain, "Watches per domain" }, - { "transactions", "a_max_transaction, "Transactions per domain" }, - { "outstanding", "a_req_outstanding, - "Outstanding requests per domain" }, - { "transaction-nodes", "a_trans_nodes, - "Max. number of accessed nodes per transaction" }, - { "memory", "a_memory_per_domain_hard, - "Total Xenstore memory per domain (error level)" }, - { "node-size", "a_max_entry_size, "Max. size of a node" }, - { "path-max", "a_max_path_len, "Max. length of a node path" }, - { "permissions", "a_nb_perms_per_node, - "Max. number of permissions per node" }, - { NULL, NULL, NULL } -}; - -static const struct quota soft_quotas[] = { - { "memory", "a_memory_per_domain_soft, - "Total Xenstore memory per domain (warning level)" }, - { NULL, NULL, NULL } -}; - static int quota_show_current(const void *ctx, struct connection *conn, const struct quota *quotas) { @@ -260,9 +231,11 @@ static int quota_show_current(const void *ctx, struct connection *conn, if (!resp) return ENOMEM; - for (i = 0; quotas[i].quota; i++) { + for (i = 0; i < ACC_N; i++) { + if (!quotas[i].name) + continue; resp = talloc_asprintf_append(resp, "%-17s: %8d %s\n", - quotas[i].name, *quotas[i].quota, + quotas[i].name, quotas[i].val, quotas[i].descr); if (!resp) return ENOMEM; @@ -274,7 +247,7 @@ static int quota_show_current(const void *ctx, struct connection *conn, } static int quota_set(const void *ctx, struct connection *conn, - char **vec, int num, const struct quota *quotas) + char **vec, int num, struct quota *quotas) { unsigned int i; int val; @@ -286,9 +259,9 @@ static int quota_set(const void *ctx, struct connection *conn, if (val < 1) return EINVAL; - for (i = 0; quotas[i].quota; i++) { - if (!strcmp(vec[0], quotas[i].name)) { - *quotas[i].quota = val; + for (i = 0; i < ACC_N; i++) { + if (quotas[i].name && !strcmp(vec[0], quotas[i].name)) { + quotas[i].val = val; send_ack(conn, XS_CONTROL); return 0; } diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index af16b18692..ae1ea29b80 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -89,17 +89,6 @@ unsigned int trace_flags = TRACE_OBJ | TRACE_IO; static const char *sockmsg_string(enum xsd_sockmsg_type type); -int quota_nb_entry_per_domain = 1000; -int quota_nb_watch_per_domain = 128; -int quota_max_entry_size = 2048; /* 2K */ -int quota_max_transaction = 10; -int quota_nb_perms_per_node = 5; -int quota_trans_nodes = 1024; -int quota_max_path_len = XENSTORE_REL_PATH_MAX; -int quota_req_outstanding = 20; -int quota_memory_per_domain_soft = 2 * 1024 * 1024; /* 2 MB */ -int quota_memory_per_domain_hard = 2 * 1024 * 1024 + 512 * 1024; /* 2.5 MB */ - unsigned int timeout_watch_event_msec = 20000; void trace(const char *fmt, ...) @@ -799,7 +788,7 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node, + node->perms.num * sizeof(node->perms.p[0]) + node->datalen + node->childlen; - if (domain_max_chk(conn, ACC_NODESZ, data.dsize, quota_max_entry_size) + if (domain_max_chk(conn, ACC_NODESZ, data.dsize) && !no_quota_check) { errno = ENOSPC; return errno; @@ -1192,8 +1181,7 @@ bool is_valid_nodename(const struct connection *conn, const char *node) if (sscanf(node, "/local/domain/%5u/%n", &domid, &local_off) != 1) local_off = 0; - if (domain_max_chk(conn, ACC_PATHLEN, strlen(node) - local_off, - quota_max_path_len)) + if (domain_max_chk(conn, ACC_PATHLEN, strlen(node) - local_off)) return false; return valid_chars(node); @@ -1491,7 +1479,7 @@ static struct node *create_node(struct connection *conn, const void *ctx, for (i = node; i; i = i->parent) { /* i->parent is set for each new node, so check quota. */ if (i->parent && - domain_nbentry(conn) >= quota_nb_entry_per_domain) { + domain_nbentry(conn) >= hard_quotas[ACC_NODES].val) { ret = ENOSPC; goto err; } @@ -1767,7 +1755,7 @@ static int do_set_perms(const void *ctx, struct connection *conn, return EINVAL; perms.num--; - if (domain_max_chk(conn, ACC_NPERM, perms.num, quota_nb_perms_per_node)) + if (domain_max_chk(conn, ACC_NPERM, perms.num)) return ENOSPC; permstr = in->buffer + strlen(in->buffer) + 1; @@ -2635,7 +2623,16 @@ static void usage(void) " memory: total used memory per domain for nodes,\n" " transactions, watches and requests, above\n" " which Xenstore will stop talking to domain\n" +" nodes: number nodes owned by a domain\n" +" node-permissions: number of access permissions per\n" +" node\n" +" node-size: total size of a node (permissions +\n" +" children names + content)\n" " outstanding: number of outstanding requests\n" +" path-length: length of a node path\n" +" transactions: number of concurrent transactions\n" +" per domain\n" +" watches: number of watches per domain" " -q, --quota-soft = set a soft quota to the value ,\n" " causing a warning to be issued via syslog() if the\n" " limit is violated, allowed quotas are:\n" @@ -2686,12 +2683,12 @@ int dom0_domid = 0; int dom0_event = 0; int priv_domid = 0; -static int get_optval_int(const char *arg) +static unsigned int get_optval_int(const char *arg) { char *end; - long val; + unsigned long val; - val = strtol(arg, &end, 10); + val = strtoul(arg, &end, 10); if (!*arg || *end || val < 0 || val > INT_MAX) barf("invalid parameter value \"%s\"\n", arg); @@ -2700,15 +2697,19 @@ static int get_optval_int(const char *arg) static bool what_matches(const char *arg, const char *what) { - unsigned int what_len = strlen(what); + unsigned int what_len; + + if (!what) + false; + what_len = strlen(what); return !strncmp(arg, what, what_len) && arg[what_len] == '='; } static void set_timeout(const char *arg) { const char *eq = strchr(arg, '='); - int val; + unsigned int val; if (!eq) barf("quotas must be specified via =\n"); @@ -2722,22 +2723,22 @@ static void set_timeout(const char *arg) static void set_quota(const char *arg, bool soft) { const char *eq = strchr(arg, '='); - int val; + struct quota *q = soft ? soft_quotas : hard_quotas; + unsigned int val; + unsigned int i; if (!eq) barf("quotas must be specified via =\n"); val = get_optval_int(eq + 1); - if (what_matches(arg, "outstanding") && !soft) - quota_req_outstanding = val; - else if (what_matches(arg, "transaction-nodes") && !soft) - quota_trans_nodes = val; - else if (what_matches(arg, "memory")) { - if (soft) - quota_memory_per_domain_soft = val; - else - quota_memory_per_domain_hard = val; - } else - barf("unknown quota \"%s\"\n", arg); + + for (i = 0; i < ACC_N; i++) { + if (what_matches(arg, q[i].name)) { + q[i].val = val; + return; + } + } + + barf("unknown quota \"%s\"\n", arg); } /* Sorted by bit values of TRACE_* flags. Flag is (1u << index). */ @@ -2789,7 +2790,7 @@ int main(int argc, char *argv[]) no_domain_init = true; break; case 'E': - quota_nb_entry_per_domain = strtol(optarg, NULL, 10); + hard_quotas[ACC_NODES].val = strtoul(optarg, NULL, 10); break; case 'F': pidfile = optarg; @@ -2807,10 +2808,10 @@ int main(int argc, char *argv[]) recovery = false; break; case 'S': - quota_max_entry_size = strtol(optarg, NULL, 10); + hard_quotas[ACC_NODESZ].val = strtoul(optarg, NULL, 10); break; case 't': - quota_max_transaction = strtol(optarg, NULL, 10); + hard_quotas[ACC_TRANS].val = strtoul(optarg, NULL, 10); break; case 'T': tracefile = optarg; @@ -2829,15 +2830,17 @@ int main(int argc, char *argv[]) verbose = true; break; case 'W': - quota_nb_watch_per_domain = strtol(optarg, NULL, 10); + hard_quotas[ACC_WATCH].val = strtoul(optarg, NULL, 10); break; case 'A': - quota_nb_perms_per_node = strtol(optarg, NULL, 10); + hard_quotas[ACC_NPERM].val = strtoul(optarg, NULL, 10); break; case 'M': - quota_max_path_len = strtol(optarg, NULL, 10); - quota_max_path_len = min(XENSTORE_REL_PATH_MAX, - quota_max_path_len); + hard_quotas[ACC_PATHLEN].val = + strtoul(optarg, NULL, 10); + hard_quotas[ACC_PATHLEN].val = + min((unsigned int)XENSTORE_REL_PATH_MAX, + hard_quotas[ACC_PATHLEN].val); break; case 'Q': set_quota(optarg, false); diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index 752c69d80f..e3a987028a 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -307,16 +307,6 @@ extern TDB_CONTEXT *tdb_ctx; extern int dom0_domid; extern int dom0_event; extern int priv_domid; -extern int quota_nb_watch_per_domain; -extern int quota_max_transaction; -extern int quota_max_entry_size; -extern int quota_nb_perms_per_node; -extern int quota_max_path_len; -extern int quota_nb_entry_per_domain; -extern int quota_req_outstanding; -extern int quota_trans_nodes; -extern int quota_memory_per_domain_soft; -extern int quota_memory_per_domain_hard; extern bool keep_orphans; extern unsigned int timeout_watch_event_msec; diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 2b4a551df5..1f746afd70 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -43,7 +43,61 @@ static evtchn_port_t virq_port; xenevtchn_handle *xce_handle = NULL; -static unsigned int acc_global_max[ACC_N]; +struct quota hard_quotas[ACC_N] = { + [ACC_NODES] = { + .name = "nodes", + .descr = "Nodes per domain", + .val = 1000, + }, + [ACC_WATCH] = { + .name = "watches", + .descr = "Watches per domain", + .val = 128, + }, + [ACC_OUTST] = { + .name = "outstanding", + .descr = "Outstanding requests per domain", + .val = 20, + }, + [ACC_MEM] = { + .name = "memory", + .descr = "Total Xenstore memory per domain (error level)", + .val = 2 * 1024 * 1024 + 512 * 1024, /* 2.5 MB */ + }, + [ACC_TRANS] = { + .name = "transactions", + .descr = "Active transactions per domain", + .val = 10, + }, + [ACC_TRANSNODES] = { + .name = "transaction-nodes", + .descr = "Max. number of accessed nodes per transaction", + .val = 1024, + }, + [ACC_NPERM] = { + .name = "node-permissions", + .descr = "Max. number of permissions per node", + .val = 5, + }, + [ACC_PATHLEN] = { + .name = "path-max", + .descr = "Max. length of a node path", + .val = XENSTORE_REL_PATH_MAX, + }, + [ACC_NODESZ] = { + .name = "node-size", + .descr = "Max. size of a node", + .val = 2048, + }, +}; + +struct quota soft_quotas[ACC_N] = { + [ACC_MEM] = { + .name = "memory", + .descr = "Total Xenstore memory per domain (warning level)", + .val = 2 * 1024 * 1024, /* 2.0 MB */ + }, +}; struct domain { @@ -204,10 +258,10 @@ 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 >= quota_req_outstanding) + if (domain->acc[ACC_OUTST].val >= hard_quotas[ACC_OUTST].val) return false; - if (domain->acc[ACC_MEM].val >= quota_memory_per_domain_hard && - quota_memory_per_domain_hard) + if (domain->acc[ACC_MEM].val >= hard_quotas[ACC_MEM].val && + hard_quotas[ACC_MEM].val) return false; } @@ -426,6 +480,7 @@ int domain_get_quota(const void *ctx, struct connection *conn, { struct domain *d = find_domain_struct(domid); char *resp; + unsigned int i; if (!d) return ENOENT; @@ -434,19 +489,15 @@ int domain_get_quota(const void *ctx, struct connection *conn, if (!resp) return ENOMEM; -#define ent(t, e) \ - resp = talloc_asprintf_append(resp, "%-17s: %8u (max: %8u\n", #t, \ - d->acc[e].val, d->acc[e].max); \ - if (!resp) return ENOMEM - - ent(nodes, ACC_NODES); - ent(watches, ACC_WATCH); - ent(transactions, ACC_TRANS); - ent(outstanding, ACC_OUTST); - ent(memory, ACC_MEM); - ent(transaction-nodes, ACC_TRANSNODES); - -#undef ent + for (i = 0; i < ACC_N; i++) { + if (!hard_quotas[i].name) + continue; + resp = talloc_asprintf_append(resp, "%-17s: %8u (max %8u)\n", + hard_quotas[i].name, + d->acc[i].val, d->acc[i].max); + if (!resp) + return ENOMEM; + } send_reply(conn, XS_CONTROL, resp, strlen(resp) + 1); @@ -456,24 +507,21 @@ int domain_get_quota(const void *ctx, struct connection *conn, int domain_max_global_acc(const void *ctx, struct connection *conn) { char *resp; + unsigned int i; resp = talloc_asprintf(ctx, "Max. seen accounting values:\n"); if (!resp) return ENOMEM; -#define ent(t, e) \ - resp = talloc_asprintf_append(resp, "%-17s: %8u\n", #t, \ - acc_global_max[e]); \ - if (!resp) return ENOMEM - - ent(nodes, ACC_NODES); - ent(watches, ACC_WATCH); - ent(transactions, ACC_TRANS); - ent(outstanding, ACC_OUTST); - ent(memory, ACC_MEM); - ent(transaction-nodes, ACC_TRANSNODES); - -#undef ent + for (i = 0; i < ACC_N; i++) { + if (!hard_quotas[i].name) + continue; + resp = talloc_asprintf_append(resp, "%-17s: %8u\n", + hard_quotas[i].name, + hard_quotas[i].max); + if (!resp) + return ENOMEM; + } send_reply(conn, XS_CONTROL, resp, strlen(resp) + 1); @@ -592,7 +640,7 @@ int acc_fix_domains(struct list_head *head, bool update) list_for_each_entry(cd, head, list) { cnt = domain_nbentry_fix(cd->domid, cd->acc[ACC_NODES], update); if (!update) { - if (cnt >= quota_nb_entry_per_domain) + if (cnt >= hard_quotas[ACC_NODES].val) return ENOSPC; if (cnt < 0) return ENOMEM; @@ -1091,8 +1139,8 @@ static void domain_acc_chk_max(struct domain *d, unsigned int what, { if (val > d->acc[what].max) d->acc[what].max = val; - if (val > acc_global_max[what] && domid_is_unprivileged(domid)) - acc_global_max[what] = val; + if (val > hard_quotas[what].max && domid_is_unprivileged(domid)) + hard_quotas[what].max = val; } static int domain_acc_add_chk(struct domain *d, unsigned int what, int add, @@ -1218,19 +1266,19 @@ void domain_reset_global_acc(void) unsigned int i; for (i = 0; i < ACC_N; i++) - acc_global_max[i] = 0; + hard_quotas[i].max = 0; /* Set current max values seen. */ hashtable_iterate(domhash, domain_reset_global_acc_sub, NULL); } bool domain_max_chk(const struct connection *conn, unsigned int what, - unsigned int val, unsigned int quota) + unsigned int val) { if (!conn || !conn->domain) return false; - if (domain_is_unprivileged(conn) && val > quota) + if (domain_is_unprivileged(conn) && val > hard_quotas[what].val) return true; domain_acc_chk_max(conn->domain, what, val, conn->id); @@ -1279,8 +1327,7 @@ static bool domain_chk_quota(struct connection *conn, unsigned int mem) domain = conn->domain; now = time(NULL); - if (mem >= quota_memory_per_domain_hard && - quota_memory_per_domain_hard) { + if (mem >= hard_quotas[ACC_MEM].val && hard_quotas[ACC_MEM].val) { if (domain->hard_quota_reported) return true; syslog(LOG_ERR, "Domain %u exceeds hard memory quota, Xenstore interface to domain stalled\n", @@ -1297,15 +1344,14 @@ static bool domain_chk_quota(struct connection *conn, unsigned int mem) syslog(LOG_INFO, "Domain %u below hard memory quota again\n", domain->domid); } - if (mem >= quota_memory_per_domain_soft && - quota_memory_per_domain_soft && - !domain->soft_quota_reported) { + if (mem >= soft_quotas[ACC_MEM].val && + soft_quotas[ACC_MEM].val && !domain->soft_quota_reported) { domain->mem_last_msg = now; domain->soft_quota_reported = true; syslog(LOG_WARNING, "Domain %u exceeds soft memory quota\n", domain->domid); } - if (mem < quota_memory_per_domain_soft && + if (mem < soft_quotas[ACC_MEM].val && domain->soft_quota_reported) { domain->mem_last_msg = now; domain->soft_quota_reported = false; diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index 2bf9b0d87b..1d11085ebc 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -34,6 +34,16 @@ enum { ACC_N /* Number of elements per domain. */ }; +struct quota { + const char *name; + const char *descr; + unsigned int val; + unsigned int max; +}; + +extern struct quota hard_quotas[ACC_N]; +extern struct quota soft_quotas[ACC_N]; + void handle_event(void); void check_domains(void); @@ -123,7 +133,7 @@ void acc_commit(struct connection *conn); int domain_max_global_acc(const void *ctx, struct connection *conn); void domain_reset_global_acc(void); bool domain_max_chk(const struct connection *conn, unsigned int what, - unsigned int val, unsigned int quota); + unsigned int val); /* Write rate limiting */ diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c index 7967770ca2..13fabe030d 100644 --- a/tools/xenstore/xenstored_transaction.c +++ b/tools/xenstore/xenstored_transaction.c @@ -244,8 +244,7 @@ int access_node(struct connection *conn, struct node *node, i = find_accessed_node(trans, node->name); if (!i) { - if (domain_max_chk(conn, ACC_TRANSNODES, trans->nodes + 1, - quota_trans_nodes)) { + if (domain_max_chk(conn, ACC_TRANSNODES, trans->nodes + 1)) { ret = ENOSPC; goto err; } @@ -471,7 +470,7 @@ int do_transaction_start(const void *ctx, struct connection *conn, if (conn->transaction) return EBUSY; - if (domain_transaction_get(conn) > quota_max_transaction) + if (domain_transaction_get(conn) > hard_quotas[ACC_TRANS].val) return ENOSPC; /* Attach transaction to ctx for autofree until it's complete */ diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_watch.c index 4deef21c4c..ca0194966e 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -239,7 +239,7 @@ int do_watch(const void *ctx, struct connection *conn, struct buffered_data *in) return EEXIST; } - if (domain_watch(conn) > quota_nb_watch_per_domain) + if (domain_watch(conn) > hard_quotas[ACC_WATCH].val) return E2BIG; watch = add_watch(conn, vec[0], vec[1], relative, false);