xref: /qemu/hw/xen/xen-bus-helper.c (revision ab9056ff)
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/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 
17 struct xs_state {
18     enum xenbus_state statenum;
19     const char *statestr;
20 };
21 #define XS_STATE(state) { state, #state }
22 
23 static 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 
37 const 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 
50 void 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 
67 void 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 
77 void 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 
99 void 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 
110 int 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 
137 int 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 
151 void 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 
168 void 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