return NULL;
}
-const char *dump_state_node_perms(FILE *fp, struct xs_state_node *sn,
- const struct xs_permissions *perms,
+const char *dump_state_node_perms(FILE *fp, const struct xs_permissions *perms,
unsigned int n_perms)
{
unsigned int p;
for (p = 0; p < n_perms; p++) {
+ struct xs_state_node_perm sp;
+
switch ((int)perms[p].perms & ~XS_PERM_IGNORE) {
case XS_PERM_READ:
- sn->perms[p].access = XS_STATE_NODE_PERM_READ;
+ sp.access = XS_STATE_NODE_PERM_READ;
break;
case XS_PERM_WRITE:
- sn->perms[p].access = XS_STATE_NODE_PERM_WRITE;
+ sp.access = XS_STATE_NODE_PERM_WRITE;
break;
case XS_PERM_READ | XS_PERM_WRITE:
- sn->perms[p].access = XS_STATE_NODE_PERM_BOTH;
+ sp.access = XS_STATE_NODE_PERM_BOTH;
break;
default:
- sn->perms[p].access = XS_STATE_NODE_PERM_NONE;
+ sp.access = XS_STATE_NODE_PERM_NONE;
break;
}
- sn->perms[p].flags = (perms[p].perms & XS_PERM_IGNORE)
+ sp.flags = (perms[p].perms & XS_PERM_IGNORE)
? XS_STATE_NODE_PERM_IGNORE : 0;
- sn->perms[p].domid = perms[p].id;
- }
+ sp.domid = perms[p].id;
- if (fwrite(sn->perms, sizeof(*sn->perms), n_perms, fp) != n_perms)
- return "Dump node permissions error";
+ if (fwrite(&sp, sizeof(sp), 1, fp) != 1)
+ return "Dump node permissions error";
+ }
return NULL;
}
-static const char *dump_state_node_tree(FILE *fp, char *path)
+struct dump_node_data {
+ FILE *fp;
+ const char *err;
+};
+
+static int dump_state_node_err(struct dump_node_data *data, const char *err)
+{
+ data->err = err;
+ return WALK_TREE_ERROR_STOP;
+}
+
+static int dump_state_node(const void *ctx, struct connection *conn,
+ struct node *node, void *arg)
{
- unsigned int pathlen, childlen, p = 0;
+ struct dump_node_data *data = arg;
+ FILE *fp = data->fp;
+ unsigned int pathlen;
struct xs_state_record_header head;
struct xs_state_node sn;
- TDB_DATA key, data;
- const struct xs_tdb_record_hdr *hdr;
- const char *child;
const char *ret;
- pathlen = strlen(path) + 1;
-
- set_tdb_key(path, &key);
- data = tdb_fetch(tdb_ctx, key);
- if (data.dptr == NULL)
- return "Error reading node";
-
- /* Clean up in case of failure. */
- talloc_steal(path, data.dptr);
-
- hdr = (void *)data.dptr;
+ pathlen = strlen(node->name) + 1;
head.type = XS_STATE_TYPE_NODE;
head.length = sizeof(sn);
sn.conn_id = 0;
sn.ta_id = 0;
sn.ta_access = 0;
- sn.perm_n = hdr->num_perms;
+ sn.perm_n = node->perms.num;
sn.path_len = pathlen;
- sn.data_len = hdr->datalen;
- head.length += hdr->num_perms * sizeof(*sn.perms);
+ sn.data_len = node->datalen;
+ head.length += node->perms.num * sizeof(*sn.perms);
head.length += pathlen;
- head.length += hdr->datalen;
+ head.length += node->datalen;
head.length = ROUNDUP(head.length, 3);
if (fwrite(&head, sizeof(head), 1, fp) != 1)
- return "Dump node state error";
+ return dump_state_node_err(data, "Dump node head error");
if (fwrite(&sn, sizeof(sn), 1, fp) != 1)
- return "Dump node state error";
+ return dump_state_node_err(data, "Dump node state error");
- ret = dump_state_node_perms(fp, &sn, hdr->perms, hdr->num_perms);
+ ret = dump_state_node_perms(fp, node->perms.p, node->perms.num);
if (ret)
- return ret;
+ return dump_state_node_err(data, ret);
- if (fwrite(path, pathlen, 1, fp) != 1)
- return "Dump node path error";
- if (hdr->datalen &&
- fwrite(hdr->perms + hdr->num_perms, hdr->datalen, 1, fp) != 1)
- return "Dump node data error";
+ if (fwrite(node->name, pathlen, 1, fp) != 1)
+ return dump_state_node_err(data, "Dump node path error");
+
+ if (node->datalen && fwrite(node->data, node->datalen, 1, fp) != 1)
+ return dump_state_node_err(data, "Dump node data error");
ret = dump_state_align(fp);
if (ret)
- return ret;
-
- child = (char *)(hdr->perms + hdr->num_perms) + hdr->datalen;
-
- /*
- * Use path for constructing children paths.
- * As we don't write out nodes without having written their parent
- * already we will never clobber a part of the path we'll need later.
- */
- pathlen--;
- if (path[pathlen - 1] != '/') {
- path[pathlen] = '/';
- pathlen++;
- }
- while (p < hdr->childlen) {
- childlen = strlen(child) + 1;
- if (pathlen + childlen > XENSTORE_ABS_PATH_MAX)
- return "Dump node path length error";
- strcpy(path + pathlen, child);
- ret = dump_state_node_tree(fp, path);
- if (ret)
- return ret;
- p += childlen;
- child += childlen;
- }
-
- talloc_free(data.dptr);
+ return dump_state_node_err(data, ret);
- return NULL;
+ return WALK_TREE_OK;
}
const char *dump_state_nodes(FILE *fp, const void *ctx)
{
- char *path;
-
- path = talloc_size(ctx, XENSTORE_ABS_PATH_MAX);
- if (!path)
- return "Path buffer allocation error";
+ struct dump_node_data data = {
+ .fp = fp,
+ .err = "Dump node walk error"
+ };
+ struct walk_funcs walkfuncs = { .enter = dump_state_node };
- strcpy(path, "/");
+ if (walk_node_tree(ctx, NULL, "/", &walkfuncs, &data))
+ return data.err;
- return dump_state_node_tree(fp, path);
+ return NULL;
}
void read_state_global(const void *ctx, const void *state)