xref: /openbmc/qemu/hw/xen/xen-bus-helper.c (revision 15002921e878e6cf485f655d580733b5319ea015)
1094a2239SPaul Durrant /*
2094a2239SPaul Durrant  * Copyright (c) 2018  Citrix Systems Inc.
3094a2239SPaul Durrant  *
4094a2239SPaul Durrant  * This work is licensed under the terms of the GNU GPL, version 2 or later.
5094a2239SPaul Durrant  * See the COPYING file in the top-level directory.
6094a2239SPaul Durrant  */
7094a2239SPaul Durrant 
8094a2239SPaul Durrant #include "qemu/osdep.h"
9094a2239SPaul Durrant #include "hw/xen/xen.h"
10094a2239SPaul Durrant #include "hw/xen/xen-bus.h"
11094a2239SPaul Durrant #include "hw/xen/xen-bus-helper.h"
12094a2239SPaul Durrant #include "qapi/error.h"
13*ba2a92dbSPaul Durrant #include "trace.h"
14094a2239SPaul Durrant 
15094a2239SPaul Durrant #include <glib/gprintf.h>
16094a2239SPaul Durrant 
17094a2239SPaul Durrant struct xs_state {
18094a2239SPaul Durrant     enum xenbus_state statenum;
19094a2239SPaul Durrant     const char *statestr;
20094a2239SPaul Durrant };
21094a2239SPaul Durrant #define XS_STATE(state) { state, #state }
22094a2239SPaul Durrant 
23094a2239SPaul Durrant static struct xs_state xs_state[] = {
24094a2239SPaul Durrant     XS_STATE(XenbusStateUnknown),
25094a2239SPaul Durrant     XS_STATE(XenbusStateInitialising),
26094a2239SPaul Durrant     XS_STATE(XenbusStateInitWait),
27094a2239SPaul Durrant     XS_STATE(XenbusStateInitialised),
28094a2239SPaul Durrant     XS_STATE(XenbusStateConnected),
29094a2239SPaul Durrant     XS_STATE(XenbusStateClosing),
30094a2239SPaul Durrant     XS_STATE(XenbusStateClosed),
31094a2239SPaul Durrant     XS_STATE(XenbusStateReconfiguring),
32094a2239SPaul Durrant     XS_STATE(XenbusStateReconfigured),
33094a2239SPaul Durrant };
34094a2239SPaul Durrant 
35094a2239SPaul Durrant #undef XS_STATE
36094a2239SPaul Durrant 
xs_strstate(enum xenbus_state state)37094a2239SPaul Durrant const char *xs_strstate(enum xenbus_state state)
38094a2239SPaul Durrant {
39094a2239SPaul Durrant     unsigned int i;
40094a2239SPaul Durrant 
41094a2239SPaul Durrant    for (i = 0; i < ARRAY_SIZE(xs_state); i++) {
42094a2239SPaul Durrant         if (xs_state[i].statenum == state) {
43094a2239SPaul Durrant             return xs_state[i].statestr;
44094a2239SPaul Durrant         }
45094a2239SPaul Durrant     }
46094a2239SPaul Durrant 
47094a2239SPaul Durrant     return "INVALID";
48094a2239SPaul Durrant }
49094a2239SPaul Durrant 
xs_node_create(struct qemu_xs_handle * h,xs_transaction_t tid,const char * node,unsigned int owner,unsigned int domid,unsigned int perms,Error ** errp)50*ba2a92dbSPaul Durrant void xs_node_create(struct qemu_xs_handle *h, xs_transaction_t tid,
51*ba2a92dbSPaul Durrant                     const char *node, unsigned int owner, unsigned int domid,
52*ba2a92dbSPaul Durrant                     unsigned int perms, Error **errp)
53094a2239SPaul Durrant {
54094a2239SPaul Durrant     trace_xs_node_create(node);
55094a2239SPaul Durrant 
56*ba2a92dbSPaul Durrant     if (!qemu_xen_xs_create(h, tid, owner, domid, perms, node)) {
57094a2239SPaul Durrant         error_setg_errno(errp, errno, "failed to create node '%s'", node);
58094a2239SPaul Durrant     }
59094a2239SPaul Durrant }
60094a2239SPaul Durrant 
xs_node_destroy(struct qemu_xs_handle * h,xs_transaction_t tid,const char * node,Error ** errp)61*ba2a92dbSPaul Durrant void xs_node_destroy(struct qemu_xs_handle *h, xs_transaction_t tid,
62094a2239SPaul Durrant                      const char *node, Error **errp)
63094a2239SPaul Durrant {
64094a2239SPaul Durrant     trace_xs_node_destroy(node);
65094a2239SPaul Durrant 
66*ba2a92dbSPaul Durrant     if (!qemu_xen_xs_destroy(h, tid, node)) {
67094a2239SPaul Durrant         error_setg_errno(errp, errno, "failed to destroy node '%s'", node);
68094a2239SPaul Durrant     }
69094a2239SPaul Durrant }
70094a2239SPaul Durrant 
xs_node_vprintf(struct qemu_xs_handle * h,xs_transaction_t tid,const char * node,const char * key,Error ** errp,const char * fmt,va_list ap)71*ba2a92dbSPaul Durrant void xs_node_vprintf(struct qemu_xs_handle *h, xs_transaction_t tid,
72094a2239SPaul Durrant                      const char *node, const char *key, Error **errp,
73094a2239SPaul Durrant                      const char *fmt, va_list ap)
74094a2239SPaul Durrant {
75094a2239SPaul Durrant     char *path, *value;
76094a2239SPaul Durrant     int len;
77094a2239SPaul Durrant 
78094a2239SPaul Durrant     path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
79094a2239SPaul Durrant         g_strdup(key);
80094a2239SPaul Durrant     len = g_vasprintf(&value, fmt, ap);
81094a2239SPaul Durrant 
82094a2239SPaul Durrant     trace_xs_node_vprintf(path, value);
83094a2239SPaul Durrant 
84*ba2a92dbSPaul Durrant     if (!qemu_xen_xs_write(h, tid, path, value, len)) {
85094a2239SPaul Durrant         error_setg_errno(errp, errno, "failed to write '%s' to '%s'",
86094a2239SPaul Durrant                          value, path);
87094a2239SPaul Durrant     }
88094a2239SPaul Durrant 
89094a2239SPaul Durrant     g_free(value);
90094a2239SPaul Durrant     g_free(path);
91094a2239SPaul Durrant }
92094a2239SPaul Durrant 
xs_node_printf(struct qemu_xs_handle * h,xs_transaction_t tid,const char * node,const char * key,Error ** errp,const char * fmt,...)93*ba2a92dbSPaul Durrant void xs_node_printf(struct qemu_xs_handle *h,  xs_transaction_t tid,
94094a2239SPaul Durrant                     const char *node, const char *key, Error **errp,
95094a2239SPaul Durrant                     const char *fmt, ...)
96094a2239SPaul Durrant {
97094a2239SPaul Durrant     va_list ap;
98094a2239SPaul Durrant 
99094a2239SPaul Durrant     va_start(ap, fmt);
100*ba2a92dbSPaul Durrant     xs_node_vprintf(h, tid, node, key, errp, fmt, ap);
101094a2239SPaul Durrant     va_end(ap);
102094a2239SPaul Durrant }
103094a2239SPaul Durrant 
xs_node_vscanf(struct qemu_xs_handle * h,xs_transaction_t tid,const char * node,const char * key,Error ** errp,const char * fmt,va_list ap)104*ba2a92dbSPaul Durrant int xs_node_vscanf(struct qemu_xs_handle *h,  xs_transaction_t tid,
105094a2239SPaul Durrant                    const char *node, const char *key, Error **errp,
106094a2239SPaul Durrant                    const char *fmt, va_list ap)
107094a2239SPaul Durrant {
108094a2239SPaul Durrant     char *path, *value;
109094a2239SPaul Durrant     int rc;
110094a2239SPaul Durrant 
111094a2239SPaul Durrant     path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
112094a2239SPaul Durrant         g_strdup(key);
113*ba2a92dbSPaul Durrant     value = qemu_xen_xs_read(h, tid, path, NULL);
114094a2239SPaul Durrant 
115094a2239SPaul Durrant     trace_xs_node_vscanf(path, value);
116094a2239SPaul Durrant 
117094a2239SPaul Durrant     if (value) {
118094a2239SPaul Durrant         rc = vsscanf(value, fmt, ap);
119094a2239SPaul Durrant     } else {
120094a2239SPaul Durrant         error_setg_errno(errp, errno, "failed to read from '%s'",
121094a2239SPaul Durrant                          path);
122094a2239SPaul Durrant         rc = EOF;
123094a2239SPaul Durrant     }
124094a2239SPaul Durrant 
125094a2239SPaul Durrant     free(value);
126094a2239SPaul Durrant     g_free(path);
127094a2239SPaul Durrant 
128094a2239SPaul Durrant     return rc;
129094a2239SPaul Durrant }
130094a2239SPaul Durrant 
xs_node_scanf(struct qemu_xs_handle * h,xs_transaction_t tid,const char * node,const char * key,Error ** errp,const char * fmt,...)131*ba2a92dbSPaul Durrant int xs_node_scanf(struct qemu_xs_handle *h,  xs_transaction_t tid,
132094a2239SPaul Durrant                   const char *node, const char *key, Error **errp,
133094a2239SPaul Durrant                   const char *fmt, ...)
134094a2239SPaul Durrant {
135094a2239SPaul Durrant     va_list ap;
136094a2239SPaul Durrant     int rc;
137094a2239SPaul Durrant 
138094a2239SPaul Durrant     va_start(ap, fmt);
139*ba2a92dbSPaul Durrant     rc = xs_node_vscanf(h, tid, node, key, errp, fmt, ap);
140094a2239SPaul Durrant     va_end(ap);
141094a2239SPaul Durrant 
142094a2239SPaul Durrant     return rc;
143094a2239SPaul Durrant }
14482a29e30SPaul Durrant 
xs_node_watch(struct qemu_xs_handle * h,const char * node,const char * key,xs_watch_fn fn,void * opaque,Error ** errp)145*ba2a92dbSPaul Durrant struct qemu_xs_watch *xs_node_watch(struct qemu_xs_handle *h, const char *node,
146*ba2a92dbSPaul Durrant                                     const char *key, xs_watch_fn fn,
147*ba2a92dbSPaul Durrant                                     void *opaque, Error **errp)
14882a29e30SPaul Durrant {
14982a29e30SPaul Durrant     char *path;
150*ba2a92dbSPaul Durrant     struct qemu_xs_watch *w;
15182a29e30SPaul Durrant 
15282a29e30SPaul Durrant     path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
15382a29e30SPaul Durrant         g_strdup(key);
15482a29e30SPaul Durrant 
15582a29e30SPaul Durrant     trace_xs_node_watch(path);
15682a29e30SPaul Durrant 
157*ba2a92dbSPaul Durrant     w = qemu_xen_xs_watch(h, path, fn, opaque);
158*ba2a92dbSPaul Durrant     if (!w) {
15982a29e30SPaul Durrant         error_setg_errno(errp, errno, "failed to watch node '%s'", path);
16082a29e30SPaul Durrant     }
16182a29e30SPaul Durrant 
16282a29e30SPaul Durrant     g_free(path);
163*ba2a92dbSPaul Durrant 
164*ba2a92dbSPaul Durrant     return w;
16582a29e30SPaul Durrant }
16682a29e30SPaul Durrant 
xs_node_unwatch(struct qemu_xs_handle * h,struct qemu_xs_watch * w)167*ba2a92dbSPaul Durrant void xs_node_unwatch(struct qemu_xs_handle *h, struct qemu_xs_watch *w)
16882a29e30SPaul Durrant {
169*ba2a92dbSPaul Durrant     qemu_xen_xs_unwatch(h, w);
17082a29e30SPaul Durrant }
171