qmp-cmds.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601
  1. /*
  2. * QEMU Management Protocol commands
  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 GPL, version 2. See
  10. * the COPYING file in the top-level directory.
  11. *
  12. * Contributions after 2012-01-13 are licensed under the terms of the
  13. * GNU GPL, version 2 or (at your option) any later version.
  14. */
  15. #include "qemu/osdep.h"
  16. #include "qemu/cutils.h"
  17. #include "qemu/option.h"
  18. #include "monitor/monitor.h"
  19. #include "sysemu/sysemu.h"
  20. #include "qemu/config-file.h"
  21. #include "qemu/uuid.h"
  22. #include "chardev/char.h"
  23. #include "ui/qemu-spice.h"
  24. #include "ui/console.h"
  25. #include "ui/dbus-display.h"
  26. #include "sysemu/kvm.h"
  27. #include "sysemu/runstate.h"
  28. #include "sysemu/runstate-action.h"
  29. #include "sysemu/blockdev.h"
  30. #include "sysemu/block-backend.h"
  31. #include "qapi/error.h"
  32. #include "qapi/qapi-commands-acpi.h"
  33. #include "qapi/qapi-commands-block.h"
  34. #include "qapi/qapi-commands-control.h"
  35. #include "qapi/qapi-commands-machine.h"
  36. #include "qapi/qapi-commands-misc.h"
  37. #include "qapi/qapi-commands-stats.h"
  38. #include "qapi/qapi-commands-ui.h"
  39. #include "qapi/type-helpers.h"
  40. #include "qapi/qmp/qerror.h"
  41. #include "exec/ramlist.h"
  42. #include "hw/mem/memory-device.h"
  43. #include "hw/acpi/acpi_dev_interface.h"
  44. #include "hw/intc/intc.h"
  45. #include "hw/rdma/rdma.h"
  46. #include "monitor/stats.h"
  47. NameInfo *qmp_query_name(Error **errp)
  48. {
  49. NameInfo *info = g_malloc0(sizeof(*info));
  50. if (qemu_name) {
  51. info->has_name = true;
  52. info->name = g_strdup(qemu_name);
  53. }
  54. return info;
  55. }
  56. KvmInfo *qmp_query_kvm(Error **errp)
  57. {
  58. KvmInfo *info = g_malloc0(sizeof(*info));
  59. info->enabled = kvm_enabled();
  60. info->present = accel_find("kvm");
  61. return info;
  62. }
  63. UuidInfo *qmp_query_uuid(Error **errp)
  64. {
  65. UuidInfo *info = g_malloc0(sizeof(*info));
  66. info->UUID = qemu_uuid_unparse_strdup(&qemu_uuid);
  67. return info;
  68. }
  69. void qmp_quit(Error **errp)
  70. {
  71. shutdown_action = SHUTDOWN_ACTION_POWEROFF;
  72. qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_QMP_QUIT);
  73. }
  74. void qmp_stop(Error **errp)
  75. {
  76. /* if there is a dump in background, we should wait until the dump
  77. * finished */
  78. if (qemu_system_dump_in_progress()) {
  79. error_setg(errp, "There is a dump in process, please wait.");
  80. return;
  81. }
  82. if (runstate_check(RUN_STATE_INMIGRATE)) {
  83. autostart = 0;
  84. } else {
  85. vm_stop(RUN_STATE_PAUSED);
  86. }
  87. }
  88. void qmp_system_reset(Error **errp)
  89. {
  90. qemu_system_reset_request(SHUTDOWN_CAUSE_HOST_QMP_SYSTEM_RESET);
  91. }
  92. void qmp_system_powerdown(Error **errp)
  93. {
  94. qemu_system_powerdown_request();
  95. }
  96. void qmp_cont(Error **errp)
  97. {
  98. BlockBackend *blk;
  99. BlockJob *job;
  100. Error *local_err = NULL;
  101. /* if there is a dump in background, we should wait until the dump
  102. * finished */
  103. if (qemu_system_dump_in_progress()) {
  104. error_setg(errp, "There is a dump in process, please wait.");
  105. return;
  106. }
  107. if (runstate_needs_reset()) {
  108. error_setg(errp, "Resetting the Virtual Machine is required");
  109. return;
  110. } else if (runstate_check(RUN_STATE_SUSPENDED)) {
  111. return;
  112. } else if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
  113. error_setg(errp, "Migration is not finalized yet");
  114. return;
  115. }
  116. for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
  117. blk_iostatus_reset(blk);
  118. }
  119. WITH_JOB_LOCK_GUARD() {
  120. for (job = block_job_next_locked(NULL); job;
  121. job = block_job_next_locked(job)) {
  122. block_job_iostatus_reset_locked(job);
  123. }
  124. }
  125. /* Continuing after completed migration. Images have been inactivated to
  126. * allow the destination to take control. Need to get control back now.
  127. *
  128. * If there are no inactive block nodes (e.g. because the VM was just
  129. * paused rather than completing a migration), bdrv_inactivate_all() simply
  130. * doesn't do anything. */
  131. bdrv_activate_all(&local_err);
  132. if (local_err) {
  133. error_propagate(errp, local_err);
  134. return;
  135. }
  136. if (runstate_check(RUN_STATE_INMIGRATE)) {
  137. autostart = 1;
  138. } else {
  139. vm_start();
  140. }
  141. }
  142. void qmp_system_wakeup(Error **errp)
  143. {
  144. if (!qemu_wakeup_suspend_enabled()) {
  145. error_setg(errp,
  146. "wake-up from suspend is not supported by this guest");
  147. return;
  148. }
  149. qemu_system_wakeup_request(QEMU_WAKEUP_REASON_OTHER, errp);
  150. }
  151. void qmp_set_password(SetPasswordOptions *opts, Error **errp)
  152. {
  153. int rc;
  154. if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
  155. if (!qemu_using_spice(errp)) {
  156. return;
  157. }
  158. rc = qemu_spice.set_passwd(opts->password,
  159. opts->connected == SET_PASSWORD_ACTION_FAIL,
  160. opts->connected == SET_PASSWORD_ACTION_DISCONNECT);
  161. } else {
  162. assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
  163. if (opts->connected != SET_PASSWORD_ACTION_KEEP) {
  164. /* vnc supports "connected=keep" only */
  165. error_setg(errp, QERR_INVALID_PARAMETER, "connected");
  166. return;
  167. }
  168. /* Note that setting an empty password will not disable login through
  169. * this interface. */
  170. rc = vnc_display_password(opts->u.vnc.display, opts->password);
  171. }
  172. if (rc != 0) {
  173. error_setg(errp, "Could not set password");
  174. }
  175. }
  176. void qmp_expire_password(ExpirePasswordOptions *opts, Error **errp)
  177. {
  178. time_t when;
  179. int rc;
  180. const char *whenstr = opts->time;
  181. if (strcmp(whenstr, "now") == 0) {
  182. when = 0;
  183. } else if (strcmp(whenstr, "never") == 0) {
  184. when = TIME_MAX;
  185. } else if (whenstr[0] == '+') {
  186. when = time(NULL) + strtoull(whenstr+1, NULL, 10);
  187. } else {
  188. when = strtoull(whenstr, NULL, 10);
  189. }
  190. if (opts->protocol == DISPLAY_PROTOCOL_SPICE) {
  191. if (!qemu_using_spice(errp)) {
  192. return;
  193. }
  194. rc = qemu_spice.set_pw_expire(when);
  195. } else {
  196. assert(opts->protocol == DISPLAY_PROTOCOL_VNC);
  197. rc = vnc_display_pw_expire(opts->u.vnc.display, when);
  198. }
  199. if (rc != 0) {
  200. error_setg(errp, "Could not set password expire time");
  201. }
  202. }
  203. #ifdef CONFIG_VNC
  204. void qmp_change_vnc_password(const char *password, Error **errp)
  205. {
  206. if (vnc_display_password(NULL, password) < 0) {
  207. error_setg(errp, "Could not set password");
  208. }
  209. }
  210. #endif
  211. void qmp_add_client(const char *protocol, const char *fdname,
  212. bool has_skipauth, bool skipauth, bool has_tls, bool tls,
  213. Error **errp)
  214. {
  215. Chardev *s;
  216. int fd;
  217. fd = monitor_get_fd(monitor_cur(), fdname, errp);
  218. if (fd < 0) {
  219. return;
  220. }
  221. if (strcmp(protocol, "spice") == 0) {
  222. if (!qemu_using_spice(errp)) {
  223. close(fd);
  224. return;
  225. }
  226. skipauth = has_skipauth ? skipauth : false;
  227. tls = has_tls ? tls : false;
  228. if (qemu_spice.display_add_client(fd, skipauth, tls) < 0) {
  229. error_setg(errp, "spice failed to add client");
  230. close(fd);
  231. }
  232. return;
  233. #ifdef CONFIG_VNC
  234. } else if (strcmp(protocol, "vnc") == 0) {
  235. skipauth = has_skipauth ? skipauth : false;
  236. vnc_display_add_client(NULL, fd, skipauth);
  237. return;
  238. #endif
  239. #ifdef CONFIG_DBUS_DISPLAY
  240. } else if (strcmp(protocol, "@dbus-display") == 0) {
  241. if (!qemu_using_dbus_display(errp)) {
  242. close(fd);
  243. return;
  244. }
  245. if (!qemu_dbus_display.add_client(fd, errp)) {
  246. close(fd);
  247. return;
  248. }
  249. return;
  250. #endif
  251. } else if ((s = qemu_chr_find(protocol)) != NULL) {
  252. if (qemu_chr_add_client(s, fd) < 0) {
  253. error_setg(errp, "failed to add client");
  254. close(fd);
  255. return;
  256. }
  257. return;
  258. }
  259. error_setg(errp, "protocol '%s' is invalid", protocol);
  260. close(fd);
  261. }
  262. MemoryDeviceInfoList *qmp_query_memory_devices(Error **errp)
  263. {
  264. return qmp_memory_device_list();
  265. }
  266. ACPIOSTInfoList *qmp_query_acpi_ospm_status(Error **errp)
  267. {
  268. bool ambig;
  269. ACPIOSTInfoList *head = NULL;
  270. ACPIOSTInfoList **prev = &head;
  271. Object *obj = object_resolve_path_type("", TYPE_ACPI_DEVICE_IF, &ambig);
  272. if (obj) {
  273. AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
  274. AcpiDeviceIf *adev = ACPI_DEVICE_IF(obj);
  275. adevc->ospm_status(adev, &prev);
  276. } else {
  277. error_setg(errp, "command is not supported, missing ACPI device");
  278. }
  279. return head;
  280. }
  281. MemoryInfo *qmp_query_memory_size_summary(Error **errp)
  282. {
  283. MemoryInfo *mem_info = g_new0(MemoryInfo, 1);
  284. MachineState *ms = MACHINE(qdev_get_machine());
  285. mem_info->base_memory = ms->ram_size;
  286. mem_info->plugged_memory = get_plugged_memory_size();
  287. mem_info->has_plugged_memory =
  288. mem_info->plugged_memory != (uint64_t)-1;
  289. return mem_info;
  290. }
  291. void qmp_display_reload(DisplayReloadOptions *arg, Error **errp)
  292. {
  293. switch (arg->type) {
  294. case DISPLAY_RELOAD_TYPE_VNC:
  295. #ifdef CONFIG_VNC
  296. if (arg->u.vnc.has_tls_certs && arg->u.vnc.tls_certs) {
  297. vnc_display_reload_certs(NULL, errp);
  298. }
  299. #else
  300. error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
  301. #endif
  302. break;
  303. default:
  304. abort();
  305. }
  306. }
  307. void qmp_display_update(DisplayUpdateOptions *arg, Error **errp)
  308. {
  309. switch (arg->type) {
  310. case DISPLAY_UPDATE_TYPE_VNC:
  311. #ifdef CONFIG_VNC
  312. vnc_display_update(&arg->u.vnc, errp);
  313. #else
  314. error_setg(errp, "vnc is invalid, missing 'CONFIG_VNC'");
  315. #endif
  316. break;
  317. default:
  318. abort();
  319. }
  320. }
  321. static int qmp_x_query_rdma_foreach(Object *obj, void *opaque)
  322. {
  323. RdmaProvider *rdma;
  324. RdmaProviderClass *k;
  325. GString *buf = opaque;
  326. if (object_dynamic_cast(obj, INTERFACE_RDMA_PROVIDER)) {
  327. rdma = RDMA_PROVIDER(obj);
  328. k = RDMA_PROVIDER_GET_CLASS(obj);
  329. if (k->format_statistics) {
  330. k->format_statistics(rdma, buf);
  331. } else {
  332. g_string_append_printf(buf,
  333. "RDMA statistics not available for %s.\n",
  334. object_get_typename(obj));
  335. }
  336. }
  337. return 0;
  338. }
  339. HumanReadableText *qmp_x_query_rdma(Error **errp)
  340. {
  341. g_autoptr(GString) buf = g_string_new("");
  342. object_child_foreach_recursive(object_get_root(),
  343. qmp_x_query_rdma_foreach, buf);
  344. return human_readable_text_from_str(buf);
  345. }
  346. HumanReadableText *qmp_x_query_ramblock(Error **errp)
  347. {
  348. g_autoptr(GString) buf = ram_block_format();
  349. return human_readable_text_from_str(buf);
  350. }
  351. static int qmp_x_query_irq_foreach(Object *obj, void *opaque)
  352. {
  353. InterruptStatsProvider *intc;
  354. InterruptStatsProviderClass *k;
  355. GString *buf = opaque;
  356. if (object_dynamic_cast(obj, TYPE_INTERRUPT_STATS_PROVIDER)) {
  357. intc = INTERRUPT_STATS_PROVIDER(obj);
  358. k = INTERRUPT_STATS_PROVIDER_GET_CLASS(obj);
  359. uint64_t *irq_counts;
  360. unsigned int nb_irqs, i;
  361. if (k->get_statistics &&
  362. k->get_statistics(intc, &irq_counts, &nb_irqs)) {
  363. if (nb_irqs > 0) {
  364. g_string_append_printf(buf, "IRQ statistics for %s:\n",
  365. object_get_typename(obj));
  366. for (i = 0; i < nb_irqs; i++) {
  367. if (irq_counts[i] > 0) {
  368. g_string_append_printf(buf, "%2d: %" PRId64 "\n", i,
  369. irq_counts[i]);
  370. }
  371. }
  372. }
  373. } else {
  374. g_string_append_printf(buf,
  375. "IRQ statistics not available for %s.\n",
  376. object_get_typename(obj));
  377. }
  378. }
  379. return 0;
  380. }
  381. HumanReadableText *qmp_x_query_irq(Error **errp)
  382. {
  383. g_autoptr(GString) buf = g_string_new("");
  384. object_child_foreach_recursive(object_get_root(),
  385. qmp_x_query_irq_foreach, buf);
  386. return human_readable_text_from_str(buf);
  387. }
  388. typedef struct StatsCallbacks {
  389. StatsProvider provider;
  390. StatRetrieveFunc *stats_cb;
  391. SchemaRetrieveFunc *schemas_cb;
  392. QTAILQ_ENTRY(StatsCallbacks) next;
  393. } StatsCallbacks;
  394. static QTAILQ_HEAD(, StatsCallbacks) stats_callbacks =
  395. QTAILQ_HEAD_INITIALIZER(stats_callbacks);
  396. void add_stats_callbacks(StatsProvider provider,
  397. StatRetrieveFunc *stats_fn,
  398. SchemaRetrieveFunc *schemas_fn)
  399. {
  400. StatsCallbacks *entry = g_new(StatsCallbacks, 1);
  401. entry->provider = provider;
  402. entry->stats_cb = stats_fn;
  403. entry->schemas_cb = schemas_fn;
  404. QTAILQ_INSERT_TAIL(&stats_callbacks, entry, next);
  405. }
  406. static bool invoke_stats_cb(StatsCallbacks *entry,
  407. StatsResultList **stats_results,
  408. StatsFilter *filter, StatsRequest *request,
  409. Error **errp)
  410. {
  411. strList *targets = NULL;
  412. strList *names = NULL;
  413. ERRP_GUARD();
  414. if (request) {
  415. if (request->provider != entry->provider) {
  416. return true;
  417. }
  418. if (request->has_names && !request->names) {
  419. return true;
  420. }
  421. names = request->has_names ? request->names : NULL;
  422. }
  423. switch (filter->target) {
  424. case STATS_TARGET_VM:
  425. break;
  426. case STATS_TARGET_VCPU:
  427. if (filter->u.vcpu.has_vcpus) {
  428. if (!filter->u.vcpu.vcpus) {
  429. /* No targets allowed? Return no statistics. */
  430. return true;
  431. }
  432. targets = filter->u.vcpu.vcpus;
  433. }
  434. break;
  435. default:
  436. abort();
  437. }
  438. entry->stats_cb(stats_results, filter->target, names, targets, errp);
  439. if (*errp) {
  440. qapi_free_StatsResultList(*stats_results);
  441. *stats_results = NULL;
  442. return false;
  443. }
  444. return true;
  445. }
  446. StatsResultList *qmp_query_stats(StatsFilter *filter, Error **errp)
  447. {
  448. StatsResultList *stats_results = NULL;
  449. StatsCallbacks *entry;
  450. StatsRequestList *request;
  451. QTAILQ_FOREACH(entry, &stats_callbacks, next) {
  452. if (filter->has_providers) {
  453. for (request = filter->providers; request; request = request->next) {
  454. if (!invoke_stats_cb(entry, &stats_results, filter,
  455. request->value, errp)) {
  456. break;
  457. }
  458. }
  459. } else {
  460. if (!invoke_stats_cb(entry, &stats_results, filter, NULL, errp)) {
  461. break;
  462. }
  463. }
  464. }
  465. return stats_results;
  466. }
  467. StatsSchemaList *qmp_query_stats_schemas(bool has_provider,
  468. StatsProvider provider,
  469. Error **errp)
  470. {
  471. StatsSchemaList *stats_results = NULL;
  472. StatsCallbacks *entry;
  473. ERRP_GUARD();
  474. QTAILQ_FOREACH(entry, &stats_callbacks, next) {
  475. if (!has_provider || provider == entry->provider) {
  476. entry->schemas_cb(&stats_results, errp);
  477. if (*errp) {
  478. qapi_free_StatsSchemaList(stats_results);
  479. return NULL;
  480. }
  481. }
  482. }
  483. return stats_results;
  484. }
  485. void add_stats_entry(StatsResultList **stats_results, StatsProvider provider,
  486. const char *qom_path, StatsList *stats_list)
  487. {
  488. StatsResult *entry = g_new0(StatsResult, 1);
  489. entry->provider = provider;
  490. if (qom_path) {
  491. entry->has_qom_path = true;
  492. entry->qom_path = g_strdup(qom_path);
  493. }
  494. entry->stats = stats_list;
  495. QAPI_LIST_PREPEND(*stats_results, entry);
  496. }
  497. void add_stats_schema(StatsSchemaList **schema_results,
  498. StatsProvider provider, StatsTarget target,
  499. StatsSchemaValueList *stats_list)
  500. {
  501. StatsSchema *entry = g_new0(StatsSchema, 1);
  502. entry->provider = provider;
  503. entry->target = target;
  504. entry->stats = stats_list;
  505. QAPI_LIST_PREPEND(*schema_results, entry);
  506. }
  507. bool apply_str_list_filter(const char *string, strList *list)
  508. {
  509. strList *str_list = NULL;
  510. if (!list) {
  511. return true;
  512. }
  513. for (str_list = list; str_list; str_list = str_list->next) {
  514. if (g_str_equal(string, str_list->value)) {
  515. return true;
  516. }
  517. }
  518. return false;
  519. }