1
2
3
4
5
6
7
8#include "qemu/osdep.h"
9#include "hw/sysbus.h"
10#include "hw/xen/xen.h"
11#include "hw/xen/xen-bus.h"
12#include "hw/xen/xen-bus-helper.h"
13#include "qapi/error.h"
14
15#include <glib/gprintf.h>
16
17struct xs_state {
18 enum xenbus_state statenum;
19 const char *statestr;
20};
21#define XS_STATE(state) { state, #state }
22
23static struct xs_state xs_state[] = {
24 XS_STATE(XenbusStateUnknown),
25 XS_STATE(XenbusStateInitialising),
26 XS_STATE(XenbusStateInitWait),
27 XS_STATE(XenbusStateInitialised),
28 XS_STATE(XenbusStateConnected),
29 XS_STATE(XenbusStateClosing),
30 XS_STATE(XenbusStateClosed),
31 XS_STATE(XenbusStateReconfiguring),
32 XS_STATE(XenbusStateReconfigured),
33};
34
35#undef XS_STATE
36
37const char *xs_strstate(enum xenbus_state state)
38{
39 unsigned int i;
40
41 for (i = 0; i < ARRAY_SIZE(xs_state); i++) {
42 if (xs_state[i].statenum == state) {
43 return xs_state[i].statestr;
44 }
45 }
46
47 return "INVALID";
48}
49
50void xs_node_create(struct xs_handle *xsh, xs_transaction_t tid,
51 const char *node, struct xs_permissions perms[],
52 unsigned int nr_perms, Error **errp)
53{
54 trace_xs_node_create(node);
55
56 if (!xs_write(xsh, tid, node, "", 0)) {
57 error_setg_errno(errp, errno, "failed to create node '%s'", node);
58 return;
59 }
60
61 if (!xs_set_permissions(xsh, tid, node, perms, nr_perms)) {
62 error_setg_errno(errp, errno, "failed to set node '%s' permissions",
63 node);
64 }
65}
66
67void xs_node_destroy(struct xs_handle *xsh, xs_transaction_t tid,
68 const char *node, Error **errp)
69{
70 trace_xs_node_destroy(node);
71
72 if (!xs_rm(xsh, tid, node)) {
73 error_setg_errno(errp, errno, "failed to destroy node '%s'", node);
74 }
75}
76
77void xs_node_vprintf(struct xs_handle *xsh, xs_transaction_t tid,
78 const char *node, const char *key, Error **errp,
79 const char *fmt, va_list ap)
80{
81 char *path, *value;
82 int len;
83
84 path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
85 g_strdup(key);
86 len = g_vasprintf(&value, fmt, ap);
87
88 trace_xs_node_vprintf(path, value);
89
90 if (!xs_write(xsh, tid, path, value, len)) {
91 error_setg_errno(errp, errno, "failed to write '%s' to '%s'",
92 value, path);
93 }
94
95 g_free(value);
96 g_free(path);
97}
98
99void xs_node_printf(struct xs_handle *xsh, xs_transaction_t tid,
100 const char *node, const char *key, Error **errp,
101 const char *fmt, ...)
102{
103 va_list ap;
104
105 va_start(ap, fmt);
106 xs_node_vprintf(xsh, tid, node, key, errp, fmt, ap);
107 va_end(ap);
108}
109
110int xs_node_vscanf(struct xs_handle *xsh, xs_transaction_t tid,
111 const char *node, const char *key, Error **errp,
112 const char *fmt, va_list ap)
113{
114 char *path, *value;
115 int rc;
116
117 path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
118 g_strdup(key);
119 value = xs_read(xsh, tid, path, NULL);
120
121 trace_xs_node_vscanf(path, value);
122
123 if (value) {
124 rc = vsscanf(value, fmt, ap);
125 } else {
126 error_setg_errno(errp, errno, "failed to read from '%s'",
127 path);
128 rc = EOF;
129 }
130
131 free(value);
132 g_free(path);
133
134 return rc;
135}
136
137int xs_node_scanf(struct xs_handle *xsh, xs_transaction_t tid,
138 const char *node, const char *key, Error **errp,
139 const char *fmt, ...)
140{
141 va_list ap;
142 int rc;
143
144 va_start(ap, fmt);
145 rc = xs_node_vscanf(xsh, tid, node, key, errp, fmt, ap);
146 va_end(ap);
147
148 return rc;
149}
150
151void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
152 char *token, Error **errp)
153{
154 char *path;
155
156 path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
157 g_strdup(key);
158
159 trace_xs_node_watch(path);
160
161 if (!xs_watch(xsh, path, token)) {
162 error_setg_errno(errp, errno, "failed to watch node '%s'", path);
163 }
164
165 g_free(path);
166}
167
168void xs_node_unwatch(struct xs_handle *xsh, const char *node,
169 const char *key, const char *token, Error **errp)
170{
171 char *path;
172
173 path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
174 g_strdup(key);
175
176 trace_xs_node_unwatch(path);
177
178 if (!xs_unwatch(xsh, path, token)) {
179 error_setg_errno(errp, errno, "failed to unwatch node '%s'", path);
180 }
181
182 g_free(path);
183}
184