@@ -9,15 +9,6 @@
#include "xenstore_lib.h"
-/* Header of the node record in tdb. */
-struct xs_tdb_record_hdr {
- uint64_t generation;
- uint32_t num_perms;
- uint32_t datalen;
- uint32_t childlen;
- struct xs_permissions perms[0];
-};
-
/* Is A == B ? */
#define streq(a,b) (strcmp((a),(b)) == 0)
@@ -555,9 +555,9 @@ static void initialize_fds(int *p_sock_pollfd_idx, int *ptimeout)
}
}
-struct xs_tdb_record_hdr *db_fetch(const char *db_name, size_t *size)
+struct node_hdr *db_fetch(const char *db_name, size_t *size)
{
- struct xs_tdb_record_hdr *hdr;
+ struct node_hdr *hdr;
hdr = hashtable_search(nodes, db_name);
if (!hdr) {
@@ -565,7 +565,7 @@ struct xs_tdb_record_hdr *db_fetch(const char *db_name, size_t *size)
return NULL;
}
- *size = sizeof(*hdr) + hdr->num_perms * sizeof(hdr->perms[0]) +
+ *size = sizeof(*hdr) + hdr->num_perms * sizeof(struct xs_permissions) +
hdr->datalen + hdr->childlen;
trace_tdb("read %s size %zu\n", db_name, *size + strlen(db_name));
@@ -573,10 +573,15 @@ struct xs_tdb_record_hdr *db_fetch(const char *db_name, size_t *size)
return hdr;
}
+static struct xs_permissions *perms_from_node_hdr(struct node_hdr *hdr)
+{
+ return (struct xs_permissions *)(hdr + 1);
+}
+
static void get_acc_data(const char *name, struct node_account_data *acc)
{
size_t size;
- struct xs_tdb_record_hdr *hdr;
+ struct node_hdr *hdr;
if (acc->memory < 0) {
hdr = db_fetch(name, &size);
@@ -585,7 +590,7 @@ static void get_acc_data(const char *name, struct node_account_data *acc)
acc->memory = 0;
} else {
acc->memory = size;
- acc->domid = hdr->perms[0].id;
+ acc->domid = perms_from_node_hdr(hdr)->id;
}
}
}
@@ -606,7 +611,7 @@ int db_write(struct connection *conn, const char *db_name, void *data,
size_t size, struct node_account_data *acc,
enum write_node_mode mode, bool no_quota_check)
{
- struct xs_tdb_record_hdr *hdr = data;
+ struct node_hdr *hdr = data;
struct node_account_data old_acc = {};
unsigned int old_domid, new_domid;
size_t name_len = strlen(db_name);
@@ -620,7 +625,7 @@ int db_write(struct connection *conn, const char *db_name, void *data,
get_acc_data(db_name, &old_acc);
old_domid = get_acc_domid(conn, db_name, old_acc.domid);
- new_domid = get_acc_domid(conn, db_name, hdr->perms[0].id);
+ new_domid = get_acc_domid(conn, db_name, perms_from_node_hdr(hdr)->id);
/*
* Don't check for ENOENT, as we want to be able to switch orphaned
@@ -661,7 +666,7 @@ int db_write(struct connection *conn, const char *db_name, void *data,
if (acc) {
/* Don't use new_domid, as it might be a transaction node. */
- acc->domid = hdr->perms[0].id;
+ acc->domid = perms_from_node_hdr(hdr)->id;
acc->memory = size;
}
@@ -699,7 +704,7 @@ struct node *read_node(struct connection *conn, const void *ctx,
const char *name)
{
size_t size;
- struct xs_tdb_record_hdr *hdr;
+ struct node_hdr *hdr;
struct node *node;
const char *db_name;
int err;
@@ -733,7 +738,7 @@ struct node *read_node(struct connection *conn, const void *ctx,
node->perms.num = hdr->num_perms;
node->datalen = hdr->datalen;
node->childlen = hdr->childlen;
- node->acc.domid = hdr->perms[0].id;
+ node->acc.domid = perms_from_node_hdr(hdr)->id;
node->acc.memory = size;
/* Copy node data to new memory area, starting with permissions. */
@@ -743,7 +748,7 @@ struct node *read_node(struct connection *conn, const void *ctx,
errno = ENOMEM;
goto error;
}
- memcpy(node->perms.p, hdr->perms, size);
+ memcpy(node->perms.p, perms_from_node_hdr(hdr), size);
/* Permissions are struct xs_permissions. */
if (domain_adjust_node_perms(node))
@@ -787,7 +792,7 @@ int write_node_raw(struct connection *conn, const char *db_name,
void *data;
size_t size;
void *p;
- struct xs_tdb_record_hdr *hdr;
+ struct node_hdr *hdr;
if (domain_adjust_node_perms(node))
return errno;
@@ -814,9 +819,9 @@ int write_node_raw(struct connection *conn, const char *db_name,
hdr->datalen = node->datalen;
hdr->childlen = node->childlen;
- memcpy(hdr->perms, node->perms.p,
- node->perms.num * sizeof(*node->perms.p));
- p = hdr->perms + node->perms.num;
+ p = perms_from_node_hdr(hdr);
+ memcpy(p, node->perms.p, node->perms.num * sizeof(*node->perms.p));
+ p += node->perms.num * sizeof(*node->perms.p);
memcpy(p, node->data, node->datalen);
p += node->datalen;
memcpy(p, node->children, node->childlen);
@@ -168,6 +168,24 @@ struct connection
};
extern struct list_head connections;
+/*
+ * Header of the node record in the data base.
+ * In the data base the memory of the node is a single memory chunk with the
+ * following format:
+ * struct {
+ * node_hdr hdr;
+ * struct xs_permissions perms[hdr.num_perms];
+ * char data[hdr.datalen];
+ * char children[hdr.childlen];
+ * };
+ */
+struct node_hdr {
+ uint64_t generation;
+ uint16_t num_perms;
+ uint16_t datalen;
+ uint32_t childlen;
+};
+
struct node_perms {
unsigned int num;
struct xs_permissions *p;
@@ -361,7 +379,7 @@ extern xengnttab_handle **xgt_handle;
int remember_string(struct hashtable *hash, const char *str);
/* Data base access functions. */
-struct xs_tdb_record_hdr *db_fetch(const char *db_name, size_t *size);
+struct node_hdr *db_fetch(const char *db_name, size_t *size);
int db_write(struct connection *conn, const char *db_name, void *data,
size_t size, struct node_account_data *acc,
enum write_node_mode mode, bool no_quota_check);
@@ -357,7 +357,7 @@ static int finalize_transaction(struct connection *conn,
{
struct accessed_node *i, *n;
size_t size;
- struct xs_tdb_record_hdr *hdr;
+ struct node_hdr *hdr;
uint64_t gen;
int flag;
Struct xs_tdb_record_hdr is used for nodes stored in the data base. When working on a node, struct node is being used, which is including the same information as struct xs_tdb_record_hdr, but in a different format. Rework struct xs_tdb_record_hdr in order to prepare including it in struct node. Do the following modifications: - move its definition to xenstored_core.h, as the reason to put it into utils.h are no longer existing - rename it to struct node_hdr, as the "tdb" in its name has only historical reasons - replace the empty permission array at the end with a comment about the layout of data in the data base (concatenation of header, permissions, node contents, and children list) - use narrower types for num_perms and datalen, as those are naturally limited to XENSTORE_PAYLOAD_MAX (childlen is different here, as it is in theory basically unlimited) Signed-off-by: Juergen Gross <jgross@suse.com> --- V2: - new patch --- tools/xenstore/utils.h | 9 ------- tools/xenstore/xenstored_core.c | 35 +++++++++++++++----------- tools/xenstore/xenstored_core.h | 20 ++++++++++++++- tools/xenstore/xenstored_transaction.c | 2 +- 4 files changed, 40 insertions(+), 26 deletions(-)