qmp-dispatch.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. /*
  2. * Core Definitions for QAPI/QMP Dispatch
  3. *
  4. * Copyright IBM, Corp. 2011
  5. *
  6. * Authors:
  7. * Anthony Liguori <aliguori@us.ibm.com>
  8. *
  9. * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
  10. * See the COPYING.LIB file in the top-level directory.
  11. *
  12. */
  13. #include "qemu/osdep.h"
  14. #include "block/aio.h"
  15. #include "qapi/compat-policy.h"
  16. #include "qapi/error.h"
  17. #include "qapi/qmp-registry.h"
  18. #include "qobject/qdict.h"
  19. #include "qobject/qjson.h"
  20. #include "qapi/qobject-input-visitor.h"
  21. #include "qapi/qobject-output-visitor.h"
  22. #include "qobject/qbool.h"
  23. #include "qemu/coroutine.h"
  24. #include "qemu/main-loop.h"
  25. Visitor *qobject_input_visitor_new_qmp(QObject *obj)
  26. {
  27. Visitor *v = qobject_input_visitor_new(obj);
  28. visit_set_policy(v, &compat_policy);
  29. return v;
  30. }
  31. Visitor *qobject_output_visitor_new_qmp(QObject **result)
  32. {
  33. Visitor *v = qobject_output_visitor_new(result);
  34. visit_set_policy(v, &compat_policy);
  35. return v;
  36. }
  37. static QDict *qmp_dispatch_check_obj(QDict *dict, bool allow_oob,
  38. Error **errp)
  39. {
  40. const char *exec_key = NULL;
  41. const QDictEntry *ent;
  42. const char *arg_name;
  43. const QObject *arg_obj;
  44. for (ent = qdict_first(dict); ent;
  45. ent = qdict_next(dict, ent)) {
  46. arg_name = qdict_entry_key(ent);
  47. arg_obj = qdict_entry_value(ent);
  48. if (!strcmp(arg_name, "execute")
  49. || (!strcmp(arg_name, "exec-oob") && allow_oob)) {
  50. if (qobject_type(arg_obj) != QTYPE_QSTRING) {
  51. error_setg(errp, "QMP input member '%s' must be a string",
  52. arg_name);
  53. return NULL;
  54. }
  55. if (exec_key) {
  56. error_setg(errp, "QMP input member '%s' clashes with '%s'",
  57. arg_name, exec_key);
  58. return NULL;
  59. }
  60. exec_key = arg_name;
  61. } else if (!strcmp(arg_name, "arguments")) {
  62. if (qobject_type(arg_obj) != QTYPE_QDICT) {
  63. error_setg(errp,
  64. "QMP input member 'arguments' must be an object");
  65. return NULL;
  66. }
  67. } else if (!strcmp(arg_name, "id")) {
  68. continue;
  69. } else {
  70. error_setg(errp, "QMP input member '%s' is unexpected",
  71. arg_name);
  72. return NULL;
  73. }
  74. }
  75. if (!exec_key) {
  76. error_setg(errp, "QMP input lacks member 'execute'");
  77. return NULL;
  78. }
  79. return dict;
  80. }
  81. QDict *qmp_error_response(Error *err)
  82. {
  83. QDict *rsp;
  84. rsp = qdict_from_jsonf_nofail("{ 'error': { 'class': %s, 'desc': %s } }",
  85. QapiErrorClass_str(error_get_class(err)),
  86. error_get_pretty(err));
  87. error_free(err);
  88. return rsp;
  89. }
  90. /*
  91. * Does @qdict look like a command to be run out-of-band?
  92. */
  93. bool qmp_is_oob(const QDict *dict)
  94. {
  95. return qdict_haskey(dict, "exec-oob")
  96. && !qdict_haskey(dict, "execute");
  97. }
  98. typedef struct QmpDispatchBH {
  99. const QmpCommand *cmd;
  100. Monitor *cur_mon;
  101. QDict *args;
  102. QObject **ret;
  103. Error **errp;
  104. Coroutine *co;
  105. } QmpDispatchBH;
  106. static void do_qmp_dispatch_bh(void *opaque)
  107. {
  108. QmpDispatchBH *data = opaque;
  109. assert(monitor_cur() == NULL);
  110. monitor_set_cur(qemu_coroutine_self(), data->cur_mon);
  111. data->cmd->fn(data->args, data->ret, data->errp);
  112. monitor_set_cur(qemu_coroutine_self(), NULL);
  113. aio_co_wake(data->co);
  114. }
  115. /*
  116. * Runs outside of coroutine context for OOB commands, but in coroutine
  117. * context for everything else.
  118. */
  119. QDict *coroutine_mixed_fn qmp_dispatch(const QmpCommandList *cmds, QObject *request,
  120. bool allow_oob, Monitor *cur_mon)
  121. {
  122. Error *err = NULL;
  123. bool oob;
  124. const char *command;
  125. QDict *args;
  126. const QmpCommand *cmd;
  127. QDict *dict;
  128. QObject *id;
  129. QObject *ret = NULL;
  130. QDict *rsp = NULL;
  131. dict = qobject_to(QDict, request);
  132. if (!dict) {
  133. id = NULL;
  134. error_setg(&err, "QMP input must be a JSON object");
  135. goto out;
  136. }
  137. id = qdict_get(dict, "id");
  138. if (!qmp_dispatch_check_obj(dict, allow_oob, &err)) {
  139. goto out;
  140. }
  141. command = qdict_get_try_str(dict, "execute");
  142. oob = false;
  143. if (!command) {
  144. assert(allow_oob);
  145. command = qdict_get_str(dict, "exec-oob");
  146. oob = true;
  147. }
  148. cmd = qmp_find_command(cmds, command);
  149. if (cmd == NULL) {
  150. error_set(&err, ERROR_CLASS_COMMAND_NOT_FOUND,
  151. "The command %s has not been found", command);
  152. goto out;
  153. }
  154. if (!compat_policy_input_ok(cmd->features, &compat_policy,
  155. ERROR_CLASS_COMMAND_NOT_FOUND,
  156. "command", command, &err)) {
  157. goto out;
  158. }
  159. if (!cmd->enabled) {
  160. error_set(&err, ERROR_CLASS_COMMAND_NOT_FOUND,
  161. "Command %s has been disabled%s%s",
  162. command,
  163. cmd->disable_reason ? ": " : "",
  164. cmd->disable_reason ?: "");
  165. goto out;
  166. }
  167. if (oob && !(cmd->options & QCO_ALLOW_OOB)) {
  168. error_setg(&err, "The command %s does not support OOB",
  169. command);
  170. goto out;
  171. }
  172. if (!qmp_command_available(cmd, &err)) {
  173. goto out;
  174. }
  175. if (!qdict_haskey(dict, "arguments")) {
  176. args = qdict_new();
  177. } else {
  178. args = qdict_get_qdict(dict, "arguments");
  179. qobject_ref(args);
  180. }
  181. assert(!(oob && qemu_in_coroutine()));
  182. assert(monitor_cur() == NULL);
  183. if (!!(cmd->options & QCO_COROUTINE) == qemu_in_coroutine()) {
  184. if (qemu_in_coroutine()) {
  185. /*
  186. * Move the coroutine from iohandler_ctx to qemu_aio_context for
  187. * executing the command handler so that it can make progress if it
  188. * involves an AIO_WAIT_WHILE().
  189. */
  190. aio_co_schedule(qemu_get_aio_context(), qemu_coroutine_self());
  191. qemu_coroutine_yield();
  192. }
  193. monitor_set_cur(qemu_coroutine_self(), cur_mon);
  194. cmd->fn(args, &ret, &err);
  195. monitor_set_cur(qemu_coroutine_self(), NULL);
  196. if (qemu_in_coroutine()) {
  197. /*
  198. * Yield and reschedule so the main loop stays responsive.
  199. *
  200. * Move back to iohandler_ctx so that nested event loops for
  201. * qemu_aio_context don't start new monitor commands.
  202. */
  203. aio_co_schedule(iohandler_get_aio_context(),
  204. qemu_coroutine_self());
  205. qemu_coroutine_yield();
  206. }
  207. } else {
  208. /*
  209. * Actual context doesn't match the one the command needs.
  210. *
  211. * Case 1: we are in coroutine context, but command does not
  212. * have QCO_COROUTINE. We need to drop out of coroutine
  213. * context for executing it.
  214. *
  215. * Case 2: we are outside coroutine context, but command has
  216. * QCO_COROUTINE. Can't actually happen, because we get here
  217. * outside coroutine context only when executing a command
  218. * out of band, and OOB commands never have QCO_COROUTINE.
  219. */
  220. assert(!oob && qemu_in_coroutine() && !(cmd->options & QCO_COROUTINE));
  221. QmpDispatchBH data = {
  222. .cur_mon = cur_mon,
  223. .cmd = cmd,
  224. .args = args,
  225. .ret = &ret,
  226. .errp = &err,
  227. .co = qemu_coroutine_self(),
  228. };
  229. aio_bh_schedule_oneshot(iohandler_get_aio_context(), do_qmp_dispatch_bh,
  230. &data);
  231. qemu_coroutine_yield();
  232. }
  233. qobject_unref(args);
  234. if (err) {
  235. /* or assert(!ret) after reviewing all handlers: */
  236. qobject_unref(ret);
  237. goto out;
  238. }
  239. if (cmd->options & QCO_NO_SUCCESS_RESP) {
  240. g_assert(!ret);
  241. return NULL;
  242. } else if (!ret) {
  243. /*
  244. * When the command's schema has no 'returns', cmd->fn()
  245. * leaves @ret null. The QMP spec calls for an empty object
  246. * then; supply it.
  247. */
  248. ret = QOBJECT(qdict_new());
  249. }
  250. rsp = qdict_new();
  251. qdict_put_obj(rsp, "return", ret);
  252. out:
  253. if (err) {
  254. assert(!rsp);
  255. rsp = qmp_error_response(err);
  256. }
  257. assert(rsp);
  258. if (id) {
  259. qdict_put_obj(rsp, "id", qobject_ref(id));
  260. }
  261. return rsp;
  262. }