xen-bus-helper.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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. #include "qemu/osdep.h"
  8. #include "hw/xen/xen.h"
  9. #include "hw/xen/xen-bus.h"
  10. #include "hw/xen/xen-bus-helper.h"
  11. #include "qapi/error.h"
  12. #include "trace.h"
  13. #include <glib/gprintf.h>
  14. struct xs_state {
  15. enum xenbus_state statenum;
  16. const char *statestr;
  17. };
  18. #define XS_STATE(state) { state, #state }
  19. static struct xs_state xs_state[] = {
  20. XS_STATE(XenbusStateUnknown),
  21. XS_STATE(XenbusStateInitialising),
  22. XS_STATE(XenbusStateInitWait),
  23. XS_STATE(XenbusStateInitialised),
  24. XS_STATE(XenbusStateConnected),
  25. XS_STATE(XenbusStateClosing),
  26. XS_STATE(XenbusStateClosed),
  27. XS_STATE(XenbusStateReconfiguring),
  28. XS_STATE(XenbusStateReconfigured),
  29. };
  30. #undef XS_STATE
  31. const char *xs_strstate(enum xenbus_state state)
  32. {
  33. unsigned int i;
  34. for (i = 0; i < ARRAY_SIZE(xs_state); i++) {
  35. if (xs_state[i].statenum == state) {
  36. return xs_state[i].statestr;
  37. }
  38. }
  39. return "INVALID";
  40. }
  41. void xs_node_create(struct qemu_xs_handle *h, xs_transaction_t tid,
  42. const char *node, unsigned int owner, unsigned int domid,
  43. unsigned int perms, Error **errp)
  44. {
  45. trace_xs_node_create(node);
  46. if (!qemu_xen_xs_create(h, tid, owner, domid, perms, node)) {
  47. error_setg_errno(errp, errno, "failed to create node '%s'", node);
  48. }
  49. }
  50. void xs_node_destroy(struct qemu_xs_handle *h, xs_transaction_t tid,
  51. const char *node, Error **errp)
  52. {
  53. trace_xs_node_destroy(node);
  54. if (!qemu_xen_xs_destroy(h, tid, node)) {
  55. error_setg_errno(errp, errno, "failed to destroy node '%s'", node);
  56. }
  57. }
  58. void xs_node_vprintf(struct qemu_xs_handle *h, xs_transaction_t tid,
  59. const char *node, const char *key, Error **errp,
  60. const char *fmt, va_list ap)
  61. {
  62. char *path, *value;
  63. int len;
  64. path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
  65. g_strdup(key);
  66. len = g_vasprintf(&value, fmt, ap);
  67. trace_xs_node_vprintf(path, value);
  68. if (!qemu_xen_xs_write(h, tid, path, value, len)) {
  69. error_setg_errno(errp, errno, "failed to write '%s' to '%s'",
  70. value, path);
  71. }
  72. g_free(value);
  73. g_free(path);
  74. }
  75. void xs_node_printf(struct qemu_xs_handle *h, xs_transaction_t tid,
  76. const char *node, const char *key, Error **errp,
  77. const char *fmt, ...)
  78. {
  79. va_list ap;
  80. va_start(ap, fmt);
  81. xs_node_vprintf(h, tid, node, key, errp, fmt, ap);
  82. va_end(ap);
  83. }
  84. int xs_node_vscanf(struct qemu_xs_handle *h, xs_transaction_t tid,
  85. const char *node, const char *key, Error **errp,
  86. const char *fmt, va_list ap)
  87. {
  88. char *value;
  89. int rc;
  90. if (node && strlen(node) != 0) {
  91. value = xs_node_read(h, tid, NULL, errp, "%s/%s", node, key);
  92. } else {
  93. value = xs_node_read(h, tid, NULL, errp, "%s", key);
  94. }
  95. if (value) {
  96. rc = vsscanf(value, fmt, ap);
  97. } else {
  98. rc = EOF;
  99. }
  100. free(value);
  101. return rc;
  102. }
  103. int xs_node_scanf(struct qemu_xs_handle *h, xs_transaction_t tid,
  104. const char *node, const char *key, Error **errp,
  105. const char *fmt, ...)
  106. {
  107. va_list ap;
  108. int rc;
  109. va_start(ap, fmt);
  110. rc = xs_node_vscanf(h, tid, node, key, errp, fmt, ap);
  111. va_end(ap);
  112. return rc;
  113. }
  114. char *xs_node_read(struct qemu_xs_handle *h, xs_transaction_t tid,
  115. unsigned int *len, Error **errp,
  116. const char *path_fmt, ...)
  117. {
  118. char *path, *value;
  119. va_list ap;
  120. va_start(ap, path_fmt);
  121. path = g_strdup_vprintf(path_fmt, ap);
  122. va_end(ap);
  123. value = qemu_xen_xs_read(h, tid, path, len);
  124. trace_xs_node_read(path, value);
  125. if (!value) {
  126. error_setg_errno(errp, errno, "failed to read from '%s'", path);
  127. }
  128. g_free(path);
  129. return value;
  130. }
  131. struct qemu_xs_watch *xs_node_watch(struct qemu_xs_handle *h, const char *node,
  132. const char *key, xs_watch_fn fn,
  133. void *opaque, Error **errp)
  134. {
  135. char *path;
  136. struct qemu_xs_watch *w;
  137. path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
  138. g_strdup(key);
  139. trace_xs_node_watch(path);
  140. w = qemu_xen_xs_watch(h, path, fn, opaque);
  141. if (!w) {
  142. error_setg_errno(errp, errno, "failed to watch node '%s'", path);
  143. }
  144. g_free(path);
  145. return w;
  146. }
  147. void xs_node_unwatch(struct qemu_xs_handle *h, struct qemu_xs_watch *w)
  148. {
  149. qemu_xen_xs_unwatch(h, w);
  150. }