]>
Commit | Line | Data |
---|---|---|
094a2239 PD |
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" | |
094a2239 PD |
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" | |
ba2a92db | 13 | #include "trace.h" |
094a2239 PD |
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 | ||
ba2a92db PD |
50 | void xs_node_create(struct qemu_xs_handle *h, xs_transaction_t tid, |
51 | const char *node, unsigned int owner, unsigned int domid, | |
52 | unsigned int perms, Error **errp) | |
094a2239 PD |
53 | { |
54 | trace_xs_node_create(node); | |
55 | ||
ba2a92db | 56 | if (!qemu_xen_xs_create(h, tid, owner, domid, perms, node)) { |
094a2239 | 57 | error_setg_errno(errp, errno, "failed to create node '%s'", node); |
094a2239 PD |
58 | } |
59 | } | |
60 | ||
ba2a92db | 61 | void xs_node_destroy(struct qemu_xs_handle *h, xs_transaction_t tid, |
094a2239 PD |
62 | const char *node, Error **errp) |
63 | { | |
64 | trace_xs_node_destroy(node); | |
65 | ||
ba2a92db | 66 | if (!qemu_xen_xs_destroy(h, tid, node)) { |
094a2239 PD |
67 | error_setg_errno(errp, errno, "failed to destroy node '%s'", node); |
68 | } | |
69 | } | |
70 | ||
ba2a92db | 71 | void xs_node_vprintf(struct qemu_xs_handle *h, xs_transaction_t tid, |
094a2239 PD |
72 | const char *node, const char *key, Error **errp, |
73 | const char *fmt, va_list ap) | |
74 | { | |
75 | char *path, *value; | |
76 | int len; | |
77 | ||
78 | path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) : | |
79 | g_strdup(key); | |
80 | len = g_vasprintf(&value, fmt, ap); | |
81 | ||
82 | trace_xs_node_vprintf(path, value); | |
83 | ||
ba2a92db | 84 | if (!qemu_xen_xs_write(h, tid, path, value, len)) { |
094a2239 PD |
85 | error_setg_errno(errp, errno, "failed to write '%s' to '%s'", |
86 | value, path); | |
87 | } | |
88 | ||
89 | g_free(value); | |
90 | g_free(path); | |
91 | } | |
92 | ||
ba2a92db | 93 | void xs_node_printf(struct qemu_xs_handle *h, xs_transaction_t tid, |
094a2239 PD |
94 | const char *node, const char *key, Error **errp, |
95 | const char *fmt, ...) | |
96 | { | |
97 | va_list ap; | |
98 | ||
99 | va_start(ap, fmt); | |
ba2a92db | 100 | xs_node_vprintf(h, tid, node, key, errp, fmt, ap); |
094a2239 PD |
101 | va_end(ap); |
102 | } | |
103 | ||
ba2a92db | 104 | int xs_node_vscanf(struct qemu_xs_handle *h, xs_transaction_t tid, |
094a2239 PD |
105 | const char *node, const char *key, Error **errp, |
106 | const char *fmt, va_list ap) | |
107 | { | |
108 | char *path, *value; | |
109 | int rc; | |
110 | ||
111 | path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) : | |
112 | g_strdup(key); | |
ba2a92db | 113 | value = qemu_xen_xs_read(h, tid, path, NULL); |
094a2239 PD |
114 | |
115 | trace_xs_node_vscanf(path, value); | |
116 | ||
117 | if (value) { | |
118 | rc = vsscanf(value, fmt, ap); | |
119 | } else { | |
120 | error_setg_errno(errp, errno, "failed to read from '%s'", | |
121 | path); | |
122 | rc = EOF; | |
123 | } | |
124 | ||
125 | free(value); | |
126 | g_free(path); | |
127 | ||
128 | return rc; | |
129 | } | |
130 | ||
ba2a92db | 131 | int xs_node_scanf(struct qemu_xs_handle *h, xs_transaction_t tid, |
094a2239 PD |
132 | const char *node, const char *key, Error **errp, |
133 | const char *fmt, ...) | |
134 | { | |
135 | va_list ap; | |
136 | int rc; | |
137 | ||
138 | va_start(ap, fmt); | |
ba2a92db | 139 | rc = xs_node_vscanf(h, tid, node, key, errp, fmt, ap); |
094a2239 PD |
140 | va_end(ap); |
141 | ||
142 | return rc; | |
143 | } | |
82a29e30 | 144 | |
ba2a92db PD |
145 | struct qemu_xs_watch *xs_node_watch(struct qemu_xs_handle *h, const char *node, |
146 | const char *key, xs_watch_fn fn, | |
147 | void *opaque, Error **errp) | |
82a29e30 PD |
148 | { |
149 | char *path; | |
ba2a92db | 150 | struct qemu_xs_watch *w; |
82a29e30 PD |
151 | |
152 | path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) : | |
153 | g_strdup(key); | |
154 | ||
155 | trace_xs_node_watch(path); | |
156 | ||
ba2a92db PD |
157 | w = qemu_xen_xs_watch(h, path, fn, opaque); |
158 | if (!w) { | |
82a29e30 PD |
159 | error_setg_errno(errp, errno, "failed to watch node '%s'", path); |
160 | } | |
161 | ||
162 | g_free(path); | |
ba2a92db PD |
163 | |
164 | return w; | |
82a29e30 PD |
165 | } |
166 | ||
ba2a92db | 167 | void xs_node_unwatch(struct qemu_xs_handle *h, struct qemu_xs_watch *w) |
82a29e30 | 168 | { |
ba2a92db | 169 | qemu_xen_xs_unwatch(h, w); |
82a29e30 | 170 | } |