xen-bus-helper.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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/sysbus.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. #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 xs_handle *xsh, xs_transaction_t tid,
  42. const char *node, struct xs_permissions perms[],
  43. unsigned int nr_perms, Error **errp)
  44. {
  45. trace_xs_node_create(node);
  46. if (!xs_write(xsh, tid, node, "", 0)) {
  47. error_setg_errno(errp, errno, "failed to create node '%s'", node);
  48. return;
  49. }
  50. if (!xs_set_permissions(xsh, tid, node, perms, nr_perms)) {
  51. error_setg_errno(errp, errno, "failed to set node '%s' permissions",
  52. node);
  53. }
  54. }
  55. void xs_node_destroy(struct xs_handle *xsh, xs_transaction_t tid,
  56. const char *node, Error **errp)
  57. {
  58. trace_xs_node_destroy(node);
  59. if (!xs_rm(xsh, tid, node)) {
  60. error_setg_errno(errp, errno, "failed to destroy node '%s'", node);
  61. }
  62. }
  63. void xs_node_vprintf(struct xs_handle *xsh, xs_transaction_t tid,
  64. const char *node, const char *key, Error **errp,
  65. const char *fmt, va_list ap)
  66. {
  67. char *path, *value;
  68. int len;
  69. path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
  70. g_strdup(key);
  71. len = g_vasprintf(&value, fmt, ap);
  72. trace_xs_node_vprintf(path, value);
  73. if (!xs_write(xsh, tid, path, value, len)) {
  74. error_setg_errno(errp, errno, "failed to write '%s' to '%s'",
  75. value, path);
  76. }
  77. g_free(value);
  78. g_free(path);
  79. }
  80. void xs_node_printf(struct xs_handle *xsh, xs_transaction_t tid,
  81. const char *node, const char *key, Error **errp,
  82. const char *fmt, ...)
  83. {
  84. va_list ap;
  85. va_start(ap, fmt);
  86. xs_node_vprintf(xsh, tid, node, key, errp, fmt, ap);
  87. va_end(ap);
  88. }
  89. int xs_node_vscanf(struct xs_handle *xsh, xs_transaction_t tid,
  90. const char *node, const char *key, Error **errp,
  91. const char *fmt, va_list ap)
  92. {
  93. char *path, *value;
  94. int rc;
  95. path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
  96. g_strdup(key);
  97. value = xs_read(xsh, tid, path, NULL);
  98. trace_xs_node_vscanf(path, value);
  99. if (value) {
  100. rc = vsscanf(value, fmt, ap);
  101. } else {
  102. error_setg_errno(errp, errno, "failed to read from '%s'",
  103. path);
  104. rc = EOF;
  105. }
  106. free(value);
  107. g_free(path);
  108. return rc;
  109. }
  110. int xs_node_scanf(struct xs_handle *xsh, xs_transaction_t tid,
  111. const char *node, const char *key, Error **errp,
  112. const char *fmt, ...)
  113. {
  114. va_list ap;
  115. int rc;
  116. va_start(ap, fmt);
  117. rc = xs_node_vscanf(xsh, tid, node, key, errp, fmt, ap);
  118. va_end(ap);
  119. return rc;
  120. }
  121. void xs_node_watch(struct xs_handle *xsh, const char *node, const char *key,
  122. char *token, Error **errp)
  123. {
  124. char *path;
  125. path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
  126. g_strdup(key);
  127. trace_xs_node_watch(path);
  128. if (!xs_watch(xsh, path, token)) {
  129. error_setg_errno(errp, errno, "failed to watch node '%s'", path);
  130. }
  131. g_free(path);
  132. }
  133. void xs_node_unwatch(struct xs_handle *xsh, const char *node,
  134. const char *key, const char *token, Error **errp)
  135. {
  136. char *path;
  137. path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) :
  138. g_strdup(key);
  139. trace_xs_node_unwatch(path);
  140. if (!xs_unwatch(xsh, path, token)) {
  141. error_setg_errno(errp, errno, "failed to unwatch node '%s'", path);
  142. }
  143. g_free(path);
  144. }