aboutsummaryrefslogtreecommitdiffstats
path: root/hw/xen/xen-bus-helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/xen/xen-bus-helper.c')
-rw-r--r--hw/xen/xen-bus-helper.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/hw/xen/xen-bus-helper.c b/hw/xen/xen-bus-helper.c
new file mode 100644
index 000000000..5a1e12b37
--- /dev/null
+++ b/hw/xen/xen-bus-helper.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2018 Citrix Systems Inc.
+ *
+ * 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 "hw/xen/xen.h"
+#include "hw/xen/xen-bus.h"
+#include "hw/xen/xen-bus-helper.h"
+#include "qapi/error.h"
+
+#include <glib/gprintf.h>
+
+struct xs_state {
+ enum xenbus_state statenum;
+ const char *statestr;
+};
+#define XS_STATE(state) { state, #state }
+
+static struct xs_state xs_state[] = {
+ XS_STATE(XenbusStateUnknown),
+ XS_STATE(XenbusStateInitialising),
+ XS_STATE(XenbusStateInitWait),
+ XS_STATE(XenbusStateInitialised),
+ XS_STATE(XenbusStateConnected),
+ XS_STATE(XenbusStateClosing),
+ XS_STATE(XenbusStateClosed),
+ XS_STATE(XenbusStateReconfiguring),
+ XS_STATE(XenbusStateReconfigured),
+};
+
+#undef XS_STATE
+
+const char *xs_strstate(enum xenbus_state state)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE(xs_state); i++) {
+ if (xs_state[i].statenum == state) {
+ return xs_state[i].statestr;
+ }
+ }
+
+ return "INVALID";
+}
+
+void xs_node_create(struct xs_handle *xsh, xs_transaction_t tid,
+ const char *node, struct xs_permissions perms[],
+ unsigned int nr_perms, Error **errp)
+{
+ trace_xs_node_create(node);
+
+ if (!xs_write(xsh, tid, node, "", 0)) {
+ error_setg_errno(errp, errno, "failed to create node '%s'", node);
+ return;
+ }
+
+ if (!xs_set_permissions(xsh, tid, node, perms, nr_perms)) {
+ error_setg_errno(errp, errno, "failed to set node '%s' permissions",
+ node);
+ }
+}
+
+void xs_node_destroy(struct xs_handle *xsh, xs_transaction_t tid,
+ const char *node, Error **errp)
+{
+ trace_xs_node_destroy(node);
+
+ if (!xs_rm(xsh, tid, node)) {
+ error_setg_errno(errp, errno, "failed to destroy node '%s'", node);
+ }
+}
+
+void xs_node_vprintf(struct xs_handle *xsh, xs_transaction_t tid,
+ const char *node, const char *key, Error **errp,
+ const char *fmt, va_list ap)
+{
+ char *path, *value;
+ int len;
+
+ path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+ g_strdup(key);
+ len = g_vasprintf(&value, fmt, ap);
+
+ trace_xs_node_vprintf(path, value);
+
+ if (!xs_write(xsh, tid, path, value, len)) {
+ error_setg_errno(errp, errno, "failed to write '%s' to '%s'",
+ value, path);
+ }
+
+ g_free(value);
+ g_free(path);
+}
+
+void xs_node_printf(struct xs_handle *xsh, xs_transaction_t tid,
+ const char *node, const char *key, Error **errp,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ xs_node_vprintf(xsh, tid, node, key, errp, fmt, ap);
+ va_end(ap);
+}
+
+int xs_node_vscanf(struct xs_handle *xsh, xs_transaction_t tid,
+ const char *node, const char *key, Error **errp,
+ const char *fmt, va_list ap)
+{
+ char *path, *value;
+ int rc;
+
+ path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+ g_strdup(key);
+ value = xs_read(xsh, tid, path, NULL);
+
+ trace_xs_node_vscanf(path, value);
+
+ if (value) {
+ rc = vsscanf(value, fmt, ap);
+ } else {
+ error_setg_errno(errp, errno, "failed to read from '%s'",
+ path);
+ rc = EOF;
+ }
+
+ free(value);
+ g_free(path);
+
+ return rc;
+}
+
+int xs_node_scanf(struct xs_handle *xsh, xs_transaction_t tid,
+ const char *node, const char *key, Error **errp,
+ const char *fmt, ...)
+{
+ va_list ap;
+ int rc;
+
+ va_start(ap, fmt);
+ rc = xs_node_vscanf(xsh, tid, node, key, errp, fmt, ap);
+ va_end(ap);
+
+ return rc;
+}
+
+void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
+ char *token, Error **errp)
+{
+ char *path;
+
+ path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+ g_strdup(key);
+
+ trace_xs_node_watch(path);
+
+ if (!xs_watch(xsh, path, token)) {
+ error_setg_errno(errp, errno, "failed to watch node '%s'", path);
+ }
+
+ g_free(path);
+}
+
+void xs_node_unwatch(struct xs_handle *xsh, const char *node,
+ const char *key, const char *token, Error **errp)
+{
+ char *path;
+
+ path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
+ g_strdup(key);
+
+ trace_xs_node_unwatch(path);
+
+ if (!xs_unwatch(xsh, path, token)) {
+ error_setg_errno(errp, errno, "failed to unwatch node '%s'", path);
+ }
+
+ g_free(path);
+}