/*
 * QEMU Xen emulation: The actual implementation of XenStore
 *
 * Copyright © 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Authors: David Woodhouse <dwmw2@infradead.org>, Paul Durrant <paul@xen.org>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "qom/object.h"

#include "hw/xen/xen.h"

#include "xen_xenstore.h"
#include "xenstore_impl.h"

#include "hw/xen/interface/io/xs_wire.h"

#define XS_MAX_WATCHES          128
#define XS_MAX_DOMAIN_NODES     1000
#define XS_MAX_NODE_SIZE        2048
#define XS_MAX_TRANSACTIONS     10
#define XS_MAX_PERMS_PER_NODE   5

#define XS_VALID_CHARS "abcdefghijklmnopqrstuvwxyz" \
                       "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
                       "0123456789-/_"

typedef struct XsNode {
    uint32_t ref;
    GByteArray *content;
    GList *perms;
    GHashTable *children;
    uint64_t gencnt;
    bool deleted_in_tx;
    bool modified_in_tx;
    unsigned int serialized_tx;
#ifdef XS_NODE_UNIT_TEST
    gchar *name; /* debug only */
#endif
} XsNode;

typedef struct XsWatch {
    struct XsWatch *next;
    xs_impl_watch_fn *cb;
    void *cb_opaque;
    char *token;
    unsigned int dom_id;
    int rel_prefix;
} XsWatch;

typedef struct XsTransaction {
    XsNode *root;
    unsigned int nr_nodes;
    unsigned int base_tx;
    unsigned int tx_id;
    unsigned int dom_id;
} XsTransaction;

struct XenstoreImplState {
    XsNode *root;
    unsigned int nr_nodes;
    GHashTable *watches;
    unsigned int nr_domu_watches;
    GHashTable *transactions;
    unsigned int nr_domu_transactions;
    unsigned int root_tx;
    unsigned int last_tx;
    bool serialized;
};


static void nobble_tx(gpointer key, gpointer value, gpointer user_data)
{
    unsigned int *new_tx_id = user_data;
    XsTransaction *tx = value;

    if (tx->base_tx == *new_tx_id) {
        /* Transactions based on XBT_NULL will always fail */
        tx->base_tx = XBT_NULL;
    }
}

static inline unsigned int next_tx(struct XenstoreImplState *s)
{
    unsigned int tx_id;

    /* Find the next TX id which isn't either XBT_NULL or in use. */
    do {
        tx_id = ++s->last_tx;
    } while (tx_id == XBT_NULL || tx_id == s->root_tx ||
             g_hash_table_lookup(s->transactions, GINT_TO_POINTER(tx_id)));

    /*
     * It is vanishingly unlikely, but ensure that no outstanding transaction
     * is based on the (previous incarnation of the) newly-allocated TX id.
     */
    g_hash_table_foreach(s->transactions, nobble_tx, &tx_id);

    return tx_id;
}

static inline XsNode *xs_node_new(void)
{
    XsNode *n = g_new0(XsNode, 1);
    n->ref = 1;

#ifdef XS_NODE_UNIT_TEST
    nr_xs_nodes++;
    xs_node_list = g_list_prepend(xs_node_list, n);
#endif
    return n;
}

static inline XsNode *xs_node_ref(XsNode *n)
{
    /* With just 10 transactions, it can never get anywhere near this. */
    g_assert(n->ref < INT_MAX);

    g_assert(n->ref);
    n->ref++;
    return n;
}

static inline void xs_node_unref(XsNode *n)
{
    if (!n) {
        return;
    }
    g_assert(n->ref);
    if (--n->ref) {
        return;
    }

    if (n->content) {
        g_byte_array_unref(n->content);
    }
    if (n->perms) {
        g_list_free_full(n->perms, g_free);
    }
    if (n->children) {
        g_hash_table_unref(n->children);
    }
#ifdef XS_NODE_UNIT_TEST
    g_free(n->name);
    nr_xs_nodes--;
    xs_node_list = g_list_remove(xs_node_list, n);
#endif
    g_free(n);
}

char *xs_perm_as_string(unsigned int perm, unsigned int domid)
{
    char letter;

    switch (perm) {
    case XS_PERM_READ | XS_PERM_WRITE:
        letter = 'b';
        break;
    case XS_PERM_READ:
        letter = 'r';
        break;
    case XS_PERM_WRITE:
        letter = 'w';
        break;
    case XS_PERM_NONE:
    default:
        letter = 'n';
        break;
    }

    return g_strdup_printf("%c%u", letter, domid);
}

static gpointer do_perm_copy(gconstpointer src, gpointer user_data)
{
    return g_strdup(src);
}

static XsNode *xs_node_create(const char *name, GList *perms)
{
    XsNode *n = xs_node_new();

#ifdef XS_NODE_UNIT_TEST
    if (name) {
        n->name = g_strdup(name);
    }
#endif

    n->perms = g_list_copy_deep(perms, do_perm_copy, NULL);

    return n;
}

/* For copying from one hash table to another using g_hash_table_foreach() */
static void do_child_insert(gpointer key, gpointer value, gpointer user_data)
{
    g_hash_table_insert(user_data, g_strdup(key), xs_node_ref(value));
}

static XsNode *xs_node_copy(XsNode *old)
{
    XsNode *n = xs_node_new();

    n->gencnt = old->gencnt;

#ifdef XS_NODE_UNIT_TEST
    if (n->name) {
        n->name = g_strdup(old->name);
    }
#endif

    assert(old);
    if (old->children) {
        n->children = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
                                            (GDestroyNotify)xs_node_unref);
        g_hash_table_foreach(old->children, do_child_insert, n->children);
    }
    if (old->perms) {
        n->perms = g_list_copy_deep(old->perms, do_perm_copy, NULL);
    }
    if (old->content) {
        n->content = g_byte_array_ref(old->content);
    }
    return n;
}

/* Returns true if it made a change to the hash table */
static bool xs_node_add_child(XsNode *n, const char *path_elem, XsNode *child)
{
    assert(!strchr(path_elem, '/'));

    if (!child) {
        assert(n->children);
        return g_hash_table_remove(n->children, path_elem);
    }

#ifdef XS_NODE_UNIT_TEST
    g_free(child->name);
    child->name = g_strdup(path_elem);
#endif
    if (!n->children) {
        n->children = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
                                            (GDestroyNotify)xs_node_unref);
    }

    /*
     * The documentation for g_hash_table_insert() says that it "returns a
     * boolean value to indicate whether the newly added value was already
     * in the hash table or not."
     *
     * It could perhaps be clearer that returning TRUE means it wasn't,
     */
    return g_hash_table_insert(n->children, g_strdup(path_elem), child);
}

struct walk_op {
    struct XenstoreImplState *s;
    char path[XENSTORE_ABS_PATH_MAX + 2]; /* Two NUL terminators */
    int (*op_fn)(XsNode **n, struct walk_op *op);
    void *op_opaque;
    void *op_opaque2;

    GList *watches;
    unsigned int dom_id;
    unsigned int tx_id;

    /* The number of nodes which will exist in the tree if this op succeeds. */
    unsigned int new_nr_nodes;

    /*
     * This is maintained on the way *down* the walk to indicate
     * whether nodes can be modified in place or whether COW is
     * required. It starts off being true, as we're always going to
     * replace the root node. If we walk into a shared subtree it
     * becomes false. If we start *creating* new nodes for a write,
     * it becomes true again.
     *
     * Do not use it on the way back up.
     */
    bool inplace;
    bool mutating;
    bool create_dirs;
    bool in_transaction;

    /* Tracking during recursion so we know which is first. */
    bool deleted_in_tx;
};

static void fire_watches(struct walk_op *op, bool parents)
{
    GList *l = NULL;
    XsWatch *w;

    if (!op->mutating || op->in_transaction) {
        return;
    }

    if (parents) {
        l = op->watches;
    }

    w = g_hash_table_lookup(op->s->watches, op->path);
    while (w || l) {
        if (!w) {
            /* Fire the parent nodes from 'op' if asked to */
            w = l->data;
            l = l->next;
            continue;
        }

        assert(strlen(op->path) > w->rel_prefix);
        w->cb(w->cb_opaque, op->path + w->rel_prefix, w->token);

        w = w->next;
    }
}

static int xs_node_add_content(XsNode **n, struct walk_op *op)
{
    GByteArray *data = op->op_opaque;

    if (op->dom_id) {
        /*
         * The real XenStored includes permissions and names of child nodes
         * in the calculated datasize but life's too short. For a single
         * tenant internal XenStore, we don't have to be quite as pedantic.
         */
        if (data->len > XS_MAX_NODE_SIZE) {
            return E2BIG;
        }
    }
    /* We *are* the node to be written. Either this or a copy. */
    if (!op->inplace) {
        XsNode *old = *n;
        *n = xs_node_copy(old);
        xs_node_unref(old);
    }

    if ((*n)->content) {
        g_byte_array_unref((*n)->content);
    }
    (*n)->content = g_byte_array_ref(data);
    if (op->tx_id != XBT_NULL) {
        (*n)->modified_in_tx = true;
    }
    return 0;
}

static int xs_node_get_content(XsNode **n, struct walk_op *op)
{
    GByteArray *data = op->op_opaque;
    GByteArray *node_data;

    assert(op->inplace);
    assert(*n);

    node_data = (*n)->content;
    if (node_data) {
        g_byte_array_append(data, node_data->data, node_data->len);
    }

    return 0;
}

static int node_rm_recurse(gpointer key, gpointer value, gpointer user_data)
{
    struct walk_op *op = user_data;
    int path_len = strlen(op->path);
    int key_len = strlen(key);
    XsNode *n = value;
    bool this_inplace = op->inplace;

    if (n->ref != 1) {
        op->inplace = 0;
    }

    assert(key_len + path_len + 2 <= sizeof(op->path));
    op->path[path_len] = '/';
    memcpy(op->path + path_len + 1, key, key_len + 1);

    if (n->children) {
        g_hash_table_foreach_remove(n->children, node_rm_recurse, op);
    }
    op->new_nr_nodes--;

    /*
     * Fire watches on *this* node but not the parents because they are
     * going to be deleted too, so the watch will fire for them anyway.
     */
    fire_watches(op, false);
    op->path[path_len] = '\0';

    /*
     * Actually deleting the child here is just an optimisation; if we
     * don't then the final unref on the topmost victim will just have
     * to cascade down again repeating all the g_hash_table_foreach()
     * calls.
     */
    return this_inplace;
}

static XsNode *xs_node_copy_deleted(XsNode *old, struct walk_op *op);
static void copy_deleted_recurse(gpointer key, gpointer value,
                                 gpointer user_data)
{
    struct walk_op *op = user_data;
    GHashTable *siblings = op->op_opaque2;
    XsNode *n = xs_node_copy_deleted(value, op);

    /*
     * Reinsert the deleted_in_tx copy of the node into the parent's
     * 'children' hash table. Having stashed it from op->op_opaque2
     * before the recursive call to xs_node_copy_deleted() scribbled
     * over it.
     */
    g_hash_table_insert(siblings, g_strdup(key), n);
}

static XsNode *xs_node_copy_deleted(XsNode *old, struct walk_op *op)
{
    XsNode *n = xs_node_new();

    n->gencnt = old->gencnt;

#ifdef XS_NODE_UNIT_TEST
    if (old->name) {
        n->name = g_strdup(old->name);
    }
#endif

    if (old->children) {
        n->children = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
                                            (GDestroyNotify)xs_node_unref);
        op->op_opaque2 = n->children;
        g_hash_table_foreach(old->children, copy_deleted_recurse, op);
    }
    if (old->perms) {
        n->perms = g_list_copy_deep(old->perms, do_perm_copy, NULL);
    }
    n->deleted_in_tx = true;
    /* If it gets resurrected we only fire a watch if it lost its content */
    if (old->content) {
        n->modified_in_tx = true;
    }
    op->new_nr_nodes--;
    return n;
}

static int xs_node_rm(XsNode **n, struct walk_op *op)
{
    bool this_inplace = op->inplace;

    if (op->tx_id != XBT_NULL) {
        /* It's not trivial to do inplace handling for this one */
        XsNode *old = *n;
        *n = xs_node_copy_deleted(old, op);
        xs_node_unref(old);
        return 0;
    }

    /* Fire watches for, and count, nodes in the subtree which get deleted */
    if ((*n)->children) {
        g_hash_table_foreach_remove((*n)->children, node_rm_recurse, op);
    }
    op->new_nr_nodes--;

    if (this_inplace) {
        xs_node_unref(*n);
    }
    *n = NULL;
    return 0;
}

static int xs_node_get_perms(XsNode **n, struct walk_op *op)
{
    GList **perms = op->op_opaque;

    assert(op->inplace);
    assert(*n);

    *perms = g_list_copy_deep((*n)->perms, do_perm_copy, NULL);
    return 0;
}

static void parse_perm(const char *perm, char *letter, unsigned int *dom_id)
{
    unsigned int n = sscanf(perm, "%c%u", letter, dom_id);

    assert(n == 2);
}

static bool can_access(unsigned int dom_id, GList *perms, const char *letters)
{
    unsigned int i, n;
    char perm_letter;
    unsigned int perm_dom_id;
    bool access;

    if (dom_id == 0) {
        return true;
    }

    n = g_list_length(perms);
    assert(n >= 1);

    /*
     * The dom_id of the first perm is the owner, and the owner always has
     * read-write access.
     */
    parse_perm(g_list_nth_data(perms, 0), &perm_letter, &perm_dom_id);
    if (dom_id == perm_dom_id) {
        return true;
    }

    /*
     * The letter of the first perm specified the default access for all other
     * domains.
     */
    access = !!strchr(letters, perm_letter);
    for (i = 1; i < n; i++) {
        parse_perm(g_list_nth_data(perms, i), &perm_letter, &perm_dom_id);
        if (dom_id != perm_dom_id) {
            continue;
        }
        access = !!strchr(letters, perm_letter);
    }

    return access;
}

static int xs_node_set_perms(XsNode **n, struct walk_op *op)
{
    GList *perms = op->op_opaque;

    if (op->dom_id) {
        unsigned int perm_dom_id;
        char perm_letter;

        /* A guest may not change permissions on nodes it does not own */
        if (!can_access(op->dom_id, (*n)->perms, "")) {
            return EPERM;
        }

        /* A guest may not change the owner of a node it owns. */
        parse_perm(perms->data, &perm_letter, &perm_dom_id);
        if (perm_dom_id != op->dom_id) {
            return EPERM;
        }

        if (g_list_length(perms) > XS_MAX_PERMS_PER_NODE) {
            return ENOSPC;
        }
    }

    /* We *are* the node to be written. Either this or a copy. */
    if (!op->inplace) {
        XsNode *old = *n;
        *n = xs_node_copy(old);
        xs_node_unref(old);
    }

    if ((*n)->perms) {
        g_list_free_full((*n)->perms, g_free);
    }
    (*n)->perms = g_list_copy_deep(perms, do_perm_copy, NULL);
    if (op->tx_id != XBT_NULL) {
        (*n)->modified_in_tx = true;
    }
    return 0;
}

/*
 * Passed a full reference in *n which it may free if it needs to COW.
 *
 * When changing the tree, the op->inplace flag indicates whether this
 * node may be modified in place (i.e. it and all its parents had a
 * refcount of one). If walking down the tree we find a node whose
 * refcount is higher, we must clear op->inplace and COW from there
 * down. Unless we are creating new nodes as scaffolding for a write
 * (which works like 'mkdir -p' does). In which case those newly
 * created nodes can (and must) be modified in place again.
 */
static int xs_node_walk(XsNode **n, struct walk_op *op)
{
    char *child_name = NULL;
    size_t namelen;
    XsNode *old = *n, *child = NULL;
    bool stole_child = false;
    bool this_inplace;
    XsWatch *watch;
    int err;

    namelen = strlen(op->path);
    watch = g_hash_table_lookup(op->s->watches, op->path);

    /* Is there a child, or do we hit the double-NUL termination? */
    if (op->path[namelen + 1]) {
        char *slash;
        child_name = op->path + namelen + 1;
        slash = strchr(child_name, '/');
        if (slash) {
            *slash = '\0';
        }
        op->path[namelen] = '/';
    }

    /* If we walk into a subtree which is shared, we must COW */
    if (op->mutating && old->ref != 1) {
        op->inplace = false;
    }

    if (!child_name) {
        const char *letters = op->mutating ? "wb" : "rb";

        if (!can_access(op->dom_id, old->perms, letters)) {
            err = EACCES;
            goto out;
        }

        /* This is the actual node on which the operation shall be performed */
        err = op->op_fn(n, op);
        if (!err) {
            fire_watches(op, true);
        }
        goto out;
    }

    /* op->inplace will be further modified during the recursion */
    this_inplace = op->inplace;

    if (old && old->children) {
        child = g_hash_table_lookup(old->children, child_name);
        /* This is a *weak* reference to 'child', owned by the hash table */
    }

    if (child) {
        if (child->deleted_in_tx) {
            assert(child->ref == 1);
            /* Cannot actually set child->deleted_in_tx = false until later */
        }
        xs_node_ref(child);
        /*
         * Now we own it too. But if we can modify inplace, that's going to
         * foil the check and force it to COW. We want to be the *only* owner
         * so that it can be modified in place, so remove it from the hash
         * table in that case. We'll add it (or its replacement) back later.
         */
        if (op->mutating && this_inplace) {
            g_hash_table_remove(old->children, child_name);
            stole_child = true;
        }
    } else if (op->create_dirs) {
        assert(op->mutating);

        if (!can_access(op->dom_id, old->perms, "wb")) {
            err = EACCES;
            goto out;
        }

        if (op->dom_id && op->new_nr_nodes >= XS_MAX_DOMAIN_NODES) {
            err = ENOSPC;
            goto out;
        }

        child = xs_node_create(child_name, old->perms);
        op->new_nr_nodes++;

        /*
         * If we're creating a new child, we can clearly modify it (and its
         * children) in place from here on down.
         */
        op->inplace = true;
    } else {
        err = ENOENT;
        goto out;
    }

    /*
     * If there's a watch on this node, add it to the list to be fired
     * (with the correct full pathname for the modified node) at the end.
     */
    if (watch) {
        op->watches = g_list_append(op->watches, watch);
    }

    /*
     * Except for the temporary child-stealing as noted, our node has not
     * changed yet. We don't yet know the overall operation will complete.
     */
    err = xs_node_walk(&child, op);

    if (watch) {
        op->watches = g_list_remove(op->watches, watch);
    }

    if (err || !op->mutating) {
        if (stole_child) {
            /* Put it back as it was. */
            g_hash_table_replace(old->children, g_strdup(child_name), child);
        } else {
            xs_node_unref(child);
        }
        goto out;
    }

    /*
     * Now we know the operation has completed successfully and we're on
     * the way back up. Make the change, substituting 'child' in the
     * node at our level.
     */
    if (!this_inplace) {
        *n = xs_node_copy(old);
        xs_node_unref(old);
    }

    /*
     * If we resurrected a deleted_in_tx node, we can mark it as no longer
     * deleted now that we know the overall operation has succeeded.
     */
    if (op->create_dirs && child && child->deleted_in_tx) {
        op->new_nr_nodes++;
        child->deleted_in_tx = false;
    }

    /*
     * The child may be NULL here, for a remove operation. Either way,
     * xs_node_add_child() will do the right thing and return a value
     * indicating whether it changed the parent's hash table or not.
     *
     * We bump the parent gencnt if it adds a child that we *didn't*
     * steal from it in the first place, or if child==NULL and was
     * thus removed (whether we stole it earlier and didn't put it
     * back, or xs_node_add_child() actually removed it now).
     */
    if ((xs_node_add_child(*n, child_name, child) && !stole_child) || !child) {
        (*n)->gencnt++;
    }

 out:
    op->path[namelen] = '\0';
    if (!namelen) {
        assert(!op->watches);
        /*
         * On completing the recursion back up the path walk and reaching the
         * top, assign the new node count if the operation was successful. If
         * the main tree was changed, bump its tx ID so that outstanding
         * transactions correctly fail. But don't bump it every time; only
         * if it makes a difference.
         */
        if (!err && op->mutating) {
            if (!op->in_transaction) {
                if (op->s->root_tx != op->s->last_tx) {
                    op->s->root_tx = next_tx(op->s);
                }
                op->s->nr_nodes = op->new_nr_nodes;
            } else {
                XsTransaction *tx = g_hash_table_lookup(op->s->transactions,
                                                        GINT_TO_POINTER(op->tx_id));
                assert(tx);
                tx->nr_nodes = op->new_nr_nodes;
            }
        }
    }
    return err;
}

static void append_directory_item(gpointer key, gpointer value,
                                  gpointer user_data)
{
    GList **items = user_data;

    *items = g_list_insert_sorted(*items, g_strdup(key), (GCompareFunc)strcmp);
}

/* Populates items with char * names which caller must free. */
static int xs_node_directory(XsNode **n, struct walk_op *op)
{
    GList **items = op->op_opaque;

    assert(op->inplace);
    assert(*n);

    if ((*n)->children) {
        g_hash_table_foreach((*n)->children, append_directory_item, items);
    }

    if (op->op_opaque2) {
        *(uint64_t *)op->op_opaque2 = (*n)->gencnt;
    }

    return 0;
}

static int validate_path(char *outpath, const char *userpath,
                         unsigned int dom_id)
{
    size_t i, pathlen = strlen(userpath);

    if (!pathlen || userpath[pathlen] == '/' || strstr(userpath, "//")) {
        return EINVAL;
    }
    for (i = 0; i < pathlen; i++) {
        if (!strchr(XS_VALID_CHARS, userpath[i])) {
            return EINVAL;
        }
    }
    if (userpath[0] == '/') {
        if (pathlen > XENSTORE_ABS_PATH_MAX) {
            return E2BIG;
        }
        memcpy(outpath, userpath, pathlen + 1);
    } else {
        if (pathlen > XENSTORE_REL_PATH_MAX) {
            return E2BIG;
        }
        snprintf(outpath, XENSTORE_ABS_PATH_MAX, "/local/domain/%u/%s", dom_id,
                 userpath);
    }
    return 0;
}


static int init_walk_op(XenstoreImplState *s, struct walk_op *op,
                        xs_transaction_t tx_id, unsigned int dom_id,
                        const char *path, XsNode ***rootp)
{
    int ret = validate_path(op->path, path, dom_id);
    if (ret) {
        return ret;
    }

    /*
     * We use *two* NUL terminators at the end of the path, as during the walk
     * we will temporarily turn each '/' into a NUL to allow us to use that
     * path element for the lookup.
     */
    op->path[strlen(op->path) + 1] = '\0';
    op->watches = NULL;
    op->path[0] = '\0';
    op->inplace = true;
    op->mutating = false;
    op->create_dirs = false;
    op->in_transaction = false;
    op->dom_id = dom_id;
    op->tx_id = tx_id;
    op->s = s;

    if (tx_id == XBT_NULL) {
        *rootp = &s->root;
        op->new_nr_nodes = s->nr_nodes;
    } else {
        XsTransaction *tx = g_hash_table_lookup(s->transactions,
                                                GINT_TO_POINTER(tx_id));
        if (!tx) {
            return ENOENT;
        }
        *rootp = &tx->root;
        op->new_nr_nodes = tx->nr_nodes;
        op->in_transaction = true;
    }

    return 0;
}

int xs_impl_read(XenstoreImplState *s, unsigned int dom_id,
                 xs_transaction_t tx_id, const char *path, GByteArray *data)
{
    /*
     * The data GByteArray shall exist, and will be freed by caller.
     * Just g_byte_array_append() to it.
     */
    struct walk_op op;
    XsNode **n;
    int ret;

    ret = init_walk_op(s, &op, tx_id, dom_id, path, &n);
    if (ret) {
        return ret;
    }
    op.op_fn = xs_node_get_content;
    op.op_opaque = data;
    return xs_node_walk(n, &op);
}

int xs_impl_write(XenstoreImplState *s, unsigned int dom_id,
                  xs_transaction_t tx_id, const char *path, GByteArray *data)
{
    /*
     * The data GByteArray shall exist, will be freed by caller. You are
     * free to use g_byte_array_steal() and keep the data. Or just ref it.
     */
    struct walk_op op;
    XsNode **n;
    int ret;

    ret = init_walk_op(s, &op, tx_id, dom_id, path, &n);
    if (ret) {
        return ret;
    }
    op.op_fn = xs_node_add_content;
    op.op_opaque = data;
    op.mutating = true;
    op.create_dirs = true;
    return xs_node_walk(n, &op);
}

int xs_impl_directory(XenstoreImplState *s, unsigned int dom_id,
                      xs_transaction_t tx_id, const char *path,
                      uint64_t *gencnt, GList **items)
{
    /*
     * The items are (char *) to be freed by caller. Although it's consumed
     * immediately so if you want to change it to (const char *) and keep
     * them, go ahead and change the caller.
     */
    struct walk_op op;
    XsNode **n;
    int ret;

    ret = init_walk_op(s, &op, tx_id, dom_id, path, &n);
    if (ret) {
        return ret;
    }
    op.op_fn = xs_node_directory;
    op.op_opaque = items;
    op.op_opaque2 = gencnt;
    return xs_node_walk(n, &op);
}

int xs_impl_transaction_start(XenstoreImplState *s, unsigned int dom_id,
                              xs_transaction_t *tx_id)
{
    XsTransaction *tx;

    if (*tx_id != XBT_NULL) {
        return EINVAL;
    }

    if (dom_id && s->nr_domu_transactions >= XS_MAX_TRANSACTIONS) {
        return ENOSPC;
    }

    tx = g_new0(XsTransaction, 1);

    tx->nr_nodes = s->nr_nodes;
    tx->tx_id = next_tx(s);
    tx->base_tx = s->root_tx;
    tx->root = xs_node_ref(s->root);
    tx->dom_id = dom_id;

    g_hash_table_insert(s->transactions, GINT_TO_POINTER(tx->tx_id), tx);
    if (dom_id) {
        s->nr_domu_transactions++;
    }
    *tx_id = tx->tx_id;
    return 0;
}

static gboolean tx_commit_walk(gpointer key, gpointer value,
                               gpointer user_data)
{
    struct walk_op *op = user_data;
    int path_len = strlen(op->path);
    int key_len = strlen(key);
    bool fire_parents = true;
    XsWatch *watch;
    XsNode *n = value;

    if (n->ref != 1) {
        return false;
    }

    if (n->deleted_in_tx) {
        /*
         * We fire watches on our parents if we are the *first* node
         * to be deleted (the topmost one). This matches the behaviour
         * when deleting in the live tree.
         */
        fire_parents = !op->deleted_in_tx;

        /* Only used on the way down so no need to clear it later */
        op->deleted_in_tx = true;
    }

    assert(key_len + path_len + 2 <= sizeof(op->path));
    op->path[path_len] = '/';
    memcpy(op->path + path_len + 1, key, key_len + 1);

    watch = g_hash_table_lookup(op->s->watches, op->path);
    if (watch) {
        op->watches = g_list_append(op->watches, watch);
    }

    if (n->children) {
        g_hash_table_foreach_remove(n->children, tx_commit_walk, op);
    }

    if (watch) {
        op->watches = g_list_remove(op->watches, watch);
    }

    /*
     * Don't fire watches if this node was only copied because a
     * descendent was changed. The modified_in_tx flag indicates the
     * ones which were really changed.
     */
    if (n->modified_in_tx || n->deleted_in_tx) {
        fire_watches(op, fire_parents);
        n->modified_in_tx = false;
    }
    op->path[path_len] = '\0';

    /* Deleted nodes really do get expunged when we commit */
    return n->deleted_in_tx;
}

static int transaction_commit(XenstoreImplState *s, XsTransaction *tx)
{
    struct walk_op op;
    XsNode **n;

    if (s->root_tx != tx->base_tx) {
        return EAGAIN;
    }
    xs_node_unref(s->root);
    s->root = tx->root;
    tx->root = NULL;
    s->root_tx = tx->tx_id;
    s->nr_nodes = tx->nr_nodes;

    init_walk_op(s, &op, XBT_NULL, tx->dom_id, "/", &n);
    op.deleted_in_tx = false;
    op.mutating = true;

    /*
     * Walk the new root and fire watches on any node which has a
     * refcount of one (which is therefore unique to this transaction).
     */
    if (s->root->children) {
        g_hash_table_foreach_remove(s->root->children, tx_commit_walk, &op);
    }

    return 0;
}

int xs_impl_transaction_end(XenstoreImplState *s, unsigned int dom_id,
                            xs_transaction_t tx_id, bool commit)
{
    int ret = 0;
    XsTransaction *tx = g_hash_table_lookup(s->transactions,
                                            GINT_TO_POINTER(tx_id));

    if (!tx || tx->dom_id != dom_id) {
        return ENOENT;
    }

    if (commit) {
        ret = transaction_commit(s, tx);
    }

    g_hash_table_remove(s->transactions, GINT_TO_POINTER(tx_id));
    if (dom_id) {
        assert(s->nr_domu_transactions);
        s->nr_domu_transactions--;
    }
    return ret;
}

int xs_impl_rm(XenstoreImplState *s, unsigned int dom_id,
               xs_transaction_t tx_id, const char *path)
{
    struct walk_op op;
    XsNode **n;
    int ret;

    ret = init_walk_op(s, &op, tx_id, dom_id, path, &n);
    if (ret) {
        return ret;
    }
    op.op_fn = xs_node_rm;
    op.mutating = true;
    return xs_node_walk(n, &op);
}

int xs_impl_get_perms(XenstoreImplState *s, unsigned int dom_id,
                      xs_transaction_t tx_id, const char *path, GList **perms)
{
    struct walk_op op;
    XsNode **n;
    int ret;

    ret = init_walk_op(s, &op, tx_id, dom_id, path, &n);
    if (ret) {
        return ret;
    }
    op.op_fn = xs_node_get_perms;
    op.op_opaque = perms;
    return xs_node_walk(n, &op);
}

static void is_valid_perm(gpointer data, gpointer user_data)
{
    char *perm = data;
    bool *valid = user_data;
    char letter;
    unsigned int dom_id;

    if (!*valid) {
        return;
    }

    if (sscanf(perm, "%c%u", &letter, &dom_id) != 2) {
        *valid = false;
        return;
    }

    switch (letter) {
    case 'n':
    case 'r':
    case 'w':
    case 'b':
        break;

    default:
        *valid = false;
        break;
    }
}

int xs_impl_set_perms(XenstoreImplState *s, unsigned int dom_id,
                      xs_transaction_t tx_id, const char *path, GList *perms)
{
    struct walk_op op;
    XsNode **n;
    bool valid = true;
    int ret;

    if (!g_list_length(perms)) {
        return EINVAL;
    }

    g_list_foreach(perms, is_valid_perm, &valid);
    if (!valid) {
        return EINVAL;
    }

    ret = init_walk_op(s, &op, tx_id, dom_id, path, &n);
    if (ret) {
        return ret;
    }
    op.op_fn = xs_node_set_perms;
    op.op_opaque = perms;
    op.mutating = true;
    return xs_node_walk(n, &op);
}

static int do_xs_impl_watch(XenstoreImplState *s, unsigned int dom_id,
                            const char *path, const char *token,
                            xs_impl_watch_fn fn, void *opaque)

{
    char abspath[XENSTORE_ABS_PATH_MAX + 1];
    XsWatch *w, *l;
    int ret;

    ret = validate_path(abspath, path, dom_id);
    if (ret) {
        return ret;
    }

    /* Check for duplicates */
    l = w = g_hash_table_lookup(s->watches, abspath);
    while (w) {
        if (!g_strcmp0(token, w->token) &&  opaque == w->cb_opaque &&
            fn == w->cb && dom_id == w->dom_id) {
            return EEXIST;
        }
        w = w->next;
    }

    if (dom_id && s->nr_domu_watches >= XS_MAX_WATCHES) {
        return E2BIG;
    }

    w = g_new0(XsWatch, 1);
    w->token = g_strdup(token);
    w->cb = fn;
    w->cb_opaque = opaque;
    w->dom_id = dom_id;
    w->rel_prefix = strlen(abspath) - strlen(path);

    /* l was looked up above when checking for duplicates */
    if (l) {
        w->next = l->next;
        l->next = w;
    } else {
        g_hash_table_insert(s->watches, g_strdup(abspath), w);
    }
    if (dom_id) {
        s->nr_domu_watches++;
    }

    return 0;
}

int xs_impl_watch(XenstoreImplState *s, unsigned int dom_id, const char *path,
                  const char *token, xs_impl_watch_fn fn, void *opaque)
{
    int ret = do_xs_impl_watch(s, dom_id, path, token, fn, opaque);

    if (!ret) {
        /* A new watch should fire immediately */
        fn(opaque, path, token);
    }

    return ret;
}

static XsWatch *free_watch(XenstoreImplState *s, XsWatch *w)
{
    XsWatch *next = w->next;

    if (w->dom_id) {
        assert(s->nr_domu_watches);
        s->nr_domu_watches--;
    }

    g_free(w->token);
    g_free(w);

    return next;
}

int xs_impl_unwatch(XenstoreImplState *s, unsigned int dom_id,
                    const char *path, const char *token,
                    xs_impl_watch_fn fn, void *opaque)
{
    char abspath[XENSTORE_ABS_PATH_MAX + 1];
    XsWatch *w, **l;
    int ret;

    ret = validate_path(abspath, path, dom_id);
    if (ret) {
        return ret;
    }

    w = g_hash_table_lookup(s->watches, abspath);
    if (!w) {
        return ENOENT;
    }

    /*
     * The hash table contains the first element of a list of
     * watches. Removing the first element in the list is a
     * special case because we have to update the hash table to
     * point to the next (or remove it if there's nothing left).
     */
    if (!g_strcmp0(token, w->token) && fn == w->cb && opaque == w->cb_opaque &&
        dom_id == w->dom_id) {
        if (w->next) {
            /* Insert the previous 'next' into the hash table */
            g_hash_table_insert(s->watches, g_strdup(abspath), w->next);
        } else {
            /* Nothing left; remove from hash table */
            g_hash_table_remove(s->watches, abspath);
        }
        free_watch(s, w);
        return 0;
    }

    /*
     * We're all done messing with the hash table because the element
     * it points to has survived the cull. Now it's just a simple
     * linked list removal operation.
     */
    for (l = &w->next; *l; l = &w->next) {
        w = *l;

        if (!g_strcmp0(token, w->token) && fn == w->cb &&
            opaque != w->cb_opaque && dom_id == w->dom_id) {
            *l = free_watch(s, w);
            return 0;
        }
    }

    return ENOENT;
}

int xs_impl_reset_watches(XenstoreImplState *s, unsigned int dom_id)
{
    char **watch_paths;
    guint nr_watch_paths;
    guint i;

    watch_paths = (char **)g_hash_table_get_keys_as_array(s->watches,
                                                          &nr_watch_paths);

    for (i = 0; i < nr_watch_paths; i++) {
        XsWatch *w1 = g_hash_table_lookup(s->watches, watch_paths[i]);
        XsWatch *w2, *w, **l;

        /*
         * w1 is the original list. The hash table has this pointer.
         * w2 is the head of our newly-filtered list.
         * w and l are temporary for processing. w is somewhat redundant
         * with *l but makes my eyes bleed less.
         */

        w = w2 = w1;
        l = &w;
        while (w) {
            if (w->dom_id == dom_id) {
                /* If we're freeing the head of the list, bump w2 */
                if (w2 == w) {
                    w2 = w->next;
                }
                *l = free_watch(s, w);
            } else {
                l = &w->next;
            }
            w = *l;
        }
        /*
         * If the head of the list survived the cull, we don't need to
         * touch the hash table and we're done with this path. Else...
         */
        if (w1 != w2) {
            g_hash_table_steal(s->watches, watch_paths[i]);

            /*
             * It was already freed. (Don't worry, this whole thing is
             * single-threaded and nobody saw it in the meantime). And
             * having *stolen* it, we now own the watch_paths[i] string
             * so if we don't give it back to the hash table, we need
             * to free it.
             */
            if (w2) {
                g_hash_table_insert(s->watches, watch_paths[i], w2);
            } else {
                g_free(watch_paths[i]);
            }
        }
    }
    g_free(watch_paths);
    return 0;
}

static void xs_tx_free(void *_tx)
{
    XsTransaction *tx = _tx;
    if (tx->root) {
        xs_node_unref(tx->root);
    }
    g_free(tx);
}

XenstoreImplState *xs_impl_create(unsigned int dom_id)
{
    XenstoreImplState *s = g_new0(XenstoreImplState, 1);
    GList *perms;

    s->watches = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
    s->transactions = g_hash_table_new_full(g_direct_hash, g_direct_equal,
                                            NULL, xs_tx_free);

    perms = g_list_append(NULL, xs_perm_as_string(XS_PERM_NONE, 0));
    s->root = xs_node_create("/", perms);
    g_list_free_full(perms, g_free);
    s->nr_nodes = 1;

    s->root_tx = s->last_tx = 1;
    return s;
}


static void clear_serialized_tx(gpointer key, gpointer value, gpointer opaque)
{
    XsNode *n = value;

    n->serialized_tx = XBT_NULL;
    if (n->children) {
        g_hash_table_foreach(n->children, clear_serialized_tx, NULL);
    }
}

static void clear_tx_serialized_tx(gpointer key, gpointer value,
                                   gpointer opaque)
{
    XsTransaction *t = value;

    clear_serialized_tx(NULL, t->root, NULL);
}

static void write_be32(GByteArray *save, uint32_t val)
{
    uint32_t be = htonl(val);
    g_byte_array_append(save, (void *)&be, sizeof(be));
}


struct save_state {
    GByteArray *bytes;
    unsigned int tx_id;
};

#define MODIFIED_IN_TX  (1U << 0)
#define DELETED_IN_TX   (1U << 1)
#define NODE_REF        (1U << 2)

static void save_node(gpointer key, gpointer value, gpointer opaque)
{
    struct save_state *ss = opaque;
    XsNode *n = value;
    char *name = key;
    uint8_t flag = 0;

    /* Child nodes (i.e. anything but the root) have a name */
    if (name) {
        g_byte_array_append(ss->bytes, key, strlen(key) + 1);
    }

    /*
     * If we already wrote this node, refer to the previous copy.
     * There's no rename/move in XenStore, so all we need to find
     * it is the tx_id of the transation in which it exists. Which
     * may be the root tx.
     */
    if (n->serialized_tx != XBT_NULL) {
        flag = NODE_REF;
        g_byte_array_append(ss->bytes, &flag, 1);
        write_be32(ss->bytes, n->serialized_tx);
    } else {
        GList *l;
        n->serialized_tx = ss->tx_id;

        if (n->modified_in_tx) {
            flag |= MODIFIED_IN_TX;
        }
        if (n->deleted_in_tx) {
            flag |= DELETED_IN_TX;
        }
        g_byte_array_append(ss->bytes, &flag, 1);

        if (n->content) {
            write_be32(ss->bytes, n->content->len);
            g_byte_array_append(ss->bytes, n->content->data, n->content->len);
        } else {
            write_be32(ss->bytes, 0);
        }

        for (l = n->perms; l; l = l->next) {
            g_byte_array_append(ss->bytes, l->data, strlen(l->data) + 1);
        }
        /* NUL termination after perms */
        g_byte_array_append(ss->bytes, (void *)"", 1);

        if (n->children) {
            g_hash_table_foreach(n->children, save_node, ss);
        }
        /* NUL termination after children (child name is NUL) */
        g_byte_array_append(ss->bytes, (void *)"", 1);
    }
}

static void save_tree(struct save_state *ss, uint32_t tx_id, XsNode *root)
{
    write_be32(ss->bytes, tx_id);
    ss->tx_id = tx_id;
    save_node(NULL, root, ss);
}

static void save_tx(gpointer key, gpointer value, gpointer opaque)
{
    uint32_t tx_id = GPOINTER_TO_INT(key);
    struct save_state *ss = opaque;
    XsTransaction *n = value;

    write_be32(ss->bytes, n->base_tx);
    write_be32(ss->bytes, n->dom_id);

    save_tree(ss, tx_id, n->root);
}

static void save_watch(gpointer key, gpointer value, gpointer opaque)
{
    struct save_state *ss = opaque;
    XsWatch *w = value;

    /* We only save the *guest* watches. */
    if (w->dom_id) {
        gpointer relpath = key + w->rel_prefix;
        g_byte_array_append(ss->bytes, relpath, strlen(relpath) + 1);
        g_byte_array_append(ss->bytes, (void *)w->token, strlen(w->token) + 1);
    }
}

GByteArray *xs_impl_serialize(XenstoreImplState *s)
{
    struct save_state ss;

    ss.bytes = g_byte_array_new();

    /*
     * node = flags [ real_node / node_ref ]
     *   flags = uint8_t (MODIFIED_IN_TX | DELETED_IN_TX | NODE_REF)
     *   node_ref = tx_id (in which the original version of this node exists)
     *   real_node = content perms child* NUL
     *     content = len data
     *       len = uint32_t
     *       data = uint8_t{len}
     *     perms = perm* NUL
     *       perm = asciiz
     *   child = name node
     *     name = asciiz
     *
     * tree = tx_id node
     *   tx_id = uint32_t
     *
     * transaction = base_tx_id dom_id tree
     *   base_tx_id = uint32_t
     *   dom_id = uint32_t
     *
     * tx_list = tree transaction* XBT_NULL
     *
     * watch = path token
     *   path = asciiz
     *   token = asciiz
     *
     * watch_list = watch* NUL
     *
     * xs_serialize_stream = last_tx tx_list watch_list
     *   last_tx = uint32_t
     */

    /* Clear serialized_tx in every node. */
    if (s->serialized) {
        clear_serialized_tx(NULL, s->root, NULL);
        g_hash_table_foreach(s->transactions, clear_tx_serialized_tx, NULL);
    }

    s->serialized = true;

    write_be32(ss.bytes, s->last_tx);
    save_tree(&ss, s->root_tx, s->root);
    g_hash_table_foreach(s->transactions, save_tx, &ss);

    write_be32(ss.bytes, XBT_NULL);

    g_hash_table_foreach(s->watches, save_watch, &ss);
    g_byte_array_append(ss.bytes, (void *)"", 1);

    return ss.bytes;
}

struct unsave_state {
    char path[XENSTORE_ABS_PATH_MAX + 1];
    XenstoreImplState *s;
    GByteArray *bytes;
    uint8_t *d;
    size_t l;
    bool root_walk;
};

static int consume_be32(struct unsave_state *us, unsigned int *val)
{
    uint32_t d;

    if (us->l < sizeof(d)) {
        return -EINVAL;
    }
    memcpy(&d, us->d, sizeof(d));
    *val = ntohl(d);
    us->d += sizeof(d);
    us->l -= sizeof(d);
    return 0;
}

static int consume_string(struct unsave_state *us, char **str, size_t *len)
{
    size_t l;

    if (!us->l) {
        return -EINVAL;
    }

    l = strnlen((void *)us->d, us->l);
    if (l == us->l) {
        return -EINVAL;
    }

    if (str) {
        *str = (void *)us->d;
    }
    if (len) {
        *len = l;
    }

    us->d += l + 1;
    us->l -= l + 1;
    return 0;
}

static XsNode *lookup_node(XsNode *n, char *path)
{
    char *slash = strchr(path, '/');
    XsNode *child;

    if (path[0] == '\0') {
        return n;
    }

    if (slash) {
        *slash = '\0';
    }

    if (!n->children) {
        return NULL;
    }
    child = g_hash_table_lookup(n->children, path);
    if (!slash) {
        return child;
    }

    *slash = '/';
    if (!child) {
        return NULL;
    }
    return lookup_node(child, slash + 1);
}

static XsNode *lookup_tx_node(struct unsave_state *us, unsigned int tx_id)
{
    XsTransaction *t;
    if (tx_id == us->s->root_tx) {
        return lookup_node(us->s->root, us->path + 1);
    }

    t = g_hash_table_lookup(us->s->transactions, GINT_TO_POINTER(tx_id));
    if (!t) {
        return NULL;
    }
    g_assert(t->root);
    return lookup_node(t->root, us->path + 1);
}

static void count_child_nodes(gpointer key, gpointer value, gpointer user_data)
{
    unsigned int *nr_nodes = user_data;
    XsNode *n = value;

    (*nr_nodes)++;

    if (n->children) {
        g_hash_table_foreach(n->children, count_child_nodes, nr_nodes);
    }
}

static int consume_node(struct unsave_state *us, XsNode **nodep,
                        unsigned int *nr_nodes)
{
    XsNode *n = NULL;
    uint8_t flags;
    int ret;

    if (us->l < 1) {
        return -EINVAL;
    }
    flags = us->d[0];
    us->d++;
    us->l--;

    if (flags == NODE_REF) {
        unsigned int tx;

        ret = consume_be32(us, &tx);
        if (ret) {
            return ret;
        }

        n = lookup_tx_node(us, tx);
        if (!n) {
            return -EINVAL;
        }
        n->ref++;
        if (n->children) {
            g_hash_table_foreach(n->children, count_child_nodes, nr_nodes);
        }
    } else {
        uint32_t datalen;

        if (flags & ~(DELETED_IN_TX | MODIFIED_IN_TX)) {
            return -EINVAL;
        }
        n = xs_node_new();

        if (flags & DELETED_IN_TX) {
            n->deleted_in_tx = true;
        }
        if (flags & MODIFIED_IN_TX) {
            n->modified_in_tx = true;
        }
        ret = consume_be32(us, &datalen);
        if (ret) {
            xs_node_unref(n);
            return -EINVAL;
        }
        if (datalen) {
            if (datalen > us->l) {
                xs_node_unref(n);
                return -EINVAL;
            }

            GByteArray *node_data = g_byte_array_new();
            g_byte_array_append(node_data, us->d, datalen);
            us->d += datalen;
            us->l -= datalen;
            n->content = node_data;

            if (us->root_walk) {
                n->modified_in_tx = true;
            }
        }
        while (1) {
            char *perm = NULL;
            size_t permlen = 0;

            ret = consume_string(us, &perm, &permlen);
            if (ret) {
                xs_node_unref(n);
                return ret;
            }

            if (!permlen) {
                break;
            }

            n->perms = g_list_append(n->perms, g_strdup(perm));
        }

        /* Now children */
        while (1) {
            size_t childlen;
            char *childname;
            char *pathend;
            XsNode *child = NULL;

            ret = consume_string(us, &childname, &childlen);
            if (ret) {
                xs_node_unref(n);
                return ret;
            }

            if (!childlen) {
                break;
            }

            pathend = us->path + strlen(us->path);
            strncat(us->path, "/", sizeof(us->path) - 1);
            strncat(us->path, childname, sizeof(us->path) - 1);

            ret = consume_node(us, &child, nr_nodes);
            *pathend = '\0';
            if (ret) {
                xs_node_unref(n);
                return ret;
            }
            g_assert(child);
            xs_node_add_child(n, childname, child);
        }

        /*
         * If the node has no data and no children we still want to fire
         * a watch on it.
         */
        if (us->root_walk && !n->children) {
            n->modified_in_tx = true;
        }
    }

    if (!n->deleted_in_tx) {
        (*nr_nodes)++;
    }

    *nodep = n;
    return 0;
}

static int consume_tree(struct unsave_state *us, XsTransaction *t)
{
    int ret;

    ret = consume_be32(us, &t->tx_id);
    if (ret) {
        return ret;
    }

    if (t->tx_id > us->s->last_tx) {
        return -EINVAL;
    }

    us->path[0] = '\0';

    return consume_node(us, &t->root, &t->nr_nodes);
}

int xs_impl_deserialize(XenstoreImplState *s, GByteArray *bytes,
                        unsigned int dom_id, xs_impl_watch_fn watch_fn,
                        void *watch_opaque)
{
    struct unsave_state us;
    XsTransaction base_t = { 0 };
    int ret;

    us.s = s;
    us.bytes = bytes;
    us.d = bytes->data;
    us.l = bytes->len;

    xs_impl_reset_watches(s, dom_id);
    g_hash_table_remove_all(s->transactions);

    xs_node_unref(s->root);
    s->root = NULL;
    s->root_tx = s->last_tx = XBT_NULL;

    ret = consume_be32(&us, &s->last_tx);
    if (ret) {
        return ret;
    }

    /*
     * Consume the base tree into a transaction so that watches can be
     * fired as we commit it. By setting us.root_walk we cause the nodes
     * to be marked as 'modified_in_tx' as they are created, so that the
     * watches are triggered on them.
     */
    base_t.dom_id = dom_id;
    base_t.base_tx = XBT_NULL;
    us.root_walk = true;
    ret = consume_tree(&us, &base_t);
    if (ret) {
        return ret;
    }
    us.root_walk = false;

    /*
     * Commit the transaction now while the refcount on all nodes is 1.
     * Note that we haven't yet reinstated the *guest* watches but that's
     * OK because we don't want the guest to see any changes. Even any
     * backend nodes which get recreated should be *precisely* as they
     * were before the migration. Back ends may have been instantiated
     * already, and will see the frontend magically blink into existence
     * now (well, from the aio_bh which fires the watches). It's their
     * responsibility to rebuild everything precisely as it was before.
     */
    ret = transaction_commit(s, &base_t);
    if (ret) {
        return ret;
    }

    while (1) {
        unsigned int base_tx;
        XsTransaction *t;

        ret = consume_be32(&us, &base_tx);
        if (ret) {
            return ret;
        }
        if (base_tx == XBT_NULL) {
            break;
        }

        t = g_new0(XsTransaction, 1);
        t->base_tx = base_tx;

        ret = consume_be32(&us, &t->dom_id);
        if (!ret) {
            ret = consume_tree(&us, t);
        }
        if (ret) {
            g_free(t);
            return ret;
        }
        g_assert(t->root);
        if (t->dom_id) {
            s->nr_domu_transactions++;
        }
        g_hash_table_insert(s->transactions, GINT_TO_POINTER(t->tx_id), t);
    }

    while (1) {
        char *path, *token;
        size_t pathlen, toklen;

        ret = consume_string(&us, &path, &pathlen);
        if (ret) {
            return ret;
        }
        if (!pathlen) {
            break;
        }

        ret = consume_string(&us, &token, &toklen);
        if (ret) {
            return ret;
        }

        if (!watch_fn) {
            continue;
        }

        ret = do_xs_impl_watch(s, dom_id, path, token, watch_fn, watch_opaque);
        if (ret) {
            return ret;
        }
    }

    if (us.l) {
        return -EINVAL;
    }

    return 0;
}
