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