From nobody Mon Feb 9 13:38:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=quarantine dis=none) header.from=suse.com ARC-Seal: i=1; a=rsa-sha256; t=1688973002; cv=none; d=zohomail.com; s=zohoarc; b=k1fMtoSEdfI4htWml62qHuRhBoXqExy+vTTA96Jd/XxU4kZp3xhGSIjSWeI7By9D09l/yYtn0XJLOjpCRQSnx7DpVfy4XX07r+A00QLkr8h33l2HU37+FHvis/ZTSR7J6kziowxe8MNw9ZzcTrNW1Y1Mk6+s7k3twowNYi70ZSs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1688973002; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=UK04J9dErimDKqoXrosnGNBdXEpxv+Xoy6piXu//+Go=; b=SLoCwHzTTuakEA7YN/Mcg0Qc+PslF+Q55rMurqahLir08CP89cACnk2YTbcY56TMCdJB3lME72jZPLC/UVud+G329iLhWjeXOk3BkHkLRk0H86NeEe5oIoZKMhbtkr+on22snPQeopCejuL2iiKaxtuH6gsiA8RHEic8B3PsH3I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1688973002960481.22650654297047; Mon, 10 Jul 2023 00:10:02 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.560984.877220 (Exim 4.92) (envelope-from ) id 1qIl1d-0001IK-0K; Mon, 10 Jul 2023 07:09:37 +0000 Received: by outflank-mailman (output) from mailman id 560984.877220; Mon, 10 Jul 2023 07:09:36 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1qIl1c-0001ID-Tp; Mon, 10 Jul 2023 07:09:36 +0000 Received: by outflank-mailman (input) for mailman id 560984; Mon, 10 Jul 2023 07:09:36 +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 1qIkto-0002xd-WC for xen-devel@lists.xenproject.org; Mon, 10 Jul 2023 07:01:33 +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 99a2c6e0-1eef-11ee-b239-6b7b168915f2; Mon, 10 Jul 2023 09:01:32 +0200 (CEST) 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 C6C5A1F38D; Mon, 10 Jul 2023 07:01:31 +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 9A10C1361C; Mon, 10 Jul 2023 07:01:31 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id 3sRVJMusq2RyYwAAMHmgww (envelope-from ); Mon, 10 Jul 2023 07:01:31 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 99a2c6e0-1eef-11ee-b239-6b7b168915f2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=susede1; t=1688972491; 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=UK04J9dErimDKqoXrosnGNBdXEpxv+Xoy6piXu//+Go=; b=L6vcRSYbCCaE/luqflnMc+4AEs3JIpmMPnN2bu8sfKaeQCNEqv2wyZB4UQZB9XHGXuDqfn 9Qm7jcvaMfrL8g+0YGIjC1xspfJtt556FaB5DQEkitGuij4yG849KJBR/A0bvAoCsOfcUs SXwbqF851v6mUhpOJa/XG4ea30w0oNA= From: Juergen Gross To: xen-devel@lists.xenproject.org Cc: Juergen Gross , Wei Liu , Julien Grall , Anthony PERARD Subject: [PATCH v2 18/18] tools/xenstore: add nocopy flag to node read functions Date: Mon, 10 Jul 2023 08:59:47 +0200 Message-Id: <20230710065947.4201-19-jgross@suse.com> X-Mailer: git-send-email 2.35.3 In-Reply-To: <20230710065947.4201-1-jgross@suse.com> References: <20230710065947.4201-1-jgross@suse.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @suse.com) X-ZM-MESSAGEID: 1688973004304100001 Content-Type: text/plain; charset="utf-8" Today when reading a node from the data base through read_node(), the node data is copied in order to avoid modifying the data base when preparing a node update, as otherwise an error might result in an inconsistent state. There are, however, many cases where such a copy operation isn't needed, as the node isn't modified. Add a "nocopy" flag to read_node() and get_node*() functions for making those cases less memory consuming and more performant. Note that there is one modification of the node data left, which is not problematic: domain_adjust_node_perms() might set the "ignore" flag of a permission. This does no harm, as such an update of the permissions doesn't need to be undone in case of a later processing error. Signed-off-by: Juergen Gross --- V2: - new patch --- tools/xenstore/xenstored_core.c | 68 +++++++++++++++++-------------- tools/xenstore/xenstored_core.h | 2 +- tools/xenstore/xenstored_domain.c | 2 +- tools/xenstore/xenstored_watch.c | 4 +- 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_cor= e.c index 7495747d76..8041a6a1c6 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -706,7 +706,7 @@ void db_delete(struct connection *conn, const char *nam= e, * Temporary memory allocations will be done with ctx. */ struct node *read_node(struct connection *conn, const void *ctx, - const char *name) + const char *name, bool nocopy) { size_t size; struct node_hdr *hdr; @@ -743,14 +743,18 @@ struct node *read_node(struct connection *conn, const= void *ctx, node->acc.domid =3D perms_from_node_hdr(hdr)->id; node->acc.memory =3D size; =20 - /* Copy node data to new memory area, starting with permissions. */ - size -=3D sizeof(*hdr); - node->perms =3D talloc_size(node, size); - if (node->perms =3D=3D NULL) { - errno =3D ENOMEM; - goto error; + if (nocopy) { + node->perms =3D (struct xs_permissions *)(hdr + 1); + } else { + /* Copy node data to new area, starting with permissions. */ + size -=3D sizeof(*hdr); + node->perms =3D talloc_size(node, size); + if (node->perms =3D=3D NULL) { + errno =3D ENOMEM; + goto error; + } + memcpy(node->perms, perms_from_node_hdr(hdr), size); } - memcpy(node->perms, perms_from_node_hdr(hdr), size); =20 /* Permissions are struct xs_permissions. */ if (domain_adjust_node_perms(node)) @@ -905,7 +909,7 @@ static int ask_parents(struct connection *conn, const v= oid *ctx, name =3D get_parent(ctx, name); if (!name) return errno; - node =3D read_node(conn, ctx, name); + node =3D read_node(conn, ctx, name, true); if (node) break; if (read_node_can_propagate_errno()) @@ -954,12 +958,12 @@ static int errno_from_parents(struct connection *conn= , const void *ctx, static struct node *get_node(struct connection *conn, const void *ctx, const char *name, - unsigned int perm) + unsigned int perm, bool nocopy) { struct node *node; struct node_perms perms; =20 - node =3D read_node(conn, ctx, name); + node =3D read_node(conn, ctx, name, nocopy); /* If we don't have permission, we don't have node. */ if (node) { node_to_node_perms(node, &perms); @@ -1248,7 +1252,7 @@ static struct node *get_node_canonicalized(struct con= nection *conn, const void *ctx, const char *name, char **canonical_name, - unsigned int perm) + unsigned int perm, bool nocopy) { char *tmp_name; =20 @@ -1261,17 +1265,18 @@ static struct node *get_node_canonicalized(struct c= onnection *conn, errno =3D EINVAL; return NULL; } - return get_node(conn, ctx, *canonical_name, perm); + return get_node(conn, ctx, *canonical_name, perm, nocopy); } =20 static struct node *get_spec_node(struct connection *conn, const void *ctx, const char *name, char **canonical_name, - unsigned int perm) + unsigned int perm, bool nocopy) { if (name[0] =3D=3D '@') - return get_node(conn, ctx, name, perm); + return get_node(conn, ctx, name, perm, nocopy); =20 - return get_node_canonicalized(conn, ctx, name, canonical_name, perm); + return get_node_canonicalized(conn, ctx, name, canonical_name, perm, + nocopy); } =20 static int send_directory(const void *ctx, struct connection *conn, @@ -1280,7 +1285,7 @@ static int send_directory(const void *ctx, struct con= nection *conn, struct node *node; =20 node =3D get_node_canonicalized(conn, ctx, onearg(in), NULL, - XS_PERM_READ); + XS_PERM_READ, true); if (!node) return errno; =20 @@ -1302,7 +1307,7 @@ static int send_directory_part(const void *ctx, struc= t connection *conn, =20 /* First arg is node name. */ node =3D get_node_canonicalized(conn, ctx, in->buffer, NULL, - XS_PERM_READ); + XS_PERM_READ, true); if (!node) return errno; =20 @@ -1352,7 +1357,7 @@ static int do_read(const void *ctx, struct connection= *conn, struct node *node; =20 node =3D get_node_canonicalized(conn, ctx, onearg(in), NULL, - XS_PERM_READ); + XS_PERM_READ, true); if (!node) return errno; =20 @@ -1414,7 +1419,7 @@ static struct node *construct_node(struct connection = *conn, const void *ctx, return NULL; =20 /* Try to read parent node until we found an existing one. */ - parent =3D read_node(conn, ctx, parentname); + parent =3D read_node(conn, ctx, parentname, false); if (!parent && (errno !=3D ENOENT || !strcmp(parentname, "/"))) return NULL; =20 @@ -1566,7 +1571,8 @@ static int do_write(const void *ctx, struct connectio= n *conn, offset =3D strlen(vec[0]) + 1; datalen =3D in->used - offset; =20 - node =3D get_node_canonicalized(conn, ctx, vec[0], &name, XS_PERM_WRITE); + node =3D get_node_canonicalized(conn, ctx, vec[0], &name, XS_PERM_WRITE, + false); if (!node) { /* No permissions, invalid input? */ if (errno !=3D ENOENT) @@ -1595,7 +1601,7 @@ static int do_mkdir(const void *ctx, struct connectio= n *conn, char *name; =20 node =3D get_node_canonicalized(conn, ctx, onearg(in), &name, - XS_PERM_WRITE); + XS_PERM_WRITE, false); =20 /* If it already exists, fine. */ if (!node) { @@ -1689,7 +1695,7 @@ int rm_node(struct connection *conn, const void *ctx,= const char *name) if (!parentname) return errno; =20 - parent =3D read_node(conn, ctx, parentname); + parent =3D read_node(conn, ctx, parentname, false); if (!parent) return read_node_can_propagate_errno() ? errno : EINVAL; =20 @@ -1725,7 +1731,7 @@ static int do_rm(const void *ctx, struct connection *= conn, char *parentname; =20 node =3D get_node_canonicalized(conn, ctx, onearg(in), &name, - XS_PERM_WRITE); + XS_PERM_WRITE, false); if (!node) { /* Didn't exist already? Fine, if parent exists. */ if (errno =3D=3D ENOENT) { @@ -1734,7 +1740,7 @@ static int do_rm(const void *ctx, struct connection *= conn, parentname =3D get_parent(ctx, name); if (!parentname) return errno; - node =3D read_node(conn, ctx, parentname); + node =3D read_node(conn, ctx, parentname, false); if (node) { send_ack(conn, XS_RM); return 0; @@ -1767,7 +1773,7 @@ static int do_get_perms(const void *ctx, struct conne= ction *conn, unsigned int len; struct node_perms perms; =20 - node =3D get_spec_node(conn, ctx, onearg(in), NULL, XS_PERM_READ); + node =3D get_spec_node(conn, ctx, onearg(in), NULL, XS_PERM_READ, true); if (!node) return errno; =20 @@ -1811,7 +1817,7 @@ static int do_set_perms(const void *ctx, struct conne= ction *conn, =20 /* We must own node to do this (tools can do this too). */ node =3D get_spec_node(conn, ctx, in->buffer, &name, - XS_PERM_WRITE | XS_PERM_OWNER); + XS_PERM_WRITE | XS_PERM_OWNER, false); if (!node) return errno; =20 @@ -1933,7 +1939,7 @@ int walk_node_tree(const void *ctx, struct connection= *conn, const char *root, parent =3D node; } /* Read next node (root node or next child). */ - node =3D read_node(conn, tmpctx, name); + node =3D read_node(conn, tmpctx, name, false); if (!node) { /* Child not found - should not happen! */ /* ENOENT case can be handled by supplied function. */ @@ -2483,7 +2489,7 @@ int check_store_path(const char *name, struct check_s= tore_data *data) { struct node *node; =20 - node =3D read_node(NULL, NULL, name); + node =3D read_node(NULL, NULL, name, false); if (!node) { log("check_store: error %d reading special node '%s'", errno, name); @@ -3245,7 +3251,7 @@ static int dump_state_special_node(FILE *fp, const vo= id *ctx, struct node *node; int ret; =20 - node =3D read_node(NULL, ctx, name); + node =3D read_node(NULL, ctx, name, true); if (!node) return dump_state_node_err(data, "Dump node read node error"); =20 @@ -3447,7 +3453,7 @@ void read_state_node(const void *ctx, const void *sta= te) parentname =3D get_parent(node, name); if (!parentname) barf("allocation error restoring node"); - parent =3D read_node(NULL, node, parentname); + parent =3D read_node(NULL, node, parentname, false); if (!parent) barf("read parent error restoring node"); =20 diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_cor= e.h index 79b2a699fd..a4cd3e503a 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -280,7 +280,7 @@ int write_node_raw(struct connection *conn, const char = *db_name, =20 /* Get a node from the data base. */ struct node *read_node(struct connection *conn, const void *ctx, - const char *name); + const char *name, bool nocopy); =20 /* Remove a node and its children. */ int rm_node(struct connection *conn, const void *ctx, const char *name); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_d= omain.c index 4d66dc91ce..b8fd7469d0 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -568,7 +568,7 @@ static void fire_special_watches(const char *name) if (!ctx) return; =20 - node =3D read_node(NULL, ctx, name); + node =3D read_node(NULL, ctx, name, true); =20 if (node) fire_watches(NULL, ctx, name, node, true, NULL); diff --git a/tools/xenstore/xenstored_watch.c b/tools/xenstore/xenstored_wa= tch.c index 10645f762d..54a9468090 100644 --- a/tools/xenstore/xenstored_watch.c +++ b/tools/xenstore/xenstored_watch.c @@ -88,7 +88,7 @@ static bool watch_permitted(struct connection *conn, cons= t void *ctx, } =20 if (!node) { - node =3D read_node(conn, ctx, name); + node =3D read_node(conn, ctx, name, true); if (!node) return false; } @@ -103,7 +103,7 @@ static bool watch_permitted(struct connection *conn, co= nst void *ctx, parent_name =3D get_parent(ctx, node->name); if (!parent_name) return false; - parent =3D read_node(conn, ctx, parent_name); + parent =3D read_node(conn, ctx, parent_name, true); if (!parent) return false; } --=20 2.35.3