From: David Woodhouse
This implements the basic wire protocol for the XenStore commands, punting
all the actual implementation to xs_impl_* functions which all just return
errors for now.
Signed-off-by: David Woodhouse
---
hw/i386/kvm/meson.build | 1 +
hw/i386/kvm/trace-events| 15 +
hw/i386/kvm/xen_xenstore.c | 871 +++-
hw/i386/kvm/xenstore_impl.c | 117 +
hw/i386/kvm/xenstore_impl.h | 58 +++
5 files changed, 1054 insertions(+), 8 deletions(-)
create mode 100644 hw/i386/kvm/xenstore_impl.c
create mode 100644 hw/i386/kvm/xenstore_impl.h
diff --git a/hw/i386/kvm/meson.build b/hw/i386/kvm/meson.build
index 82dd6ae7c6..6621ba5cd7 100644
--- a/hw/i386/kvm/meson.build
+++ b/hw/i386/kvm/meson.build
@@ -9,6 +9,7 @@ i386_kvm_ss.add(when: 'CONFIG_XEN_EMU', if_true: files(
'xen_evtchn.c',
'xen_gnttab.c',
'xen_xenstore.c',
+ 'xenstore_impl.c',
))
i386_ss.add_all(when: 'CONFIG_KVM', if_true: i386_kvm_ss)
diff --git a/hw/i386/kvm/trace-events b/hw/i386/kvm/trace-events
index b83c3eb965..e4c82de6f3 100644
--- a/hw/i386/kvm/trace-events
+++ b/hw/i386/kvm/trace-events
@@ -3,3 +3,18 @@ kvm_xen_unmap_pirq(int pirq, int gsi) "pirq %d gsi %d"
kvm_xen_get_free_pirq(int pirq, int type) "pirq %d type %d"
kvm_xen_bind_pirq(int pirq, int port) "pirq %d port %d"
kvm_xen_unmask_pirq(int pirq, char *dev, int vector) "pirq %d dev %s vector %d"
+xenstore_error(unsigned int id, unsigned int tx_id, const char *err) "req %u
tx %u err %s"
+xenstore_read(unsigned int tx_id, const char *path) "tx %u path %s"
+xenstore_write(unsigned int tx_id, const char *path) "tx %u path %s"
+xenstore_mkdir(unsigned int tx_id, const char *path) "tx %u path %s"
+xenstore_directory(unsigned int tx_id, const char *path) "tx %u path %s"
+xenstore_directory_part(unsigned int tx_id, const char *path, unsigned int
offset) "tx %u path %s offset %u"
+xenstore_transaction_start(unsigned int new_tx) "new_tx %u"
+xenstore_transaction_end(unsigned int tx_id, bool commit) "tx %u commit %d"
+xenstore_rm(unsigned int tx_id, const char *path) "tx %u path %s"
+xenstore_get_perms(unsigned int tx_id, const char *path) "tx %u path %s"
+xenstore_set_perms(unsigned int tx_id, const char *path) "tx %u path %s"
+xenstore_watch(const char *path, const char *token) "path %s token %s"
+xenstore_unwatch(const char *path, const char *token) "path %s token %s"
+xenstore_reset_watches(void) ""
+xenstore_watch_event(const char *path, const char *token) "path %s token %s"
diff --git a/hw/i386/kvm/xen_xenstore.c b/hw/i386/kvm/xen_xenstore.c
index 14193ef3f9..64d8f1a38f 100644
--- a/hw/i386/kvm/xen_xenstore.c
+++ b/hw/i386/kvm/xen_xenstore.c
@@ -28,6 +28,10 @@
#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"
@@ -47,6 +51,9 @@ struct XenXenstoreState {
SysBusDevice busdev;
/*< public >*/
+XenstoreImplState *impl;
+GList *watch_events;
+
MemoryRegion xenstore_page;
struct xenstore_domain_interface *xs;
uint8_t req_data[XENSTORE_HEADER_SIZE + XENSTORE_PAYLOAD_MAX];
@@ -64,6 +71,7 @@ struct XenXenstoreState {
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 void xen_xenstore_realize(DeviceState *dev, Error **errp)
{
@@ -89,6 +97,8 @@ static void xen_xenstore_realize(DeviceState *dev, Error
**errp)
}
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();
}
static bool xen_xenstore_is_needed(void *opaque)
@@ -213,20 +223,761 @@ static void reset_rsp(XenXenstoreState *s)
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 = _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([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([1], okstr, rsp->len);
+}
+