summaryrefslogtreecommitdiff
path: root/hmp.c
diff options
context:
space:
mode:
authorAnas Nashif <anas.nashif@intel.com>2013-01-15 13:31:42 -0800
committerAnas Nashif <anas.nashif@intel.com>2013-01-15 13:31:42 -0800
commit42bf3037d458a330856a0be584200c1e41c3f417 (patch)
tree25b9be1088727757e52271e25a446e8a852357df /hmp.c
parent060629c6ef0b7e5c267d84c91600113264d33120 (diff)
downloadqemu-42bf3037d458a330856a0be584200c1e41c3f417.tar.gz
qemu-42bf3037d458a330856a0be584200c1e41c3f417.tar.bz2
qemu-42bf3037d458a330856a0be584200c1e41c3f417.zip
Imported Upstream version 1.3.0upstream/1.3.0
Diffstat (limited to 'hmp.c')
-rw-r--r--hmp.c253
1 files changed, 243 insertions, 10 deletions
diff --git a/hmp.c b/hmp.c
index 81c8acb67..180ba2bfd 100644
--- a/hmp.c
+++ b/hmp.c
@@ -18,7 +18,9 @@
#include "qemu-option.h"
#include "qemu-timer.h"
#include "qmp-commands.h"
+#include "qemu_socket.h"
#include "monitor.h"
+#include "console.h"
static void hmp_handle_error(Monitor *mon, Error **errp)
{
@@ -151,6 +153,14 @@ void hmp_info_migrate(Monitor *mon)
monitor_printf(mon, "Migration status: %s\n", info->status);
monitor_printf(mon, "total time: %" PRIu64 " milliseconds\n",
info->total_time);
+ if (info->has_expected_downtime) {
+ monitor_printf(mon, "expected downtime: %" PRIu64 " milliseconds\n",
+ info->expected_downtime);
+ }
+ if (info->has_downtime) {
+ monitor_printf(mon, "downtime: %" PRIu64 " milliseconds\n",
+ info->downtime);
+ }
}
if (info->has_ram) {
@@ -166,6 +176,10 @@ void hmp_info_migrate(Monitor *mon)
info->ram->normal);
monitor_printf(mon, "normal bytes: %" PRIu64 " kbytes\n",
info->ram->normal_bytes >> 10);
+ if (info->ram->dirty_pages_rate) {
+ monitor_printf(mon, "dirty pages rate: %" PRIu64 " pages\n",
+ info->ram->dirty_pages_rate);
+ }
}
if (info->has_disk) {
@@ -232,20 +246,19 @@ void hmp_info_cpus(Monitor *mon)
active = '*';
}
- monitor_printf(mon, "%c CPU #%" PRId64 ": ", active, cpu->value->CPU);
+ monitor_printf(mon, "%c CPU #%" PRId64 ":", active, cpu->value->CPU);
if (cpu->value->has_pc) {
- monitor_printf(mon, "pc=0x%016" PRIx64, cpu->value->pc);
+ monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->pc);
}
if (cpu->value->has_nip) {
- monitor_printf(mon, "nip=0x%016" PRIx64, cpu->value->nip);
+ monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->nip);
}
if (cpu->value->has_npc) {
- monitor_printf(mon, "pc=0x%016" PRIx64, cpu->value->pc);
- monitor_printf(mon, "npc=0x%016" PRIx64, cpu->value->npc);
+ monitor_printf(mon, " npc=0x%016" PRIx64, cpu->value->npc);
}
if (cpu->value->has_PC) {
- monitor_printf(mon, "PC=0x%016" PRIx64, cpu->value->PC);
+ monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->PC);
}
if (cpu->value->halted) {
@@ -413,6 +426,8 @@ void hmp_info_spice(Monitor *mon)
monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n",
info->host, info->tls_port);
}
+ monitor_printf(mon, " migrated: %s\n",
+ info->migrated ? "true" : "false");
monitor_printf(mon, " auth: %s\n", info->auth);
monitor_printf(mon, " compiled: %s\n", info->compiled_version);
monitor_printf(mon, " mouse-mode: %s\n",
@@ -756,6 +771,35 @@ void hmp_block_resize(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, &errp);
}
+void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
+{
+ const char *device = qdict_get_str(qdict, "device");
+ const char *filename = qdict_get_str(qdict, "target");
+ const char *format = qdict_get_try_str(qdict, "format");
+ int reuse = qdict_get_try_bool(qdict, "reuse", 0);
+ int full = qdict_get_try_bool(qdict, "full", 0);
+ enum NewImageMode mode;
+ Error *errp = NULL;
+
+ if (!filename) {
+ error_set(&errp, QERR_MISSING_PARAMETER, "target");
+ hmp_handle_error(mon, &errp);
+ return;
+ }
+
+ if (reuse) {
+ mode = NEW_IMAGE_MODE_EXISTING;
+ } else {
+ mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
+ }
+
+ qmp_drive_mirror(device, filename, !!format, format,
+ full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
+ true, mode, false, 0,
+ false, 0, false, 0, &errp);
+ hmp_handle_error(mon, &errp);
+}
+
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
{
const char *device = qdict_get_str(qdict, "device");
@@ -927,7 +971,8 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict)
int64_t speed = qdict_get_try_int(qdict, "speed", 0);
qmp_block_stream(device, base != NULL, base,
- qdict_haskey(qdict, "speed"), speed, &error);
+ qdict_haskey(qdict, "speed"), speed,
+ BLOCKDEV_ON_ERROR_REPORT, true, &error);
hmp_handle_error(mon, &error);
}
@@ -947,8 +992,39 @@ void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
{
Error *error = NULL;
const char *device = qdict_get_str(qdict, "device");
+ bool force = qdict_get_try_bool(qdict, "force", 0);
- qmp_block_job_cancel(device, &error);
+ qmp_block_job_cancel(device, true, force, &error);
+
+ hmp_handle_error(mon, &error);
+}
+
+void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
+{
+ Error *error = NULL;
+ const char *device = qdict_get_str(qdict, "device");
+
+ qmp_block_job_pause(device, &error);
+
+ hmp_handle_error(mon, &error);
+}
+
+void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
+{
+ Error *error = NULL;
+ const char *device = qdict_get_str(qdict, "device");
+
+ qmp_block_job_resume(device, &error);
+
+ hmp_handle_error(mon, &error);
+}
+
+void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
+{
+ Error *error = NULL;
+ const char *device = qdict_get_str(qdict, "device");
+
+ qmp_block_job_complete(device, &error);
hmp_handle_error(mon, &error);
}
@@ -1039,11 +1115,12 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
{
Error *errp = NULL;
int paging = qdict_get_try_bool(qdict, "paging", 0);
- const char *file = qdict_get_str(qdict, "protocol");
+ const char *file = qdict_get_str(qdict, "filename");
bool has_begin = qdict_haskey(qdict, "begin");
bool has_length = qdict_haskey(qdict, "length");
int64_t begin = 0;
int64_t length = 0;
+ char *prot;
if (has_begin) {
begin = qdict_get_int(qdict, "begin");
@@ -1052,9 +1129,12 @@ void hmp_dump_guest_memory(Monitor *mon, const QDict *qdict)
length = qdict_get_int(qdict, "length");
}
- qmp_dump_guest_memory(paging, file, has_begin, begin, has_length, length,
+ prot = g_strconcat("file:", file, NULL);
+
+ qmp_dump_guest_memory(paging, prot, has_begin, begin, has_length, length,
&errp);
hmp_handle_error(mon, &errp);
+ g_free(prot);
}
void hmp_netdev_add(Monitor *mon, const QDict *qdict)
@@ -1102,3 +1182,156 @@ void hmp_closefd(Monitor *mon, const QDict *qdict)
qmp_closefd(fdname, &errp);
hmp_handle_error(mon, &errp);
}
+
+void hmp_send_key(Monitor *mon, const QDict *qdict)
+{
+ const char *keys = qdict_get_str(qdict, "keys");
+ KeyValueList *keylist, *head = NULL, *tmp = NULL;
+ int has_hold_time = qdict_haskey(qdict, "hold-time");
+ int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
+ Error *err = NULL;
+ char keyname_buf[16];
+ char *separator;
+ int keyname_len;
+
+ while (1) {
+ separator = strchr(keys, '-');
+ keyname_len = separator ? separator - keys : strlen(keys);
+ pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
+
+ /* Be compatible with old interface, convert user inputted "<" */
+ if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
+ pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
+ keyname_len = 4;
+ }
+ keyname_buf[keyname_len] = 0;
+
+ keylist = g_malloc0(sizeof(*keylist));
+ keylist->value = g_malloc0(sizeof(*keylist->value));
+
+ if (!head) {
+ head = keylist;
+ }
+ if (tmp) {
+ tmp->next = keylist;
+ }
+ tmp = keylist;
+
+ if (strstart(keyname_buf, "0x", NULL)) {
+ char *endp;
+ int value = strtoul(keyname_buf, &endp, 0);
+ if (*endp != '\0') {
+ goto err_out;
+ }
+ keylist->value->kind = KEY_VALUE_KIND_NUMBER;
+ keylist->value->number = value;
+ } else {
+ int idx = index_from_key(keyname_buf);
+ if (idx == Q_KEY_CODE_MAX) {
+ goto err_out;
+ }
+ keylist->value->kind = KEY_VALUE_KIND_QCODE;
+ keylist->value->qcode = idx;
+ }
+
+ if (!separator) {
+ break;
+ }
+ keys = separator + 1;
+ }
+
+ qmp_send_key(head, has_hold_time, hold_time, &err);
+ hmp_handle_error(mon, &err);
+
+out:
+ qapi_free_KeyValueList(head);
+ return;
+
+err_out:
+ monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
+ goto out;
+}
+
+void hmp_screen_dump(Monitor *mon, const QDict *qdict)
+{
+ const char *filename = qdict_get_str(qdict, "filename");
+ Error *err = NULL;
+
+ qmp_screendump(filename, &err);
+ hmp_handle_error(mon, &err);
+}
+
+void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
+{
+ const char *uri = qdict_get_str(qdict, "uri");
+ int writable = qdict_get_try_bool(qdict, "writable", 0);
+ int all = qdict_get_try_bool(qdict, "all", 0);
+ Error *local_err = NULL;
+ BlockInfoList *block_list, *info;
+ SocketAddress *addr;
+
+ if (writable && !all) {
+ error_setg(&local_err, "-w only valid together with -a");
+ goto exit;
+ }
+
+ /* First check if the address is valid and start the server. */
+ addr = socket_parse(uri, &local_err);
+ if (local_err != NULL) {
+ goto exit;
+ }
+
+ qmp_nbd_server_start(addr, &local_err);
+ qapi_free_SocketAddress(addr);
+ if (local_err != NULL) {
+ goto exit;
+ }
+
+ if (!all) {
+ return;
+ }
+
+ /* Then try adding all block devices. If one fails, close all and
+ * exit.
+ */
+ block_list = qmp_query_block(NULL);
+
+ for (info = block_list; info; info = info->next) {
+ if (!info->value->has_inserted) {
+ continue;
+ }
+
+ qmp_nbd_server_add(info->value->device, true, writable, &local_err);
+
+ if (local_err != NULL) {
+ qmp_nbd_server_stop(NULL);
+ break;
+ }
+ }
+
+ qapi_free_BlockInfoList(block_list);
+
+exit:
+ hmp_handle_error(mon, &local_err);
+}
+
+void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
+{
+ const char *device = qdict_get_str(qdict, "device");
+ int writable = qdict_get_try_bool(qdict, "writable", 0);
+ Error *local_err = NULL;
+
+ qmp_nbd_server_add(device, true, writable, &local_err);
+
+ if (local_err != NULL) {
+ hmp_handle_error(mon, &local_err);
+ }
+}
+
+void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
+{
+ Error *errp = NULL;
+
+ qmp_nbd_server_stop(&errp);
+ hmp_handle_error(mon, &errp);
+}