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