/*
 * QEMU Xen emulation: Shared/overlay pages support
 *
 * Copyright © 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Authors: David Woodhouse <dwmw2@infradead.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 "qemu/host-utils.h"
#include "qemu/module.h"
#include "qemu/main-loop.h"
#include "qemu/cutils.h"
#include "qemu/error-report.h"
#include "qapi/error.h"
#include "qom/object.h"
#include "migration/vmstate.h"

#include "hw/sysbus.h"
#include "hw/xen/xen.h"
#include "hw/xen/xen_backend_ops.h"
#include "xen_overlay.h"
#include "xen_evtchn.h"
#include "xen_xenstore.h"

#include "sysemu/kvm.h"
#include "sysemu/kvm_xen.h"

#include "trace.h"

#include "xenstore_impl.h"

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

#define TYPE_XEN_XENSTORE "xen-xenstore"
OBJECT_DECLARE_SIMPLE_TYPE(XenXenstoreState, XEN_XENSTORE)

#define ENTRIES_PER_FRAME_V1 (XEN_PAGE_SIZE / sizeof(grant_entry_v1_t))
#define ENTRIES_PER_FRAME_V2 (XEN_PAGE_SIZE / sizeof(grant_entry_v2_t))

#define XENSTORE_HEADER_SIZE ((unsigned int)sizeof(struct xsd_sockmsg))

struct XenXenstoreState {
    /*< private >*/
    SysBusDevice busdev;
    /*< public >*/

    XenstoreImplState *impl;
    GList *watch_events; /* for the guest */

    MemoryRegion xenstore_page;
    struct xenstore_domain_interface *xs;
    uint8_t req_data[XENSTORE_HEADER_SIZE + XENSTORE_PAYLOAD_MAX];
    uint8_t rsp_data[XENSTORE_HEADER_SIZE + XENSTORE_PAYLOAD_MAX];
    uint32_t req_offset;
    uint32_t rsp_offset;
    bool rsp_pending;
    bool fatal_error;

    evtchn_port_t guest_port;
    evtchn_port_t be_port;
    struct xenevtchn_handle *eh;

    uint8_t *impl_state;
    uint32_t impl_state_size;

    struct xengntdev_handle *gt;
    void *granted_xs;
};

struct XenXenstoreState *xen_xenstore_singleton;

static void xen_xenstore_event(void *opaque);
static void fire_watch_cb(void *opaque, const char *path, const char *token);

static struct xenstore_backend_ops emu_xenstore_backend_ops;

static void G_GNUC_PRINTF (4, 5) relpath_printf(XenXenstoreState *s,
                                                GList *perms,
                                                const char *relpath,
                                                const char *fmt, ...)
{
    gchar *abspath;
    gchar *value;
    va_list args;
    GByteArray *data;
    int err;

    abspath = g_strdup_printf("/local/domain/%u/%s", xen_domid, relpath);
    va_start(args, fmt);
    value = g_strdup_vprintf(fmt, args);
    va_end(args);

    data = g_byte_array_new_take((void *)value, strlen(value));

    err = xs_impl_write(s->impl, DOMID_QEMU, XBT_NULL, abspath, data);
    assert(!err);

    g_byte_array_unref(data);

    err = xs_impl_set_perms(s->impl, DOMID_QEMU, XBT_NULL, abspath, perms);
    assert(!err);

    g_free(abspath);
}

static void xen_xenstore_realize(DeviceState *dev, Error **errp)
{
    XenXenstoreState *s = XEN_XENSTORE(dev);
    GList *perms;

    if (xen_mode != XEN_EMULATE) {
        error_setg(errp, "Xen xenstore support is for Xen emulation");
        return;
    }
    memory_region_init_ram(&s->xenstore_page, OBJECT(dev), "xen:xenstore_page",
                           XEN_PAGE_SIZE, &error_abort);
    memory_region_set_enabled(&s->xenstore_page, true);
    s->xs = memory_region_get_ram_ptr(&s->xenstore_page);
    memset(s->xs, 0, XEN_PAGE_SIZE);

    /* We can't map it this early as KVM isn't ready */
    xen_xenstore_singleton = s;

    s->eh = xen_be_evtchn_open();
    if (!s->eh) {
        error_setg(errp, "Xenstore evtchn port init failed");
        return;
    }
    aio_set_fd_handler(qemu_get_aio_context(), xen_be_evtchn_fd(s->eh), true,
                       xen_xenstore_event, NULL, NULL, NULL, s);

    s->impl = xs_impl_create(xen_domid);

    /* Populate the default nodes */

    /* Nodes owned by 'dom0' but readable by the guest */
    perms = g_list_append(NULL, xs_perm_as_string(XS_PERM_NONE, DOMID_QEMU));
    perms = g_list_append(perms, xs_perm_as_string(XS_PERM_READ, xen_domid));

    relpath_printf(s, perms, "", "%s", "");

    relpath_printf(s, perms, "domid", "%u", xen_domid);

    relpath_printf(s, perms, "control/platform-feature-xs_reset_watches", "%u", 1);
    relpath_printf(s, perms, "control/platform-feature-multiprocessor-suspend", "%u", 1);

    relpath_printf(s, perms, "platform/acpi", "%u", 1);
    relpath_printf(s, perms, "platform/acpi_s3", "%u", 1);
    relpath_printf(s, perms, "platform/acpi_s4", "%u", 1);
    relpath_printf(s, perms, "platform/acpi_laptop_slate", "%u", 0);

    g_list_free_full(perms, g_free);

    /* Nodes owned by the guest */
    perms = g_list_append(NULL, xs_perm_as_string(XS_PERM_NONE, xen_domid));

    relpath_printf(s, perms, "attr", "%s", "");

    relpath_printf(s, perms, "control/shutdown", "%s", "");
    relpath_printf(s, perms, "control/feature-poweroff", "%u", 1);
    relpath_printf(s, perms, "control/feature-reboot", "%u", 1);
    relpath_printf(s, perms, "control/feature-suspend", "%u", 1);
    relpath_printf(s, perms, "control/feature-s3", "%u", 1);
    relpath_printf(s, perms, "control/feature-s4", "%u", 1);

    relpath_printf(s, perms, "data", "%s", "");
    relpath_printf(s, perms, "device", "%s", "");
    relpath_printf(s, perms, "drivers", "%s", "");
    relpath_printf(s, perms, "error", "%s", "");
    relpath_printf(s, perms, "feature", "%s", "");

    g_list_free_full(perms, g_free);

    xen_xenstore_ops = &emu_xenstore_backend_ops;
}

static bool xen_xenstore_is_needed(void *opaque)
{
    return xen_mode == XEN_EMULATE;
}

static int xen_xenstore_pre_save(void *opaque)
{
    XenXenstoreState *s = opaque;
    GByteArray *save;

    if (s->eh) {
        s->guest_port = xen_be_evtchn_get_guest_port(s->eh);
    }

    g_free(s->impl_state);
    save = xs_impl_serialize(s->impl);
    s->impl_state = save->data;
    s->impl_state_size = save->len;
    g_byte_array_free(save, false);

    return 0;
}

static int xen_xenstore_post_load(void *opaque, int ver)
{
    XenXenstoreState *s = opaque;
    GByteArray *save;
    int ret;

    /*
     * As qemu/dom0, rebind to the guest's port. The Windows drivers may
     * unbind the XenStore evtchn and rebind to it, having obtained the
     * "remote" port through EVTCHNOP_status. In the case that migration
     * occurs while it's unbound, the "remote" port needs to be the same
     * as before so that the guest can find it, but should remain unbound.
     */
    if (s->guest_port) {
        int be_port = xen_be_evtchn_bind_interdomain(s->eh, xen_domid,
                                                     s->guest_port);
        if (be_port < 0) {
            return be_port;
        }
        s->be_port = be_port;
    }

    save = g_byte_array_new_take(s->impl_state, s->impl_state_size);
    s->impl_state = NULL;
    s->impl_state_size = 0;

    ret = xs_impl_deserialize(s->impl, save, xen_domid, fire_watch_cb, s);
    return ret;
}

static const VMStateDescription xen_xenstore_vmstate = {
    .name = "xen_xenstore",
    .unmigratable = 1, /* The PV back ends don't migrate yet */
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = xen_xenstore_is_needed,
    .pre_save = xen_xenstore_pre_save,
    .post_load = xen_xenstore_post_load,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8_ARRAY(req_data, XenXenstoreState,
                            sizeof_field(XenXenstoreState, req_data)),
        VMSTATE_UINT8_ARRAY(rsp_data, XenXenstoreState,
                            sizeof_field(XenXenstoreState, rsp_data)),
        VMSTATE_UINT32(req_offset, XenXenstoreState),
        VMSTATE_UINT32(rsp_offset, XenXenstoreState),
        VMSTATE_BOOL(rsp_pending, XenXenstoreState),
        VMSTATE_UINT32(guest_port, XenXenstoreState),
        VMSTATE_BOOL(fatal_error, XenXenstoreState),
        VMSTATE_UINT32(impl_state_size, XenXenstoreState),
        VMSTATE_VARRAY_UINT32_ALLOC(impl_state, XenXenstoreState,
                                    impl_state_size, 0,
                                    vmstate_info_uint8, uint8_t),
        VMSTATE_END_OF_LIST()
    }
};

static void xen_xenstore_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = xen_xenstore_realize;
    dc->vmsd = &xen_xenstore_vmstate;
}

static const TypeInfo xen_xenstore_info = {
    .name          = TYPE_XEN_XENSTORE,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(XenXenstoreState),
    .class_init    = xen_xenstore_class_init,
};

void xen_xenstore_create(void)
{
    DeviceState *dev = sysbus_create_simple(TYPE_XEN_XENSTORE, -1, NULL);

    xen_xenstore_singleton = XEN_XENSTORE(dev);

    /*
     * Defer the init (xen_xenstore_reset()) until KVM is set up and the
     * overlay page can be mapped.
     */
}

static void xen_xenstore_register_types(void)
{
    type_register_static(&xen_xenstore_info);
}

type_init(xen_xenstore_register_types)

uint16_t xen_xenstore_get_port(void)
{
    XenXenstoreState *s = xen_xenstore_singleton;
    if (!s) {
        return 0;
    }
    return s->guest_port;
}

static bool req_pending(XenXenstoreState *s)
{
    struct xsd_sockmsg *req = (struct xsd_sockmsg *)s->req_data;

    return s->req_offset == XENSTORE_HEADER_SIZE + req->len;
}

static void reset_req(XenXenstoreState *s)
{
    memset(s->req_data, 0, sizeof(s->req_data));
    s->req_offset = 0;
}

static void reset_rsp(XenXenstoreState *s)
{
    s->rsp_pending = false;

    memset(s->rsp_data, 0, sizeof(s->rsp_data));
    s->rsp_offset = 0;
}

static void xs_error(XenXenstoreState *s, unsigned int id,
                     xs_transaction_t tx_id, int errnum)
{
    struct xsd_sockmsg *rsp = (struct xsd_sockmsg *)s->rsp_data;
    const char *errstr = NULL;

    for (unsigned int i = 0; i < ARRAY_SIZE(xsd_errors); i++) {
        struct xsd_errors *xsd_error = &xsd_errors[i];

        if (xsd_error->errnum == errnum) {
            errstr = xsd_error->errstring;
            break;
        }
    }
    assert(errstr);

    trace_xenstore_error(id, tx_id, errstr);

    rsp->type = XS_ERROR;
    rsp->req_id = id;
    rsp->tx_id = tx_id;
    rsp->len = (uint32_t)strlen(errstr) + 1;

    memcpy(&rsp[1], errstr, rsp->len);
}

static void xs_ok(XenXenstoreState *s, unsigned int type, unsigned int req_id,
                  xs_transaction_t tx_id)
{
    struct xsd_sockmsg *rsp = (struct xsd_sockmsg *)s->rsp_data;
    const char *okstr = "OK";

    rsp->type = type;
    rsp->req_id = req_id;
    rsp->tx_id = tx_id;
    rsp->len = (uint32_t)strlen(okstr) + 1;

    memcpy(&rsp[1], okstr, rsp->len);
}

/*
 * The correct request and response formats are documented in xen.git:
 * docs/misc/xenstore.txt. A summary is given below for convenience.
 * The '|' symbol represents a NUL character.
 *
 * ---------- Database read, write and permissions operations ----------
 *
 * READ                    <path>|                 <value|>
 * WRITE                   <path>|<value|>
 *         Store and read the octet string <value> at <path>.
 *         WRITE creates any missing parent paths, with empty values.
 *
 * MKDIR                   <path>|
 *         Ensures that the <path> exists, by necessary by creating
 *         it and any missing parents with empty values.  If <path>
 *         or any parent already exists, its value is left unchanged.
 *
 * RM                      <path>|
 *         Ensures that the <path> does not exist, by deleting
 *         it and all of its children.  It is not an error if <path> does
 *         not exist, but it _is_ an error if <path>'s immediate parent
 *         does not exist either.
 *
 * DIRECTORY               <path>|                 <child-leaf-name>|*
 *         Gives a list of the immediate children of <path>, as only the
 *         leafnames.  The resulting children are each named
 *         <path>/<child-leaf-name>.
 *
 * DIRECTORY_PART          <path>|<offset>         <gencnt>|<child-leaf-name>|*
 *         Same as DIRECTORY, but to be used for children lists longer than
 *         XENSTORE_PAYLOAD_MAX. Input are <path> and the byte offset into
 *         the list of children to return. Return values are the generation
 *         count <gencnt> of the node (to be used to ensure the node hasn't
 *         changed between two reads: <gencnt> being the same for multiple
 *         reads guarantees the node hasn't changed) and the list of children
 *         starting at the specified <offset> of the complete list.
 *
 * GET_PERMS               <path>|                 <perm-as-string>|+
 * SET_PERMS               <path>|<perm-as-string>|+?
 *         <perm-as-string> is one of the following
 *                 w<domid>        write only
 *                 r<domid>        read only
 *                 b<domid>        both read and write
 *                 n<domid>        no access
 *         See https://wiki.xen.org/wiki/XenBus section
 *         `Permissions' for details of the permissions system.
 *         It is possible to set permissions for the special watch paths
 *         "@introduceDomain" and "@releaseDomain" to enable receiving those
 *         watches in unprivileged domains.
 *
 * ---------- Watches ----------
 *
 * WATCH                   <wpath>|<token>|?
 *         Adds a watch.
 *
 *         When a <path> is modified (including path creation, removal,
 *         contents change or permissions change) this generates an event
 *         on the changed <path>.  Changes made in transactions cause an
 *         event only if and when committed.  Each occurring event is
 *         matched against all the watches currently set up, and each
 *         matching watch results in a WATCH_EVENT message (see below).
 *
 *         The event's path matches the watch's <wpath> if it is an child
 *         of <wpath>.
 *
 *         <wpath> can be a <path> to watch or @<wspecial>.  In the
 *         latter case <wspecial> may have any syntax but it matches
 *         (according to the rules above) only the following special
 *         events which are invented by xenstored:
 *             @introduceDomain    occurs on INTRODUCE
 *             @releaseDomain      occurs on any domain crash or
 *                                 shutdown, and also on RELEASE
 *                                 and domain destruction
 *         <wspecial> events are sent to privileged callers or explicitly
 *         via SET_PERMS enabled domains only.
 *
 *         When a watch is first set up it is triggered once straight
 *         away, with <path> equal to <wpath>.  Watches may be triggered
 *         spuriously.  The tx_id in a WATCH request is ignored.
 *
 *         Watches are supposed to be restricted by the permissions
 *         system but in practice the implementation is imperfect.
 *         Applications should not rely on being sent a notification for
 *         paths that they cannot read; however, an application may rely
 *         on being sent a watch when a path which it _is_ able to read
 *         is deleted even if that leaves only a nonexistent unreadable
 *         parent.  A notification may omitted if a node's permissions
 *         are changed so as to make it unreadable, in which case future
 *         notifications may be suppressed (and if the node is later made
 *         readable, some notifications may have been lost).
 *
 * WATCH_EVENT                                     <epath>|<token>|
 *         Unsolicited `reply' generated for matching modification events
 *         as described above.  req_id and tx_id are both 0.
 *
 *         <epath> is the event's path, ie the actual path that was
 *         modified; however if the event was the recursive removal of an
 *         parent of <wpath>, <epath> is just
 *         <wpath> (rather than the actual path which was removed).  So
 *         <epath> is a child of <wpath>, regardless.
 *
 *         Iff <wpath> for the watch was specified as a relative pathname,
 *         the <epath> path will also be relative (with the same base,
 *         obviously).
 *
 * UNWATCH                 <wpath>|<token>|?
 *
 * RESET_WATCHES           |
 *         Reset all watches and transactions of the caller.
 *
 * ---------- Transactions ----------
 *
 * TRANSACTION_START       |                       <transid>|
 *         <transid> is an opaque uint32_t allocated by xenstored
 *         represented as unsigned decimal.  After this, transaction may
 *         be referenced by using <transid> (as 32-bit binary) in the
 *         tx_id request header field.  When transaction is started whole
 *         db is copied; reads and writes happen on the copy.
 *         It is not legal to send non-0 tx_id in TRANSACTION_START.
 *
 * TRANSACTION_END         T|
 * TRANSACTION_END         F|
 *         tx_id must refer to existing transaction.  After this
 *         request the tx_id is no longer valid and may be reused by
 *         xenstore.  If F, the transaction is discarded.  If T,
 *         it is committed: if there were any other intervening writes
 *         then our END gets get EAGAIN.
 *
 *         The plan is that in the future only intervening `conflicting'
 *         writes cause EAGAIN, meaning only writes or other commits
 *         which changed paths which were read or written in the
 *         transaction at hand.
 *
 */

static void xs_read(XenXenstoreState *s, unsigned int req_id,
                    xs_transaction_t tx_id, uint8_t *req_data, unsigned int len)
{
    const char *path = (const char *)req_data;
    struct xsd_sockmsg *rsp = (struct xsd_sockmsg *)s->rsp_data;
    uint8_t *rsp_data = (uint8_t *)&rsp[1];
    g_autoptr(GByteArray) data = g_byte_array_new();
    int err;

    if (len == 0 || req_data[len - 1] != '\0') {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    trace_xenstore_read(tx_id, path);
    err = xs_impl_read(s->impl, xen_domid, tx_id, path, data);
    if (err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    rsp->type = XS_READ;
    rsp->req_id = req_id;
    rsp->tx_id = tx_id;
    rsp->len = 0;

    len = data->len;
    if (len > XENSTORE_PAYLOAD_MAX) {
        xs_error(s, req_id, tx_id, E2BIG);
        return;
    }

    memcpy(&rsp_data[rsp->len], data->data, len);
    rsp->len += len;
}

static void xs_write(XenXenstoreState *s, unsigned int req_id,
                     xs_transaction_t tx_id, uint8_t *req_data,
                     unsigned int len)
{
    g_autoptr(GByteArray) data = g_byte_array_new();
    const char *path;
    int err;

    if (len == 0) {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    path = (const char *)req_data;

    while (len--) {
        if (*req_data++ == '\0') {
            break;
        }
        if (len == 0) {
            xs_error(s, req_id, tx_id, EINVAL);
            return;
        }
    }

    g_byte_array_append(data, req_data, len);

    trace_xenstore_write(tx_id, path);
    err = xs_impl_write(s->impl, xen_domid, tx_id, path, data);
    if (err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    xs_ok(s, XS_WRITE, req_id, tx_id);
}

static void xs_mkdir(XenXenstoreState *s, unsigned int req_id,
                     xs_transaction_t tx_id, uint8_t *req_data,
                     unsigned int len)
{
    g_autoptr(GByteArray) data = g_byte_array_new();
    const char *path;
    int err;

    if (len == 0 || req_data[len - 1] != '\0') {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    path = (const char *)req_data;

    trace_xenstore_mkdir(tx_id, path);
    err = xs_impl_read(s->impl, xen_domid, tx_id, path, data);
    if (err == ENOENT) {
        err = xs_impl_write(s->impl, xen_domid, tx_id, path, data);
    }

    if (!err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    xs_ok(s, XS_MKDIR, req_id, tx_id);
}

static void xs_append_strings(XenXenstoreState *s, struct xsd_sockmsg *rsp,
                              GList *strings, unsigned int start, bool truncate)
{
    uint8_t *rsp_data = (uint8_t *)&rsp[1];
    GList *l;

    for (l = strings; l; l = l->next) {
        size_t len = strlen(l->data) + 1; /* Including the NUL termination */
        char *str = l->data;

        if (rsp->len + len > XENSTORE_PAYLOAD_MAX) {
            if (truncate) {
                len = XENSTORE_PAYLOAD_MAX - rsp->len;
                if (!len) {
                    return;
                }
            } else {
                xs_error(s, rsp->req_id, rsp->tx_id, E2BIG);
                return;
            }
        }

        if (start) {
            if (start >= len) {
                start -= len;
                continue;
            }

            str += start;
            len -= start;
            start = 0;
        }

        memcpy(&rsp_data[rsp->len], str, len);
        rsp->len += len;
    }
    /* XS_DIRECTORY_PART wants an extra NUL to indicate the end */
    if (truncate && rsp->len < XENSTORE_PAYLOAD_MAX) {
        rsp_data[rsp->len++] = '\0';
    }
}

static void xs_directory(XenXenstoreState *s, unsigned int req_id,
                         xs_transaction_t tx_id, uint8_t *req_data,
                         unsigned int len)
{
    struct xsd_sockmsg *rsp = (struct xsd_sockmsg *)s->rsp_data;
    GList *items = NULL;
    const char *path;
    int err;

    if (len == 0 || req_data[len - 1] != '\0') {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    path = (const char *)req_data;

    trace_xenstore_directory(tx_id, path);
    err = xs_impl_directory(s->impl, xen_domid, tx_id, path, NULL, &items);
    if (err != 0) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    rsp->type = XS_DIRECTORY;
    rsp->req_id = req_id;
    rsp->tx_id = tx_id;
    rsp->len = 0;

    xs_append_strings(s, rsp, items, 0, false);

    g_list_free_full(items, g_free);
}

static void xs_directory_part(XenXenstoreState *s, unsigned int req_id,
                              xs_transaction_t tx_id, uint8_t *req_data,
                              unsigned int len)
{
    const char *offset_str, *path = (const char *)req_data;
    struct xsd_sockmsg *rsp = (struct xsd_sockmsg *)s->rsp_data;
    char *rsp_data = (char *)&rsp[1];
    uint64_t gencnt = 0;
    unsigned int offset;
    GList *items = NULL;
    int err;

    if (len == 0) {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    while (len--) {
        if (*req_data++ == '\0') {
            break;
        }
        if (len == 0) {
            xs_error(s, req_id, tx_id, EINVAL);
            return;
        }
    }

    offset_str = (const char *)req_data;
    while (len--) {
        if (*req_data++ == '\0') {
            break;
        }
        if (len == 0) {
            xs_error(s, req_id, tx_id, EINVAL);
            return;
        }
    }

    if (len) {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    if (qemu_strtoui(offset_str, NULL, 10, &offset) < 0) {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    trace_xenstore_directory_part(tx_id, path, offset);
    err = xs_impl_directory(s->impl, xen_domid, tx_id, path, &gencnt, &items);
    if (err != 0) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    rsp->type = XS_DIRECTORY_PART;
    rsp->req_id = req_id;
    rsp->tx_id = tx_id;
    rsp->len = snprintf(rsp_data, XENSTORE_PAYLOAD_MAX, "%" PRIu64, gencnt) + 1;

    xs_append_strings(s, rsp, items, offset, true);

    g_list_free_full(items, g_free);
}

static void xs_transaction_start(XenXenstoreState *s, unsigned int req_id,
                                 xs_transaction_t tx_id, uint8_t *req_data,
                                 unsigned int len)
{
    struct xsd_sockmsg *rsp = (struct xsd_sockmsg *)s->rsp_data;
    char *rsp_data = (char *)&rsp[1];
    int err;

    if (len != 1 || req_data[0] != '\0') {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    rsp->type = XS_TRANSACTION_START;
    rsp->req_id = req_id;
    rsp->tx_id = tx_id;
    rsp->len = 0;

    err = xs_impl_transaction_start(s->impl, xen_domid, &tx_id);
    if (err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    trace_xenstore_transaction_start(tx_id);

    rsp->len = snprintf(rsp_data, XENSTORE_PAYLOAD_MAX, "%u", tx_id);
    assert(rsp->len < XENSTORE_PAYLOAD_MAX);
    rsp->len++;
}

static void xs_transaction_end(XenXenstoreState *s, unsigned int req_id,
                               xs_transaction_t tx_id, uint8_t *req_data,
                               unsigned int len)
{
    bool commit;
    int err;

    if (len != 2 || req_data[1] != '\0') {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    switch (req_data[0]) {
    case 'T':
        commit = true;
        break;
    case 'F':
        commit = false;
        break;
    default:
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    trace_xenstore_transaction_end(tx_id, commit);
    err = xs_impl_transaction_end(s->impl, xen_domid, tx_id, commit);
    if (err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    xs_ok(s, XS_TRANSACTION_END, req_id, tx_id);
}

static void xs_rm(XenXenstoreState *s, unsigned int req_id,
                  xs_transaction_t tx_id, uint8_t *req_data, unsigned int len)
{
    const char *path = (const char *)req_data;
    int err;

    if (len == 0 || req_data[len - 1] != '\0') {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    trace_xenstore_rm(tx_id, path);
    err = xs_impl_rm(s->impl, xen_domid, tx_id, path);
    if (err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    xs_ok(s, XS_RM, req_id, tx_id);
}

static void xs_get_perms(XenXenstoreState *s, unsigned int req_id,
                         xs_transaction_t tx_id, uint8_t *req_data,
                         unsigned int len)
{
    const char *path = (const char *)req_data;
    struct xsd_sockmsg *rsp = (struct xsd_sockmsg *)s->rsp_data;
    GList *perms = NULL;
    int err;

    if (len == 0 || req_data[len - 1] != '\0') {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    trace_xenstore_get_perms(tx_id, path);
    err = xs_impl_get_perms(s->impl, xen_domid, tx_id, path, &perms);
    if (err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    rsp->type = XS_GET_PERMS;
    rsp->req_id = req_id;
    rsp->tx_id = tx_id;
    rsp->len = 0;

    xs_append_strings(s, rsp, perms, 0, false);

    g_list_free_full(perms, g_free);
}

static void xs_set_perms(XenXenstoreState *s, unsigned int req_id,
                         xs_transaction_t tx_id, uint8_t *req_data,
                         unsigned int len)
{
    const char *path = (const char *)req_data;
    uint8_t *perm;
    GList *perms = NULL;
    int err;

    if (len == 0) {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    while (len--) {
        if (*req_data++ == '\0') {
            break;
        }
        if (len == 0) {
            xs_error(s, req_id, tx_id, EINVAL);
            return;
        }
    }

    perm = req_data;
    while (len--) {
        if (*req_data++ == '\0') {
            perms = g_list_append(perms, perm);
            perm = req_data;
        }
    }

    /*
     * Note that there may be trailing garbage at the end of the buffer.
     * This is explicitly permitted by the '?' at the end of the definition:
     *
     *    SET_PERMS         <path>|<perm-as-string>|+?
     */

    trace_xenstore_set_perms(tx_id, path);
    err = xs_impl_set_perms(s->impl, xen_domid, tx_id, path, perms);
    g_list_free(perms);
    if (err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    xs_ok(s, XS_SET_PERMS, req_id, tx_id);
}

static void xs_watch(XenXenstoreState *s, unsigned int req_id,
                     xs_transaction_t tx_id, uint8_t *req_data,
                     unsigned int len)
{
    const char *token, *path = (const char *)req_data;
    int err;

    if (len == 0) {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    while (len--) {
        if (*req_data++ == '\0') {
            break;
        }
        if (len == 0) {
            xs_error(s, req_id, tx_id, EINVAL);
            return;
        }
    }

    token = (const char *)req_data;
    while (len--) {
        if (*req_data++ == '\0') {
            break;
        }
        if (len == 0) {
            xs_error(s, req_id, tx_id, EINVAL);
            return;
        }
    }

    /*
     * Note that there may be trailing garbage at the end of the buffer.
     * This is explicitly permitted by the '?' at the end of the definition:
     *
     *    WATCH             <wpath>|<token>|?
     */

    trace_xenstore_watch(path, token);
    err = xs_impl_watch(s->impl, xen_domid, path, token, fire_watch_cb, s);
    if (err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    xs_ok(s, XS_WATCH, req_id, tx_id);
}

static void xs_unwatch(XenXenstoreState *s, unsigned int req_id,
                       xs_transaction_t tx_id, uint8_t *req_data,
                       unsigned int len)
{
    const char *token, *path = (const char *)req_data;
    int err;

    if (len == 0) {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    while (len--) {
        if (*req_data++ == '\0') {
            break;
        }
        if (len == 0) {
            xs_error(s, req_id, tx_id, EINVAL);
            return;
        }
    }

    token = (const char *)req_data;
    while (len--) {
        if (*req_data++ == '\0') {
            break;
        }
        if (len == 0) {
            xs_error(s, req_id, tx_id, EINVAL);
            return;
        }
    }

    trace_xenstore_unwatch(path, token);
    err = xs_impl_unwatch(s->impl, xen_domid, path, token, fire_watch_cb, s);
    if (err) {
        xs_error(s, req_id, tx_id, err);
        return;
    }

    xs_ok(s, XS_UNWATCH, req_id, tx_id);
}

static void xs_reset_watches(XenXenstoreState *s, unsigned int req_id,
                             xs_transaction_t tx_id, uint8_t *req_data,
                             unsigned int len)
{
    if (len == 0 || req_data[len - 1] != '\0') {
        xs_error(s, req_id, tx_id, EINVAL);
        return;
    }

    trace_xenstore_reset_watches();
    xs_impl_reset_watches(s->impl, xen_domid);

    xs_ok(s, XS_RESET_WATCHES, req_id, tx_id);
}

static void xs_priv(XenXenstoreState *s, unsigned int req_id,
                    xs_transaction_t tx_id, uint8_t *data,
                    unsigned int len)
{
    xs_error(s, req_id, tx_id, EACCES);
}

static void xs_unimpl(XenXenstoreState *s, unsigned int req_id,
                      xs_transaction_t tx_id, uint8_t *data,
                      unsigned int len)
{
    xs_error(s, req_id, tx_id, ENOSYS);
}

typedef void (*xs_impl)(XenXenstoreState *s, unsigned int req_id,
                        xs_transaction_t tx_id, uint8_t *data,
                        unsigned int len);

struct xsd_req {
    const char *name;
    xs_impl fn;
};
#define XSD_REQ(_type, _fn)                           \
    [_type] = { .name = #_type, .fn = _fn }

struct xsd_req xsd_reqs[] = {
    XSD_REQ(XS_READ, xs_read),
    XSD_REQ(XS_WRITE, xs_write),
    XSD_REQ(XS_MKDIR, xs_mkdir),
    XSD_REQ(XS_DIRECTORY, xs_directory),
    XSD_REQ(XS_DIRECTORY_PART, xs_directory_part),
    XSD_REQ(XS_TRANSACTION_START, xs_transaction_start),
    XSD_REQ(XS_TRANSACTION_END, xs_transaction_end),
    XSD_REQ(XS_RM, xs_rm),
    XSD_REQ(XS_GET_PERMS, xs_get_perms),
    XSD_REQ(XS_SET_PERMS, xs_set_perms),
    XSD_REQ(XS_WATCH, xs_watch),
    XSD_REQ(XS_UNWATCH, xs_unwatch),
    XSD_REQ(XS_CONTROL, xs_priv),
    XSD_REQ(XS_INTRODUCE, xs_priv),
    XSD_REQ(XS_RELEASE, xs_priv),
    XSD_REQ(XS_IS_DOMAIN_INTRODUCED, xs_priv),
    XSD_REQ(XS_RESUME, xs_priv),
    XSD_REQ(XS_SET_TARGET, xs_priv),
    XSD_REQ(XS_RESET_WATCHES, xs_reset_watches),
};

static void process_req(XenXenstoreState *s)
{
    struct xsd_sockmsg *req = (struct xsd_sockmsg *)s->req_data;
    xs_impl handler = NULL;

    assert(req_pending(s));
    assert(!s->rsp_pending);

    if (req->type < ARRAY_SIZE(xsd_reqs)) {
        handler = xsd_reqs[req->type].fn;
    }
    if (!handler) {
        handler = &xs_unimpl;
    }

    handler(s, req->req_id, req->tx_id, (uint8_t *)&req[1], req->len);

    s->rsp_pending = true;
    reset_req(s);
}

static unsigned int copy_from_ring(XenXenstoreState *s, uint8_t *ptr,
                                   unsigned int len)
{
    if (!len) {
        return 0;
    }

    XENSTORE_RING_IDX prod = qatomic_read(&s->xs->req_prod);
    XENSTORE_RING_IDX cons = qatomic_read(&s->xs->req_cons);
    unsigned int copied = 0;

    /* Ensure the ring contents don't cross the req_prod access. */
    smp_rmb();

    while (len) {
        unsigned int avail = prod - cons;
        unsigned int offset = MASK_XENSTORE_IDX(cons);
        unsigned int copylen = avail;

        if (avail > XENSTORE_RING_SIZE) {
            error_report("XenStore ring handling error");
            s->fatal_error = true;
            break;
        } else if (avail == 0) {
            break;
        }

        if (copylen > len) {
            copylen = len;
        }
        if (copylen > XENSTORE_RING_SIZE - offset) {
            copylen = XENSTORE_RING_SIZE - offset;
        }

        memcpy(ptr, &s->xs->req[offset], copylen);
        copied += copylen;

        ptr += copylen;
        len -= copylen;

        cons += copylen;
    }

    /*
     * Not sure this ever mattered except on Alpha, but this barrier
     * is to ensure that the update to req_cons is globally visible
     * only after we have consumed all the data from the ring, and we
     * don't end up seeing data written to the ring *after* the other
     * end sees the update and writes more to the ring. Xen's own
     * xenstored has the same barrier here (although with no comment
     * at all, obviously, because it's Xen code).
     */
    smp_mb();

    qatomic_set(&s->xs->req_cons, cons);

    return copied;
}

static unsigned int copy_to_ring(XenXenstoreState *s, uint8_t *ptr,
                                 unsigned int len)
{
    if (!len) {
        return 0;
    }

    XENSTORE_RING_IDX cons = qatomic_read(&s->xs->rsp_cons);
    XENSTORE_RING_IDX prod = qatomic_read(&s->xs->rsp_prod);
    unsigned int copied = 0;

    /*
     * This matches the barrier in copy_to_ring() (or the guest's
     * equivalent) betweem writing the data to the ring and updating
     * rsp_prod. It protects against the pathological case (which
     * again I think never happened except on Alpha) where our
     * subsequent writes to the ring could *cross* the read of
     * rsp_cons and the guest could see the new data when it was
     * intending to read the old.
     */
    smp_mb();

    while (len) {
        unsigned int avail = cons + XENSTORE_RING_SIZE - prod;
        unsigned int offset = MASK_XENSTORE_IDX(prod);
        unsigned int copylen = len;

        if (avail > XENSTORE_RING_SIZE) {
            error_report("XenStore ring handling error");
            s->fatal_error = true;
            break;
        } else if (avail == 0) {
            break;
        }

        if (copylen > avail) {
            copylen = avail;
        }
        if (copylen > XENSTORE_RING_SIZE - offset) {
            copylen = XENSTORE_RING_SIZE - offset;
        }


        memcpy(&s->xs->rsp[offset], ptr, copylen);
        copied += copylen;

        ptr += copylen;
        len -= copylen;

        prod += copylen;
    }

    /* Ensure the ring contents are seen before rsp_prod update. */
    smp_wmb();

    qatomic_set(&s->xs->rsp_prod, prod);

    return copied;
}

static unsigned int get_req(XenXenstoreState *s)
{
    unsigned int copied = 0;

    if (s->fatal_error) {
        return 0;
    }

    assert(!req_pending(s));

    if (s->req_offset < XENSTORE_HEADER_SIZE) {
        void *ptr = s->req_data + s->req_offset;
        unsigned int len = XENSTORE_HEADER_SIZE;
        unsigned int copylen = copy_from_ring(s, ptr, len);

        copied += copylen;
        s->req_offset += copylen;
    }

    if (s->req_offset >= XENSTORE_HEADER_SIZE) {
        struct xsd_sockmsg *req = (struct xsd_sockmsg *)s->req_data;

        if (req->len > (uint32_t)XENSTORE_PAYLOAD_MAX) {
            error_report("Illegal XenStore request");
            s->fatal_error = true;
            return 0;
        }

        void *ptr = s->req_data + s->req_offset;
        unsigned int len = XENSTORE_HEADER_SIZE + req->len - s->req_offset;
        unsigned int copylen = copy_from_ring(s, ptr, len);

        copied += copylen;
        s->req_offset += copylen;
    }

    return copied;
}

static unsigned int put_rsp(XenXenstoreState *s)
{
    if (s->fatal_error) {
        return 0;
    }

    assert(s->rsp_pending);

    struct xsd_sockmsg *rsp = (struct xsd_sockmsg *)s->rsp_data;
    assert(s->rsp_offset < XENSTORE_HEADER_SIZE + rsp->len);

    void *ptr = s->rsp_data + s->rsp_offset;
    unsigned int len = XENSTORE_HEADER_SIZE + rsp->len - s->rsp_offset;
    unsigned int copylen = copy_to_ring(s, ptr, len);

    s->rsp_offset += copylen;

    /* Have we produced a complete response? */
    if (s->rsp_offset == XENSTORE_HEADER_SIZE + rsp->len) {
        reset_rsp(s);
    }

    return copylen;
}

static void deliver_watch(XenXenstoreState *s, const char *path,
                          const char *token)
{
    struct xsd_sockmsg *rsp = (struct xsd_sockmsg *)s->rsp_data;
    uint8_t *rsp_data = (uint8_t *)&rsp[1];
    unsigned int len;

    assert(!s->rsp_pending);

    trace_xenstore_watch_event(path, token);

    rsp->type = XS_WATCH_EVENT;
    rsp->req_id = 0;
    rsp->tx_id = 0;
    rsp->len = 0;

    len = strlen(path);

    /* XENSTORE_ABS/REL_PATH_MAX should ensure there can be no overflow */
    assert(rsp->len + len < XENSTORE_PAYLOAD_MAX);

    memcpy(&rsp_data[rsp->len], path, len);
    rsp->len += len;
    rsp_data[rsp->len] = '\0';
    rsp->len++;

    len = strlen(token);
    /*
     * It is possible for the guest to have chosen a token that will
     * not fit (along with the patch) into a watch event. We have no
     * choice but to drop the event if this is the case.
     */
    if (rsp->len + len >= XENSTORE_PAYLOAD_MAX) {
        return;
    }

    memcpy(&rsp_data[rsp->len], token, len);
    rsp->len += len;
    rsp_data[rsp->len] = '\0';
    rsp->len++;

    s->rsp_pending = true;
}

struct watch_event {
    char *path;
    char *token;
};

static void free_watch_event(struct watch_event *ev)
{
    if (ev) {
        g_free(ev->path);
        g_free(ev->token);
        g_free(ev);
    }
}

static void queue_watch(XenXenstoreState *s, const char *path,
                        const char *token)
{
    struct watch_event *ev = g_new0(struct watch_event, 1);

    ev->path = g_strdup(path);
    ev->token = g_strdup(token);

    s->watch_events = g_list_append(s->watch_events, ev);
}

static void fire_watch_cb(void *opaque, const char *path, const char *token)
{
    XenXenstoreState *s = opaque;

    assert(qemu_mutex_iothread_locked());

    /*
     * If there's a response pending, we obviously can't scribble over
     * it. But if there's a request pending, it has dibs on the buffer
     * too.
     *
     * In the common case of a watch firing due to backend activity
     * when the ring was otherwise idle, we should be able to copy the
     * strings directly into the rsp_data and thence the actual ring,
     * without needing to perform any allocations and queue them.
     */
    if (s->rsp_pending || req_pending(s)) {
        queue_watch(s, path, token);
    } else {
        deliver_watch(s, path, token);
        /*
         * If the message was queued because there was already ring activity,
         * no need to wake the guest. But if not, we need to send the evtchn.
         */
        xen_be_evtchn_notify(s->eh, s->be_port);
    }
}

static void process_watch_events(XenXenstoreState *s)
{
    struct watch_event *ev = s->watch_events->data;

    deliver_watch(s, ev->path, ev->token);

    s->watch_events = g_list_remove(s->watch_events, ev);
    free_watch_event(ev);
}

static void xen_xenstore_event(void *opaque)
{
    XenXenstoreState *s = opaque;
    evtchn_port_t port = xen_be_evtchn_pending(s->eh);
    unsigned int copied_to, copied_from;
    bool processed, notify = false;

    if (port != s->be_port) {
        return;
    }

    /* We know this is a no-op. */
    xen_be_evtchn_unmask(s->eh, port);

    do {
        copied_to = copied_from = 0;
        processed = false;

        if (!s->rsp_pending && s->watch_events) {
            process_watch_events(s);
        }

        if (s->rsp_pending) {
            copied_to = put_rsp(s);
        }

        if (!req_pending(s)) {
            copied_from = get_req(s);
        }

        if (req_pending(s) && !s->rsp_pending && !s->watch_events) {
            process_req(s);
            processed = true;
        }

        notify |= copied_to || copied_from;
    } while (copied_to || copied_from || processed);

    if (notify) {
        xen_be_evtchn_notify(s->eh, s->be_port);
    }
}

static void alloc_guest_port(XenXenstoreState *s)
{
    struct evtchn_alloc_unbound alloc = {
        .dom = DOMID_SELF,
        .remote_dom = DOMID_QEMU,
    };

    if (!xen_evtchn_alloc_unbound_op(&alloc)) {
        s->guest_port = alloc.port;
    }
}

int xen_xenstore_reset(void)
{
    XenXenstoreState *s = xen_xenstore_singleton;
    int err;

    if (!s) {
        return -ENOTSUP;
    }

    s->req_offset = s->rsp_offset = 0;
    s->rsp_pending = false;

    if (!memory_region_is_mapped(&s->xenstore_page)) {
        uint64_t gpa = XEN_SPECIAL_PFN(XENSTORE) << TARGET_PAGE_BITS;
        xen_overlay_do_map_page(&s->xenstore_page, gpa);
    }

    alloc_guest_port(s);

    /*
     * As qemu/dom0, bind to the guest's port. For incoming migration, this
     * will be unbound as the guest's evtchn table is overwritten. We then
     * rebind to the correct guest port in xen_xenstore_post_load().
     */
    err = xen_be_evtchn_bind_interdomain(s->eh, xen_domid, s->guest_port);
    if (err < 0) {
        return err;
    }
    s->be_port = err;

    /*
     * We don't actually access the guest's page through the grant, because
     * this isn't real Xen, and we can just use the page we gave it in the
     * first place. Map the grant anyway, mostly for cosmetic purposes so
     * it *looks* like it's in use in the guest-visible grant table.
     */
    s->gt = qemu_xen_gnttab_open();
    uint32_t xs_gntref = GNTTAB_RESERVED_XENSTORE;
    s->granted_xs = qemu_xen_gnttab_map_refs(s->gt, 1, xen_domid, &xs_gntref,
                                             PROT_READ | PROT_WRITE);

    return 0;
}

struct qemu_xs_handle {
    XenstoreImplState *impl;
    GList *watches;
    QEMUBH *watch_bh;
};

struct qemu_xs_watch {
    struct qemu_xs_handle *h;
    char *path;
    xs_watch_fn fn;
    void *opaque;
    GList *events;
};

static char *xs_be_get_domain_path(struct qemu_xs_handle *h, unsigned int domid)
{
    return g_strdup_printf("/local/domain/%u", domid);
}

static char **xs_be_directory(struct qemu_xs_handle *h, xs_transaction_t t,
                              const char *path, unsigned int *num)
{
    GList *items = NULL, *l;
    unsigned int i = 0;
    char **items_ret;
    int err;

    err = xs_impl_directory(h->impl, DOMID_QEMU, t, path, NULL, &items);
    if (err) {
        errno = err;
        return NULL;
    }

    items_ret = g_new0(char *, g_list_length(items) + 1);
    *num = 0;
    for (l = items; l; l = l->next) {
        items_ret[i++] = l->data;
        (*num)++;
    }
    g_list_free(items);
    return items_ret;
}

static void *xs_be_read(struct qemu_xs_handle *h, xs_transaction_t t,
                        const char *path, unsigned int *len)
{
    GByteArray *data = g_byte_array_new();
    bool free_segment = false;
    int err;

    err = xs_impl_read(h->impl, DOMID_QEMU, t, path, data);
    if (err) {
        free_segment = true;
        errno = err;
    } else {
        if (len) {
            *len = data->len;
        }
        /* The xen-bus-helper code expects to get NUL terminated string! */
        g_byte_array_append(data, (void *)"", 1);
    }

    return g_byte_array_free(data, free_segment);
}

static bool xs_be_write(struct qemu_xs_handle *h, xs_transaction_t t,
                        const char *path, const void *data, unsigned int len)
{
    GByteArray *gdata = g_byte_array_new();
    int err;

    g_byte_array_append(gdata, data, len);
    err = xs_impl_write(h->impl, DOMID_QEMU, t, path, gdata);
    g_byte_array_unref(gdata);
    if (err) {
        errno = err;
        return false;
    }
    return true;
}

static bool xs_be_create(struct qemu_xs_handle *h, xs_transaction_t t,
                         unsigned int owner, unsigned int domid,
                         unsigned int perms, const char *path)
{
    g_autoptr(GByteArray) data = g_byte_array_new();
    GList *perms_list = NULL;
    int err;

    /* mkdir does this */
    err = xs_impl_read(h->impl, DOMID_QEMU, t, path, data);
    if (err == ENOENT) {
        err = xs_impl_write(h->impl, DOMID_QEMU, t, path, data);
    }
    if (err) {
        errno = err;
        return false;
    }

    perms_list = g_list_append(perms_list,
                               xs_perm_as_string(XS_PERM_NONE, owner));
    perms_list = g_list_append(perms_list,
                               xs_perm_as_string(perms, domid));

    err = xs_impl_set_perms(h->impl, DOMID_QEMU, t, path, perms_list);
    g_list_free_full(perms_list, g_free);
    if (err) {
        errno = err;
        return false;
    }
    return true;
}

static bool xs_be_destroy(struct qemu_xs_handle *h, xs_transaction_t t,
                          const char *path)
{
    int err = xs_impl_rm(h->impl, DOMID_QEMU, t, path);
    if (err) {
        errno = err;
        return false;
    }
    return true;
}

static void be_watch_bh(void *_h)
{
    struct qemu_xs_handle *h = _h;
    GList *l;

    for (l = h->watches; l; l = l->next) {
        struct qemu_xs_watch *w = l->data;

        while (w->events) {
            struct watch_event *ev = w->events->data;

            w->fn(w->opaque, ev->path);

            w->events = g_list_remove(w->events, ev);
            free_watch_event(ev);
        }
    }
}

static void xs_be_watch_cb(void *opaque, const char *path, const char *token)
{
    struct watch_event *ev = g_new0(struct watch_event, 1);
    struct qemu_xs_watch *w = opaque;

    /* We don't care about the token */
    ev->path = g_strdup(path);
    w->events = g_list_append(w->events, ev);

    qemu_bh_schedule(w->h->watch_bh);
}

static struct qemu_xs_watch *xs_be_watch(struct qemu_xs_handle *h,
                                         const char *path, xs_watch_fn fn,
                                         void *opaque)
{
    struct qemu_xs_watch *w = g_new0(struct qemu_xs_watch, 1);
    int err;

    w->h = h;
    w->fn = fn;
    w->opaque = opaque;

    err = xs_impl_watch(h->impl, DOMID_QEMU, path, NULL, xs_be_watch_cb, w);
    if (err) {
        errno = err;
        g_free(w);
        return NULL;
    }

    w->path = g_strdup(path);
    h->watches = g_list_append(h->watches, w);
    return w;
}

static void xs_be_unwatch(struct qemu_xs_handle *h, struct qemu_xs_watch *w)
{
    xs_impl_unwatch(h->impl, DOMID_QEMU, w->path, NULL, xs_be_watch_cb, w);

    h->watches = g_list_remove(h->watches, w);
    g_list_free_full(w->events, (GDestroyNotify)free_watch_event);
    g_free(w->path);
    g_free(w);
}

static xs_transaction_t xs_be_transaction_start(struct qemu_xs_handle *h)
{
    unsigned int new_tx = XBT_NULL;
    int err = xs_impl_transaction_start(h->impl, DOMID_QEMU, &new_tx);
    if (err) {
        errno = err;
        return XBT_NULL;
    }
    return new_tx;
}

static bool xs_be_transaction_end(struct qemu_xs_handle *h, xs_transaction_t t,
                                  bool abort)
{
    int err = xs_impl_transaction_end(h->impl, DOMID_QEMU, t, !abort);
    if (err) {
        errno = err;
        return false;
    }
    return true;
}

static struct qemu_xs_handle *xs_be_open(void)
{
    XenXenstoreState *s = xen_xenstore_singleton;
    struct qemu_xs_handle *h;

    if (!s && !s->impl) {
        errno = -ENOSYS;
        return NULL;
    }

    h = g_new0(struct qemu_xs_handle, 1);
    h->impl = s->impl;

    h->watch_bh = aio_bh_new(qemu_get_aio_context(), be_watch_bh, h);

    return h;
}

static void xs_be_close(struct qemu_xs_handle *h)
{
    while (h->watches) {
        struct qemu_xs_watch *w = h->watches->data;
        xs_be_unwatch(h, w);
    }

    qemu_bh_delete(h->watch_bh);
    g_free(h);
}

static struct xenstore_backend_ops emu_xenstore_backend_ops = {
    .open = xs_be_open,
    .close = xs_be_close,
    .get_domain_path = xs_be_get_domain_path,
    .directory = xs_be_directory,
    .read = xs_be_read,
    .write = xs_be_write,
    .create = xs_be_create,
    .destroy = xs_be_destroy,
    .watch = xs_be_watch,
    .unwatch = xs_be_unwatch,
    .transaction_start = xs_be_transaction_start,
    .transaction_end = xs_be_transaction_end,
};
