Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
xen.23271
xsa115-3.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File xsa115-3.patch of Package xen.23271
From b8c6dbb67ebb449126023446a7d209eedf966537 Mon Sep 17 00:00:00 2001 From: Juergen Gross <jgross@suse.com> Date: Thu, 11 Jun 2020 16:12:39 +0200 Subject: [PATCH 03/10] tools/xenstore: fix node accounting after failed node creation When a node creation fails the number of nodes of the domain should be the same as before the failed node creation. In case of failure when trying to create a node requiring to create one or more intermediate nodes as well (e.g. when /a/b/c/d is to be created, but /a/b isn't existing yet) it might happen that the number of nodes of the creating domain is not reset to the value it had before. So move the quota accounting out of construct_node() and into the node write loop in create_node() in order to be able to undo the accounting in case of an error in the intermediate node destructor. This is part of XSA-115. Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Paul Durrant <paul@xen.org> Acked-by: Julien Grall <jgrall@amazon.com> --- tools/xenstore/xenstored_core.c | 37 ++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index bb2f9fd4e76e..db9b9ca7957d 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -925,11 +925,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx, if (!parent) return NULL; - if (domain_entry(conn) >= quota_nb_entry_per_domain) { - errno = ENOSPC; - return NULL; - } - /* Add child to parent. */ base = basename(name); baselen = strlen(base) + 1; @@ -962,7 +957,6 @@ static struct node *construct_node(struct connection *conn, const void *ctx, node->children = node->data = NULL; node->childlen = node->datalen = 0; node->parent = parent; - domain_entry_inc(conn, node); return node; nomem: @@ -982,6 +976,9 @@ static int destroy_node(void *_node) key.dsize = strlen(node->name); tdb_delete(tdb_ctx, key); + + domain_entry_dec(talloc_parent(node), node); + return 0; } @@ -998,18 +995,34 @@ static struct node *create_node(struct connection *conn, const void *ctx, node->data = data; node->datalen = datalen; - /* We write out the nodes down, setting destructor in case - * something goes wrong. */ + /* + * We write out the nodes bottom up. + * All new created nodes will have i->parent set, while the final + * node will be already existing and won't have i->parent set. + * New nodes are subject to quota handling. + * Initially set a destructor for all new nodes removing them from + * TDB again and undoing quota accounting for the case of an error + * during the write loop. + */ for (i = node; i; i = i->parent) { - if (write_node(conn, i, false)) { - domain_entry_dec(conn, i); + /* i->parent is set for each new node, so check quota. */ + if (i->parent && + domain_entry(conn) >= quota_nb_entry_per_domain) { + errno = ENOSPC; return NULL; } - talloc_set_destructor(i, destroy_node); + if (write_node(conn, i, false)) + return NULL; + + /* Account for new node, set destructor for error case. */ + if (i->parent) { + domain_entry_inc(conn, i); + talloc_set_destructor(i, destroy_node); + } } /* OK, now remove destructors so they stay around */ - for (i = node; i; i = i->parent) + for (i = node; i->parent; i = i->parent) talloc_set_destructor(i, NULL); return node; } -- 2.17.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor