xref: /openbmc/qemu/hw/xen/xen-bus-helper.c (revision ffe98631)
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 }
183