Merge remote-tracking branch 'qmp/queue/qmp' into staging

Conflicts:
	ui/spice-core.c
This commit is contained in:
Anthony Liguori
2011-10-31 11:02:29 -05:00
27 changed files with 1623 additions and 1066 deletions
+14 -58
View File
@@ -25,12 +25,11 @@
*/
#include "monitor.h"
#include "qjson.h"
#include "qint.h"
#include "cpu-common.h"
#include "kvm.h"
#include "balloon.h"
#include "trace.h"
#include "qmp-commands.h"
static QEMUBalloonEvent *balloon_event_fn;
static QEMUBalloonStatus *balloon_stat_fn;
@@ -72,76 +71,33 @@ static int qemu_balloon(ram_addr_t target)
return 1;
}
static int qemu_balloon_status(MonitorCompletion cb, void *opaque)
static int qemu_balloon_status(BalloonInfo *info)
{
if (!balloon_stat_fn) {
return 0;
}
balloon_stat_fn(balloon_opaque, cb, opaque);
balloon_stat_fn(balloon_opaque, info);
return 1;
}
static void print_balloon_stat(const char *key, QObject *obj, void *opaque)
BalloonInfo *qmp_query_balloon(Error **errp)
{
Monitor *mon = opaque;
if (strcmp(key, "actual")) {
monitor_printf(mon, ",%s=%" PRId64, key,
qint_get_int(qobject_to_qint(obj)));
}
}
void monitor_print_balloon(Monitor *mon, const QObject *data)
{
QDict *qdict;
qdict = qobject_to_qdict(data);
if (!qdict_haskey(qdict, "actual")) {
return;
}
monitor_printf(mon, "balloon: actual=%" PRId64,
qdict_get_int(qdict, "actual") >> 20);
qdict_iter(qdict, print_balloon_stat, mon);
monitor_printf(mon, "\n");
}
/**
* do_info_balloon(): Balloon information
*
* Make an asynchronous request for balloon info. When the request completes
* a QDict will be returned according to the following specification:
*
* - "actual": current balloon value in bytes
* The following fields may or may not be present:
* - "mem_swapped_in": Amount of memory swapped in (bytes)
* - "mem_swapped_out": Amount of memory swapped out (bytes)
* - "major_page_faults": Number of major faults
* - "minor_page_faults": Number of minor faults
* - "free_mem": Total amount of free and unused memory (bytes)
* - "total_mem": Total amount of available memory (bytes)
*
* Example:
*
* { "actual": 1073741824, "mem_swapped_in": 0, "mem_swapped_out": 0,
* "major_page_faults": 142, "minor_page_faults": 239245,
* "free_mem": 1014185984, "total_mem": 1044668416 }
*/
int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque)
{
int ret;
BalloonInfo *info;
if (kvm_enabled() && !kvm_has_sync_mmu()) {
qerror_report(QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
return -1;
error_set(errp, QERR_KVM_MISSING_CAP, "synchronous MMU", "balloon");
return NULL;
}
ret = qemu_balloon_status(cb, opaque);
if (!ret) {
qerror_report(QERR_DEVICE_NOT_ACTIVE, "balloon");
return -1;
info = g_malloc0(sizeof(*info));
if (qemu_balloon_status(info) == 0) {
error_set(errp, QERR_DEVICE_NOT_ACTIVE, "balloon");
qapi_free_BalloonInfo(info);
return NULL;
}
return 0;
return info;
}
/**
+2 -4
View File
@@ -15,17 +15,15 @@
#define _QEMU_BALLOON_H
#include "monitor.h"
#include "qapi-types.h"
typedef void (QEMUBalloonEvent)(void *opaque, ram_addr_t target);
typedef void (QEMUBalloonStatus)(void *opaque, MonitorCompletion cb,
void *cb_data);
typedef void (QEMUBalloonStatus)(void *opaque, BalloonInfo *info);
int qemu_add_balloon_handler(QEMUBalloonEvent *event_func,
QEMUBalloonStatus *stat_func, void *opaque);
void qemu_remove_balloon_handler(void *opaque);
void monitor_print_balloon(Monitor *mon, const QObject *data);
int do_info_balloon(Monitor *mon, MonitorCompletion cb, void *opaque);
int do_balloon(Monitor *mon, const QDict *params,
MonitorCompletion cb, void *opaque);
+75 -161
View File
@@ -27,8 +27,9 @@
#include "monitor.h"
#include "block_int.h"
#include "module.h"
#include "qemu-objects.h"
#include "qjson.h"
#include "qemu-coroutine.h"
#include "qmp-commands.h"
#ifdef CONFIG_BSD
#include <sys/types.h>
@@ -1824,195 +1825,105 @@ void bdrv_mon_event(const BlockDriverState *bdrv,
qobject_decref(data);
}
static void bdrv_print_dict(QObject *obj, void *opaque)
BlockInfoList *qmp_query_block(Error **errp)
{
QDict *bs_dict;
Monitor *mon = opaque;
bs_dict = qobject_to_qdict(obj);
monitor_printf(mon, "%s: removable=%d",
qdict_get_str(bs_dict, "device"),
qdict_get_bool(bs_dict, "removable"));
if (qdict_get_bool(bs_dict, "removable")) {
monitor_printf(mon, " locked=%d", qdict_get_bool(bs_dict, "locked"));
monitor_printf(mon, " tray-open=%d",
qdict_get_bool(bs_dict, "tray-open"));
}
if (qdict_haskey(bs_dict, "io-status")) {
monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status"));
}
if (qdict_haskey(bs_dict, "inserted")) {
QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted"));
monitor_printf(mon, " file=");
monitor_print_filename(mon, qdict_get_str(qdict, "file"));
if (qdict_haskey(qdict, "backing_file")) {
monitor_printf(mon, " backing_file=");
monitor_print_filename(mon, qdict_get_str(qdict, "backing_file"));
}
monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
qdict_get_bool(qdict, "ro"),
qdict_get_str(qdict, "drv"),
qdict_get_bool(qdict, "encrypted"));
} else {
monitor_printf(mon, " [not inserted]");
}
monitor_printf(mon, "\n");
}
void bdrv_info_print(Monitor *mon, const QObject *data)
{
qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon);
}
static const char *const io_status_name[BDRV_IOS_MAX] = {
[BDRV_IOS_OK] = "ok",
[BDRV_IOS_FAILED] = "failed",
[BDRV_IOS_ENOSPC] = "nospace",
};
void bdrv_info(Monitor *mon, QObject **ret_data)
{
QList *bs_list;
BlockInfoList *head = NULL, *cur_item = NULL;
BlockDriverState *bs;
bs_list = qlist_new();
QTAILQ_FOREACH(bs, &bdrv_states, list) {
QObject *bs_obj;
QDict *bs_dict;
BlockInfoList *info = g_malloc0(sizeof(*info));
bs_obj = qobject_from_jsonf("{ 'device': %s, 'type': 'unknown', "
"'removable': %i, 'locked': %i }",
bs->device_name,
bdrv_dev_has_removable_media(bs),
bdrv_dev_is_medium_locked(bs));
bs_dict = qobject_to_qdict(bs_obj);
info->value = g_malloc0(sizeof(*info->value));
info->value->device = g_strdup(bs->device_name);
info->value->type = g_strdup("unknown");
info->value->locked = bdrv_dev_is_medium_locked(bs);
info->value->removable = bdrv_dev_has_removable_media(bs);
if (bdrv_dev_has_removable_media(bs)) {
qdict_put(bs_dict, "tray-open",
qbool_from_int(bdrv_dev_is_tray_open(bs)));
info->value->has_tray_open = true;
info->value->tray_open = bdrv_dev_is_tray_open(bs);
}
if (bdrv_iostatus_is_enabled(bs)) {
qdict_put(bs_dict, "io-status",
qstring_from_str(io_status_name[bs->iostatus]));
info->value->has_io_status = true;
info->value->io_status = bs->iostatus;
}
if (bs->drv) {
QObject *obj;
obj = qobject_from_jsonf("{ 'file': %s, 'ro': %i, 'drv': %s, "
"'encrypted': %i }",
bs->filename, bs->read_only,
bs->drv->format_name,
bdrv_is_encrypted(bs));
if (bs->backing_file[0] != '\0') {
QDict *qdict = qobject_to_qdict(obj);
qdict_put(qdict, "backing_file",
qstring_from_str(bs->backing_file));
info->value->has_inserted = true;
info->value->inserted = g_malloc0(sizeof(*info->value->inserted));
info->value->inserted->file = g_strdup(bs->filename);
info->value->inserted->ro = bs->read_only;
info->value->inserted->drv = g_strdup(bs->drv->format_name);
info->value->inserted->encrypted = bs->encrypted;
if (bs->backing_file[0]) {
info->value->inserted->has_backing_file = true;
info->value->inserted->backing_file = g_strdup(bs->backing_file);
}
qdict_put_obj(bs_dict, "inserted", obj);
}
qlist_append_obj(bs_list, bs_obj);
/* XXX: waiting for the qapi to support GSList */
if (!cur_item) {
head = cur_item = info;
} else {
cur_item->next = info;
cur_item = info;
}
}
*ret_data = QOBJECT(bs_list);
return head;
}
static void bdrv_stats_iter(QObject *data, void *opaque)
/* Consider exposing this as a full fledged QMP command */
static BlockStats *qmp_query_blockstat(const BlockDriverState *bs, Error **errp)
{
QDict *qdict;
Monitor *mon = opaque;
BlockStats *s;
qdict = qobject_to_qdict(data);
monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));
s = g_malloc0(sizeof(*s));
qdict = qobject_to_qdict(qdict_get(qdict, "stats"));
monitor_printf(mon, " rd_bytes=%" PRId64
" wr_bytes=%" PRId64
" rd_operations=%" PRId64
" wr_operations=%" PRId64
" flush_operations=%" PRId64
" wr_total_time_ns=%" PRId64
" rd_total_time_ns=%" PRId64
" flush_total_time_ns=%" PRId64
"\n",
qdict_get_int(qdict, "rd_bytes"),
qdict_get_int(qdict, "wr_bytes"),
qdict_get_int(qdict, "rd_operations"),
qdict_get_int(qdict, "wr_operations"),
qdict_get_int(qdict, "flush_operations"),
qdict_get_int(qdict, "wr_total_time_ns"),
qdict_get_int(qdict, "rd_total_time_ns"),
qdict_get_int(qdict, "flush_total_time_ns"));
}
void bdrv_stats_print(Monitor *mon, const QObject *data)
{
qlist_iter(qobject_to_qlist(data), bdrv_stats_iter, mon);
}
static QObject* bdrv_info_stats_bs(BlockDriverState *bs)
{
QObject *res;
QDict *dict;
res = qobject_from_jsonf("{ 'stats': {"
"'rd_bytes': %" PRId64 ","
"'wr_bytes': %" PRId64 ","
"'rd_operations': %" PRId64 ","
"'wr_operations': %" PRId64 ","
"'wr_highest_offset': %" PRId64 ","
"'flush_operations': %" PRId64 ","
"'wr_total_time_ns': %" PRId64 ","
"'rd_total_time_ns': %" PRId64 ","
"'flush_total_time_ns': %" PRId64
"} }",
bs->nr_bytes[BDRV_ACCT_READ],
bs->nr_bytes[BDRV_ACCT_WRITE],
bs->nr_ops[BDRV_ACCT_READ],
bs->nr_ops[BDRV_ACCT_WRITE],
bs->wr_highest_sector *
(uint64_t)BDRV_SECTOR_SIZE,
bs->nr_ops[BDRV_ACCT_FLUSH],
bs->total_time_ns[BDRV_ACCT_WRITE],
bs->total_time_ns[BDRV_ACCT_READ],
bs->total_time_ns[BDRV_ACCT_FLUSH]);
dict = qobject_to_qdict(res);
if (*bs->device_name) {
qdict_put(dict, "device", qstring_from_str(bs->device_name));
if (bs->device_name[0]) {
s->has_device = true;
s->device = g_strdup(bs->device_name);
}
s->stats = g_malloc0(sizeof(*s->stats));
s->stats->rd_bytes = bs->nr_bytes[BDRV_ACCT_READ];
s->stats->wr_bytes = bs->nr_bytes[BDRV_ACCT_WRITE];
s->stats->rd_operations = bs->nr_ops[BDRV_ACCT_READ];
s->stats->wr_operations = bs->nr_ops[BDRV_ACCT_WRITE];
s->stats->wr_highest_offset = bs->wr_highest_sector * BDRV_SECTOR_SIZE;
s->stats->flush_operations = bs->nr_ops[BDRV_ACCT_FLUSH];
s->stats->wr_total_time_ns = bs->total_time_ns[BDRV_ACCT_WRITE];
s->stats->rd_total_time_ns = bs->total_time_ns[BDRV_ACCT_READ];
s->stats->flush_total_time_ns = bs->total_time_ns[BDRV_ACCT_FLUSH];
if (bs->file) {
QObject *parent = bdrv_info_stats_bs(bs->file);
qdict_put_obj(dict, "parent", parent);
s->has_parent = true;
s->parent = qmp_query_blockstat(bs->file, NULL);
}
return res;
return s;
}
void bdrv_info_stats(Monitor *mon, QObject **ret_data)
BlockStatsList *qmp_query_blockstats(Error **errp)
{
QObject *obj;
QList *devices;
BlockStatsList *head = NULL, *cur_item = NULL;
BlockDriverState *bs;
devices = qlist_new();
QTAILQ_FOREACH(bs, &bdrv_states, list) {
obj = bdrv_info_stats_bs(bs);
qlist_append_obj(devices, obj);
BlockStatsList *info = g_malloc0(sizeof(*info));
info->value = qmp_query_blockstat(bs, NULL);
/* XXX: waiting for the qapi to support GSList */
if (!cur_item) {
head = cur_item = info;
} else {
cur_item->next = info;
cur_item = info;
}
}
*ret_data = QOBJECT(devices);
return head;
}
const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
@@ -3139,14 +3050,15 @@ int bdrv_in_use(BlockDriverState *bs)
void bdrv_iostatus_enable(BlockDriverState *bs)
{
bs->iostatus = BDRV_IOS_OK;
bs->iostatus_enabled = true;
bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
}
/* The I/O status is only enabled if the drive explicitly
* enables it _and_ the VM is configured to stop on errors */
bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
{
return (bs->iostatus != BDRV_IOS_INVAL &&
return (bs->iostatus_enabled &&
(bs->on_write_error == BLOCK_ERR_STOP_ENOSPC ||
bs->on_write_error == BLOCK_ERR_STOP_ANY ||
bs->on_read_error == BLOCK_ERR_STOP_ANY));
@@ -3154,13 +3066,13 @@ bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
void bdrv_iostatus_disable(BlockDriverState *bs)
{
bs->iostatus = BDRV_IOS_INVAL;
bs->iostatus_enabled = false;
}
void bdrv_iostatus_reset(BlockDriverState *bs)
{
if (bdrv_iostatus_is_enabled(bs)) {
bs->iostatus = BDRV_IOS_OK;
bs->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
}
}
@@ -3169,9 +3081,11 @@ void bdrv_iostatus_reset(BlockDriverState *bs)
possible to implement this without device models being involved */
void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
{
if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) {
if (bdrv_iostatus_is_enabled(bs) &&
bs->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
assert(error >= 0);
bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED;
bs->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
BLOCK_DEVICE_IO_STATUS_FAILED;
}
}
-5
View File
@@ -77,11 +77,6 @@ typedef enum {
BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
} BlockMonEventAction;
typedef enum {
BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC,
BDRV_IOS_MAX
} BlockIOStatus;
void bdrv_iostatus_enable(BlockDriverState *bs);
void bdrv_iostatus_reset(BlockDriverState *bs);
void bdrv_iostatus_disable(BlockDriverState *bs);
+3 -1
View File
@@ -29,6 +29,7 @@
#include "qemu-queue.h"
#include "qemu-coroutine.h"
#include "qemu-timer.h"
#include "qapi-types.h"
#define BLOCK_FLAG_ENCRYPT 1
#define BLOCK_FLAG_COMPAT6 4
@@ -202,7 +203,8 @@ struct BlockDriverState {
drivers. They are not used by the block driver */
int cyls, heads, secs, translation;
BlockErrorAction on_read_error, on_write_error;
BlockIOStatus iostatus;
bool iostatus_enabled;
BlockDeviceIoStatus iostatus;
char device_name[32];
unsigned long *dirty_bitmap;
int64_t dirty_count;
-9
View File
@@ -383,8 +383,6 @@ char *vnc_display_local_addr(DisplayState *ds);
#ifdef CONFIG_VNC
int vnc_display_password(DisplayState *ds, const char *password);
int vnc_display_pw_expire(DisplayState *ds, time_t expires);
void do_info_vnc_print(Monitor *mon, const QObject *data);
void do_info_vnc(Monitor *mon, QObject **ret_data);
#else
static inline int vnc_display_password(DisplayState *ds, const char *password)
{
@@ -396,13 +394,6 @@ static inline int vnc_display_pw_expire(DisplayState *ds, time_t expires)
qerror_report(QERR_FEATURE_DISABLED, "vnc");
return -ENODEV;
};
static inline void do_info_vnc(Monitor *mon, QObject **ret_data)
{
};
static inline void do_info_vnc_print(Monitor *mon, const QObject *data)
{
monitor_printf(mon, "VNC support disabled\n");
};
#endif
/* curses.c */
+45
View File
@@ -30,6 +30,7 @@
#include "gdbstub.h"
#include "dma.h"
#include "kvm.h"
#include "qmp-commands.h"
#include "qemu-thread.h"
#include "cpus.h"
@@ -1094,3 +1095,47 @@ void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
cpu_list(f, cpu_fprintf); /* deprecated */
#endif
}
CpuInfoList *qmp_query_cpus(Error **errp)
{
CpuInfoList *head = NULL, *cur_item = NULL;
CPUState *env;
for(env = first_cpu; env != NULL; env = env->next_cpu) {
CpuInfoList *info;
cpu_synchronize_state(env);
info = g_malloc0(sizeof(*info));
info->value = g_malloc0(sizeof(*info->value));
info->value->CPU = env->cpu_index;
info->value->current = (env == first_cpu);
info->value->halted = env->halted;
info->value->thread_id = env->thread_id;
#if defined(TARGET_I386)
info->value->has_pc = true;
info->value->pc = env->eip + env->segs[R_CS].base;
#elif defined(TARGET_PPC)
info->value->has_nip = true;
info->value->nip = env->nip;
#elif defined(TARGET_SPARC)
info->value->has_pc = true;
info->value->pc = env->pc;
info->value->has_npc = true;
info->value->npc = env->npc;
#elif defined(TARGET_MIPS)
info->value->has_PC = true;
info->value->PC = env->active_tc.PC;
#endif
/* XXX: waiting for the qapi to support GSList */
if (!cur_item) {
head = cur_item = info;
} else {
cur_item->next = info;
cur_item = info;
}
}
return head;
}
+2 -1
View File
@@ -12,8 +12,9 @@
#include "qemu-common.h"
#include "error.h"
#include "qjson.h"
#include "qdict.h"
#include "error_int.h"
#include "qemu-objects.h"
#include "qerror.h"
struct Error
+1 -2
View File
@@ -587,8 +587,7 @@ ETEXI
.args_type = "index:i",
.params = "index",
.help = "set the default CPU",
.user_print = monitor_user_noop,
.mhandler.cmd_new = do_cpu_set,
.mhandler.cmd = hmp_cpu,
},
STEXI
+407
View File
@@ -94,6 +94,401 @@ void hmp_info_chardev(Monitor *mon)
qapi_free_ChardevInfoList(char_info);
}
void hmp_info_mice(Monitor *mon)
{
MouseInfoList *mice_list, *mouse;
mice_list = qmp_query_mice(NULL);
if (!mice_list) {
monitor_printf(mon, "No mouse devices connected\n");
return;
}
for (mouse = mice_list; mouse; mouse = mouse->next) {
monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
mouse->value->current ? '*' : ' ',
mouse->value->index, mouse->value->name,
mouse->value->absolute ? " (absolute)" : "");
}
qapi_free_MouseInfoList(mice_list);
}
void hmp_info_migrate(Monitor *mon)
{
MigrationInfo *info;
info = qmp_query_migrate(NULL);
if (info->has_status) {
monitor_printf(mon, "Migration status: %s\n", info->status);
}
if (info->has_ram) {
monitor_printf(mon, "transferred ram: %" PRIu64 " kbytes\n",
info->ram->transferred >> 10);
monitor_printf(mon, "remaining ram: %" PRIu64 " kbytes\n",
info->ram->remaining >> 10);
monitor_printf(mon, "total ram: %" PRIu64 " kbytes\n",
info->ram->total >> 10);
}
if (info->has_disk) {
monitor_printf(mon, "transferred disk: %" PRIu64 " kbytes\n",
info->disk->transferred >> 10);
monitor_printf(mon, "remaining disk: %" PRIu64 " kbytes\n",
info->disk->remaining >> 10);
monitor_printf(mon, "total disk: %" PRIu64 " kbytes\n",
info->disk->total >> 10);
}
qapi_free_MigrationInfo(info);
}
void hmp_info_cpus(Monitor *mon)
{
CpuInfoList *cpu_list, *cpu;
cpu_list = qmp_query_cpus(NULL);
for (cpu = cpu_list; cpu; cpu = cpu->next) {
int active = ' ';
if (cpu->value->CPU == monitor_get_cpu_index()) {
active = '*';
}
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);
}
if (cpu->value->has_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);
}
if (cpu->value->has_PC) {
monitor_printf(mon, "PC=0x%016" PRIx64, cpu->value->PC);
}
if (cpu->value->halted) {
monitor_printf(mon, " (halted)");
}
monitor_printf(mon, " thread_id=%" PRId64 "\n", cpu->value->thread_id);
}
qapi_free_CpuInfoList(cpu_list);
}
void hmp_info_block(Monitor *mon)
{
BlockInfoList *block_list, *info;
block_list = qmp_query_block(NULL);
for (info = block_list; info; info = info->next) {
monitor_printf(mon, "%s: removable=%d",
info->value->device, info->value->removable);
if (info->value->removable) {
monitor_printf(mon, " locked=%d", info->value->locked);
monitor_printf(mon, " tray-open=%d", info->value->tray_open);
}
if (info->value->has_io_status) {
monitor_printf(mon, " io-status=%s",
BlockDeviceIoStatus_lookup[info->value->io_status]);
}
if (info->value->has_inserted) {
monitor_printf(mon, " file=");
monitor_print_filename(mon, info->value->inserted->file);
if (info->value->inserted->has_backing_file) {
monitor_printf(mon, " backing_file=");
monitor_print_filename(mon, info->value->inserted->backing_file);
}
monitor_printf(mon, " ro=%d drv=%s encrypted=%d",
info->value->inserted->ro,
info->value->inserted->drv,
info->value->inserted->encrypted);
} else {
monitor_printf(mon, " [not inserted]");
}
monitor_printf(mon, "\n");
}
qapi_free_BlockInfoList(block_list);
}
void hmp_info_blockstats(Monitor *mon)
{
BlockStatsList *stats_list, *stats;
stats_list = qmp_query_blockstats(NULL);
for (stats = stats_list; stats; stats = stats->next) {
if (!stats->value->has_device) {
continue;
}
monitor_printf(mon, "%s:", stats->value->device);
monitor_printf(mon, " rd_bytes=%" PRId64
" wr_bytes=%" PRId64
" rd_operations=%" PRId64
" wr_operations=%" PRId64
" flush_operations=%" PRId64
" wr_total_time_ns=%" PRId64
" rd_total_time_ns=%" PRId64
" flush_total_time_ns=%" PRId64
"\n",
stats->value->stats->rd_bytes,
stats->value->stats->wr_bytes,
stats->value->stats->rd_operations,
stats->value->stats->wr_operations,
stats->value->stats->flush_operations,
stats->value->stats->wr_total_time_ns,
stats->value->stats->rd_total_time_ns,
stats->value->stats->flush_total_time_ns);
}
qapi_free_BlockStatsList(stats_list);
}
void hmp_info_vnc(Monitor *mon)
{
VncInfo *info;
Error *err = NULL;
VncClientInfoList *client;
info = qmp_query_vnc(&err);
if (err) {
monitor_printf(mon, "%s\n", error_get_pretty(err));
error_free(err);
return;
}
if (!info->enabled) {
monitor_printf(mon, "Server: disabled\n");
goto out;
}
monitor_printf(mon, "Server:\n");
if (info->has_host && info->has_service) {
monitor_printf(mon, " address: %s:%s\n", info->host, info->service);
}
if (info->has_auth) {
monitor_printf(mon, " auth: %s\n", info->auth);
}
if (!info->has_clients || info->clients == NULL) {
monitor_printf(mon, "Client: none\n");
} else {
for (client = info->clients; client; client = client->next) {
monitor_printf(mon, "Client:\n");
monitor_printf(mon, " address: %s:%s\n",
client->value->host, client->value->service);
monitor_printf(mon, " x509_dname: %s\n",
client->value->x509_dname ?
client->value->x509_dname : "none");
monitor_printf(mon, " username: %s\n",
client->value->has_sasl_username ?
client->value->sasl_username : "none");
}
}
out:
qapi_free_VncInfo(info);
}
void hmp_info_spice(Monitor *mon)
{
SpiceChannelList *chan;
SpiceInfo *info;
info = qmp_query_spice(NULL);
if (!info->enabled) {
monitor_printf(mon, "Server: disabled\n");
goto out;
}
monitor_printf(mon, "Server:\n");
if (info->has_port) {
monitor_printf(mon, " address: %s:%" PRId64 "\n",
info->host, info->port);
}
if (info->has_tls_port) {
monitor_printf(mon, " address: %s:%" PRId64 " [tls]\n",
info->host, info->tls_port);
}
monitor_printf(mon, " auth: %s\n", info->auth);
monitor_printf(mon, " compiled: %s\n", info->compiled_version);
if (!info->has_channels || info->channels == NULL) {
monitor_printf(mon, "Channels: none\n");
} else {
for (chan = info->channels; chan; chan = chan->next) {
monitor_printf(mon, "Channel:\n");
monitor_printf(mon, " address: %s:%s%s\n",
chan->value->host, chan->value->port,
chan->value->tls ? " [tls]" : "");
monitor_printf(mon, " session: %" PRId64 "\n",
chan->value->connection_id);
monitor_printf(mon, " channel: %" PRId64 ":%" PRId64 "\n",
chan->value->channel_type, chan->value->channel_id);
}
}
out:
qapi_free_SpiceInfo(info);
}
void hmp_info_balloon(Monitor *mon)
{
BalloonInfo *info;
Error *err = NULL;
info = qmp_query_balloon(&err);
if (err) {
monitor_printf(mon, "%s\n", error_get_pretty(err));
error_free(err);
return;
}
monitor_printf(mon, "balloon: actual=%" PRId64, info->actual >> 20);
if (info->has_mem_swapped_in) {
monitor_printf(mon, " mem_swapped_in=%" PRId64, info->mem_swapped_in);
}
if (info->has_mem_swapped_out) {
monitor_printf(mon, " mem_swapped_out=%" PRId64, info->mem_swapped_out);
}
if (info->has_major_page_faults) {
monitor_printf(mon, " major_page_faults=%" PRId64,
info->major_page_faults);
}
if (info->has_minor_page_faults) {
monitor_printf(mon, " minor_page_faults=%" PRId64,
info->minor_page_faults);
}
if (info->has_free_mem) {
monitor_printf(mon, " free_mem=%" PRId64, info->free_mem);
}
if (info->has_total_mem) {
monitor_printf(mon, " total_mem=%" PRId64, info->total_mem);
}
monitor_printf(mon, "\n");
qapi_free_BalloonInfo(info);
}
static void hmp_info_pci_device(Monitor *mon, const PciDeviceInfo *dev)
{
PciMemoryRegionList *region;
monitor_printf(mon, " Bus %2" PRId64 ", ", dev->bus);
monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n",
dev->slot, dev->function);
monitor_printf(mon, " ");
if (dev->class_info.has_desc) {
monitor_printf(mon, "%s", dev->class_info.desc);
} else {
monitor_printf(mon, "Class %04" PRId64, dev->class_info.class);
}
monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
dev->id.vendor, dev->id.device);
if (dev->has_irq) {
monitor_printf(mon, " IRQ %" PRId64 ".\n", dev->irq);
}
if (dev->has_pci_bridge) {
monitor_printf(mon, " BUS %" PRId64 ".\n",
dev->pci_bridge->bus.number);
monitor_printf(mon, " secondary bus %" PRId64 ".\n",
dev->pci_bridge->bus.secondary);
monitor_printf(mon, " subordinate bus %" PRId64 ".\n",
dev->pci_bridge->bus.subordinate);
monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n",
dev->pci_bridge->bus.io_range->base,
dev->pci_bridge->bus.io_range->limit);
monitor_printf(mon,
" memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n",
dev->pci_bridge->bus.memory_range->base,
dev->pci_bridge->bus.memory_range->limit);
monitor_printf(mon, " prefetchable memory range "
"[0x%08"PRIx64", 0x%08"PRIx64"]\n",
dev->pci_bridge->bus.prefetchable_range->base,
dev->pci_bridge->bus.prefetchable_range->limit);
}
for (region = dev->regions; region; region = region->next) {
uint64_t addr, size;
addr = region->value->address;
size = region->value->size;
monitor_printf(mon, " BAR%" PRId64 ": ", region->value->bar);
if (!strcmp(region->value->type, "io")) {
monitor_printf(mon, "I/O at 0x%04" PRIx64
" [0x%04" PRIx64 "].\n",
addr, addr + size - 1);
} else {
monitor_printf(mon, "%d bit%s memory at 0x%08" PRIx64
" [0x%08" PRIx64 "].\n",
region->value->mem_type_64 ? 64 : 32,
region->value->prefetch ? " prefetchable" : "",
addr, addr + size - 1);
}
}
monitor_printf(mon, " id \"%s\"\n", dev->qdev_id);
if (dev->has_pci_bridge) {
if (dev->pci_bridge->has_devices) {
PciDeviceInfoList *cdev;
for (cdev = dev->pci_bridge->devices; cdev; cdev = cdev->next) {
hmp_info_pci_device(mon, cdev->value);
}
}
}
}
void hmp_info_pci(Monitor *mon)
{
PciInfoList *info;
Error *err = NULL;
info = qmp_query_pci(&err);
if (err) {
monitor_printf(mon, "PCI devices not supported\n");
error_free(err);
return;
}
for (; info; info = info->next) {
PciDeviceInfoList *dev;
for (dev = info->value->devices; dev; dev = dev->next) {
hmp_info_pci_device(mon, dev->value);
}
}
qapi_free_PciInfoList(info);
}
void hmp_quit(Monitor *mon, const QDict *qdict)
{
monitor_suspend(mon);
@@ -114,3 +509,15 @@ void hmp_system_powerdown(Monitor *mon, const QDict *qdict)
{
qmp_system_powerdown(NULL);
}
void hmp_cpu(Monitor *mon, const QDict *qdict)
{
int64_t cpu_index;
/* XXX: drop the monitor_set_cpu() usage when all HMP commands that
use it are converted to the QAPI */
cpu_index = qdict_get_int(qdict, "index");
if (monitor_set_cpu(cpu_index) < 0) {
monitor_printf(mon, "invalid CPU index\n");
}
}
+10
View File
@@ -23,9 +23,19 @@ void hmp_info_kvm(Monitor *mon);
void hmp_info_status(Monitor *mon);
void hmp_info_uuid(Monitor *mon);
void hmp_info_chardev(Monitor *mon);
void hmp_info_mice(Monitor *mon);
void hmp_info_migrate(Monitor *mon);
void hmp_info_cpus(Monitor *mon);
void hmp_info_block(Monitor *mon);
void hmp_info_blockstats(Monitor *mon);
void hmp_info_vnc(Monitor *mon);
void hmp_info_spice(Monitor *mon);
void hmp_info_balloon(Monitor *mon);
void hmp_info_pci(Monitor *mon);
void hmp_quit(Monitor *mon, const QDict *qdict);
void hmp_stop(Monitor *mon, const QDict *qdict);
void hmp_system_reset(Monitor *mon, const QDict *qdict);
void hmp_system_powerdown(Monitor *mon, const QDict *qdict);
void hmp_cpu(Monitor *mon, const QDict *qdict);
#endif
+7 -10
View File
@@ -21,22 +21,19 @@
#include "sysemu.h"
#include "monitor.h"
#include "pci.h"
#include "qmp-commands.h"
PciInfoList *qmp_query_pci(Error **errp)
{
error_set(errp, QERR_UNSUPPORTED);
return NULL;
}
static void pci_error_message(Monitor *mon)
{
monitor_printf(mon, "PCI devices not supported\n");
}
void do_pci_info(Monitor *mon, QObject **ret_data)
{
pci_error_message(mon);
}
void do_pci_info_print(Monitor *mon, const QObject *data)
{
pci_error_message(mon);
}
int do_pcie_aer_inejct_error(Monitor *mon,
const QDict *qdict, QObject **ret_data)
{
+126 -208
View File
@@ -29,8 +29,8 @@
#include "net.h"
#include "sysemu.h"
#include "loader.h"
#include "qemu-objects.h"
#include "range.h"
#include "qmp-commands.h"
//#define DEBUG_PCI
#ifdef DEBUG_PCI
@@ -1164,276 +1164,194 @@ void pci_for_each_device(PCIBus *bus, int bus_num,
}
}
static void pci_device_print(Monitor *mon, QDict *device)
static const pci_class_desc *get_class_desc(int class)
{
QDict *qdict;
QListEntry *entry;
uint64_t addr, size;
monitor_printf(mon, " Bus %2" PRId64 ", ", qdict_get_int(device, "bus"));
monitor_printf(mon, "device %3" PRId64 ", function %" PRId64 ":\n",
qdict_get_int(device, "slot"),
qdict_get_int(device, "function"));
monitor_printf(mon, " ");
qdict = qdict_get_qdict(device, "class_info");
if (qdict_haskey(qdict, "desc")) {
monitor_printf(mon, "%s", qdict_get_str(qdict, "desc"));
} else {
monitor_printf(mon, "Class %04" PRId64, qdict_get_int(qdict, "class"));
}
qdict = qdict_get_qdict(device, "id");
monitor_printf(mon, ": PCI device %04" PRIx64 ":%04" PRIx64 "\n",
qdict_get_int(qdict, "device"),
qdict_get_int(qdict, "vendor"));
if (qdict_haskey(device, "irq")) {
monitor_printf(mon, " IRQ %" PRId64 ".\n",
qdict_get_int(device, "irq"));
}
if (qdict_haskey(device, "pci_bridge")) {
QDict *info;
qdict = qdict_get_qdict(device, "pci_bridge");
info = qdict_get_qdict(qdict, "bus");
monitor_printf(mon, " BUS %" PRId64 ".\n",
qdict_get_int(info, "number"));
monitor_printf(mon, " secondary bus %" PRId64 ".\n",
qdict_get_int(info, "secondary"));
monitor_printf(mon, " subordinate bus %" PRId64 ".\n",
qdict_get_int(info, "subordinate"));
info = qdict_get_qdict(qdict, "io_range");
monitor_printf(mon, " IO range [0x%04"PRIx64", 0x%04"PRIx64"]\n",
qdict_get_int(info, "base"),
qdict_get_int(info, "limit"));
info = qdict_get_qdict(qdict, "memory_range");
monitor_printf(mon,
" memory range [0x%08"PRIx64", 0x%08"PRIx64"]\n",
qdict_get_int(info, "base"),
qdict_get_int(info, "limit"));
info = qdict_get_qdict(qdict, "prefetchable_range");
monitor_printf(mon, " prefetchable memory range "
"[0x%08"PRIx64", 0x%08"PRIx64"]\n",
qdict_get_int(info, "base"),
qdict_get_int(info, "limit"));
}
QLIST_FOREACH_ENTRY(qdict_get_qlist(device, "regions"), entry) {
qdict = qobject_to_qdict(qlist_entry_obj(entry));
monitor_printf(mon, " BAR%d: ", (int) qdict_get_int(qdict, "bar"));
addr = qdict_get_int(qdict, "address");
size = qdict_get_int(qdict, "size");
if (!strcmp(qdict_get_str(qdict, "type"), "io")) {
monitor_printf(mon, "I/O at 0x%04"FMT_PCIBUS
" [0x%04"FMT_PCIBUS"].\n",
addr, addr + size - 1);
} else {
monitor_printf(mon, "%d bit%s memory at 0x%08"FMT_PCIBUS
" [0x%08"FMT_PCIBUS"].\n",
qdict_get_bool(qdict, "mem_type_64") ? 64 : 32,
qdict_get_bool(qdict, "prefetch") ?
" prefetchable" : "", addr, addr + size - 1);
}
}
monitor_printf(mon, " id \"%s\"\n", qdict_get_str(device, "qdev_id"));
if (qdict_haskey(device, "pci_bridge")) {
qdict = qdict_get_qdict(device, "pci_bridge");
if (qdict_haskey(qdict, "devices")) {
QListEntry *dev;
QLIST_FOREACH_ENTRY(qdict_get_qlist(qdict, "devices"), dev) {
pci_device_print(mon, qobject_to_qdict(qlist_entry_obj(dev)));
}
}
}
}
void do_pci_info_print(Monitor *mon, const QObject *data)
{
QListEntry *bus, *dev;
QLIST_FOREACH_ENTRY(qobject_to_qlist(data), bus) {
QDict *qdict = qobject_to_qdict(qlist_entry_obj(bus));
QLIST_FOREACH_ENTRY(qdict_get_qlist(qdict, "devices"), dev) {
pci_device_print(mon, qobject_to_qdict(qlist_entry_obj(dev)));
}
}
}
static QObject *pci_get_dev_class(const PCIDevice *dev)
{
int class;
const pci_class_desc *desc;
class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
desc = pci_class_descriptions;
while (desc->desc && class != desc->class)
while (desc->desc && class != desc->class) {
desc++;
if (desc->desc) {
return qobject_from_jsonf("{ 'desc': %s, 'class': %d }",
desc->desc, class);
} else {
return qobject_from_jsonf("{ 'class': %d }", class);
}
return desc;
}
static QObject *pci_get_dev_id(const PCIDevice *dev)
{
return qobject_from_jsonf("{ 'device': %d, 'vendor': %d }",
pci_get_word(dev->config + PCI_VENDOR_ID),
pci_get_word(dev->config + PCI_DEVICE_ID));
}
static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num);
static QObject *pci_get_regions_list(const PCIDevice *dev)
static PciMemoryRegionList *qmp_query_pci_regions(const PCIDevice *dev)
{
PciMemoryRegionList *head = NULL, *cur_item = NULL;
int i;
QList *regions_list;
regions_list = qlist_new();
for (i = 0; i < PCI_NUM_REGIONS; i++) {
QObject *obj;
const PCIIORegion *r = &dev->io_regions[i];
PciMemoryRegionList *region;
if (!r->size) {
continue;
}
if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
obj = qobject_from_jsonf("{ 'bar': %d, 'type': 'io', "
"'address': %" PRId64 ", "
"'size': %" PRId64 " }",
i, r->addr, r->size);
} else {
int mem_type_64 = r->type & PCI_BASE_ADDRESS_MEM_TYPE_64;
region = g_malloc0(sizeof(*region));
region->value = g_malloc0(sizeof(*region->value));
obj = qobject_from_jsonf("{ 'bar': %d, 'type': 'memory', "
"'mem_type_64': %i, 'prefetch': %i, "
"'address': %" PRId64 ", "
"'size': %" PRId64 " }",
i, mem_type_64,
r->type & PCI_BASE_ADDRESS_MEM_PREFETCH,
r->addr, r->size);
if (r->type & PCI_BASE_ADDRESS_SPACE_IO) {
region->value->type = g_strdup("io");
} else {
region->value->type = g_strdup("memory");
region->value->has_prefetch = true;
region->value->prefetch = !!(r->type & PCI_BASE_ADDRESS_MEM_PREFETCH);
region->value->has_mem_type_64 = true;
region->value->mem_type_64 = !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64);
}
qlist_append_obj(regions_list, obj);
region->value->bar = i;
region->value->address = r->addr;
region->value->size = r->size;
/* XXX: waiting for the qapi to support GSList */
if (!cur_item) {
head = cur_item = region;
} else {
cur_item->next = region;
cur_item = region;
}
}
return QOBJECT(regions_list);
return head;
}
static QObject *pci_get_devices_list(PCIBus *bus, int bus_num);
static QObject *pci_get_dev_dict(PCIDevice *dev, PCIBus *bus, int bus_num)
static PciBridgeInfo *qmp_query_pci_bridge(PCIDevice *dev, PCIBus *bus,
int bus_num)
{
uint8_t type;
QObject *obj;
PciBridgeInfo *info;
obj = qobject_from_jsonf("{ 'bus': %d, 'slot': %d, 'function': %d," "'class_info': %p, 'id': %p, 'regions': %p,"
" 'qdev_id': %s }",
bus_num,
PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
pci_get_dev_class(dev), pci_get_dev_id(dev),
pci_get_regions_list(dev),
dev->qdev.id ? dev->qdev.id : "");
info = g_malloc0(sizeof(*info));
info->bus.number = dev->config[PCI_PRIMARY_BUS];
info->bus.secondary = dev->config[PCI_SECONDARY_BUS];
info->bus.subordinate = dev->config[PCI_SUBORDINATE_BUS];
info->bus.io_range = g_malloc0(sizeof(*info->bus.io_range));
info->bus.io_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO);
info->bus.io_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO);
info->bus.memory_range = g_malloc0(sizeof(*info->bus.memory_range));
info->bus.memory_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
info->bus.memory_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY);
info->bus.prefetchable_range = g_malloc0(sizeof(*info->bus.prefetchable_range));
info->bus.prefetchable_range->base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
info->bus.prefetchable_range->limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);
if (dev->config[PCI_SECONDARY_BUS] != 0) {
PCIBus *child_bus = pci_find_bus(bus, dev->config[PCI_SECONDARY_BUS]);
if (child_bus) {
info->has_devices = true;
info->devices = qmp_query_pci_devices(child_bus, dev->config[PCI_SECONDARY_BUS]);
}
}
return info;
}
static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
int bus_num)
{
const pci_class_desc *desc;
PciDeviceInfo *info;
uint8_t type;
int class;
info = g_malloc0(sizeof(*info));
info->bus = bus_num;
info->slot = PCI_SLOT(dev->devfn);
info->function = PCI_FUNC(dev->devfn);
class = pci_get_word(dev->config + PCI_CLASS_DEVICE);
info->class_info.class = class;
desc = get_class_desc(class);
if (desc->desc) {
info->class_info.has_desc = true;
info->class_info.desc = g_strdup(desc->desc);
}
info->id.vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
info->id.device = pci_get_word(dev->config + PCI_DEVICE_ID);
info->regions = qmp_query_pci_regions(dev);
info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
if (dev->config[PCI_INTERRUPT_PIN] != 0) {
QDict *qdict = qobject_to_qdict(obj);
qdict_put(qdict, "irq", qint_from_int(dev->config[PCI_INTERRUPT_LINE]));
info->has_irq = true;
info->irq = dev->config[PCI_INTERRUPT_LINE];
}
type = dev->config[PCI_HEADER_TYPE] & ~PCI_HEADER_TYPE_MULTI_FUNCTION;
if (type == PCI_HEADER_TYPE_BRIDGE) {
QDict *qdict;
QObject *pci_bridge;
pci_bridge = qobject_from_jsonf("{ 'bus': "
"{ 'number': %d, 'secondary': %d, 'subordinate': %d }, "
"'io_range': { 'base': %" PRId64 ", 'limit': %" PRId64 "}, "
"'memory_range': { 'base': %" PRId64 ", 'limit': %" PRId64 "}, "
"'prefetchable_range': { 'base': %" PRId64 ", 'limit': %" PRId64 "} }",
dev->config[PCI_PRIMARY_BUS], dev->config[PCI_SECONDARY_BUS],
dev->config[PCI_SUBORDINATE_BUS],
pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO),
pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO),
pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY),
pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY),
pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_PREFETCH),
pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY |
PCI_BASE_ADDRESS_MEM_PREFETCH));
if (dev->config[PCI_SECONDARY_BUS] != 0) {
PCIBus *child_bus = pci_find_bus(bus, dev->config[PCI_SECONDARY_BUS]);
if (child_bus) {
qdict = qobject_to_qdict(pci_bridge);
qdict_put_obj(qdict, "devices",
pci_get_devices_list(child_bus,
dev->config[PCI_SECONDARY_BUS]));
}
}
qdict = qobject_to_qdict(obj);
qdict_put_obj(qdict, "pci_bridge", pci_bridge);
info->has_pci_bridge = true;
info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
}
return obj;
return info;
}
static QObject *pci_get_devices_list(PCIBus *bus, int bus_num)
static PciDeviceInfoList *qmp_query_pci_devices(PCIBus *bus, int bus_num)
{
int devfn;
PciDeviceInfoList *info, *head = NULL, *cur_item = NULL;
PCIDevice *dev;
QList *dev_list;
dev_list = qlist_new();
int devfn;
for (devfn = 0; devfn < ARRAY_SIZE(bus->devices); devfn++) {
dev = bus->devices[devfn];
if (dev) {
qlist_append_obj(dev_list, pci_get_dev_dict(dev, bus, bus_num));
info = g_malloc0(sizeof(*info));
info->value = qmp_query_pci_device(dev, bus, bus_num);
/* XXX: waiting for the qapi to support GSList */
if (!cur_item) {
head = cur_item = info;
} else {
cur_item->next = info;
cur_item = info;
}
}
}
return QOBJECT(dev_list);
return head;
}
static QObject *pci_get_bus_dict(PCIBus *bus, int bus_num)
static PciInfo *qmp_query_pci_bus(PCIBus *bus, int bus_num)
{
PciInfo *info = NULL;
bus = pci_find_bus(bus, bus_num);
if (bus) {
return qobject_from_jsonf("{ 'bus': %d, 'devices': %p }",
bus_num, pci_get_devices_list(bus, bus_num));
info = g_malloc0(sizeof(*info));
info->bus = bus_num;
info->devices = qmp_query_pci_devices(bus, bus_num);
}
return NULL;
return info;
}
void do_pci_info(Monitor *mon, QObject **ret_data)
PciInfoList *qmp_query_pci(Error **errp)
{
QList *bus_list;
PciInfoList *info, *head = NULL, *cur_item = NULL;
struct PCIHostBus *host;
bus_list = qlist_new();
QLIST_FOREACH(host, &host_buses, next) {
QObject *obj = pci_get_bus_dict(host->bus, 0);
if (obj) {
qlist_append_obj(bus_list, obj);
info = g_malloc0(sizeof(*info));
info->value = qmp_query_pci_bus(host->bus, 0);
/* XXX: waiting for the qapi to support GSList */
if (!cur_item) {
head = cur_item = info;
} else {
cur_item->next = info;
cur_item = info;
}
}
*ret_data = QOBJECT(bus_list);
return head;
}
static const char * const pci_nic_models[] = {
-4
View File
@@ -2,7 +2,6 @@
#define QEMU_PCI_H
#include "qemu-common.h"
#include "qobject.h"
#include "qdev.h"
#include "memory.h"
@@ -271,9 +270,6 @@ int pci_parse_devaddr(const char *addr, int *domp, int *busp,
int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
unsigned *slotp);
void do_pci_info_print(Monitor *mon, const QObject *data);
void do_pci_info(Monitor *mon, QObject **ret_data);
void pci_device_deassert_intx(PCIDevice *dev);
static inline void
+14 -64
View File
@@ -18,22 +18,14 @@
#include "virtio.h"
#include "pc.h"
#include "cpu.h"
#include "monitor.h"
#include "balloon.h"
#include "virtio-balloon.h"
#include "kvm.h"
#include "qlist.h"
#include "qint.h"
#include "qstring.h"
#if defined(__linux__)
#include <sys/mman.h>
#endif
/* Disable guest-provided stats by now (https://bugzilla.redhat.com/show_bug.cgi?id=623903) */
#define ENABLE_GUEST_STATS 0
typedef struct VirtIOBalloon
{
VirtIODevice vdev;
@@ -43,8 +35,6 @@ typedef struct VirtIOBalloon
uint64_t stats[VIRTIO_BALLOON_S_NR];
VirtQueueElement stats_vq_elem;
size_t stats_vq_offset;
MonitorCompletion *stats_callback;
void *stats_opaque_callback_data;
DeviceState *qdev;
} VirtIOBalloon;
@@ -76,31 +66,6 @@ static inline void reset_stats(VirtIOBalloon *dev)
for (i = 0; i < VIRTIO_BALLOON_S_NR; dev->stats[i++] = -1);
}
static void stat_put(QDict *dict, const char *label, uint64_t val)
{
if (val != -1)
qdict_put(dict, label, qint_from_int(val));
}
static QObject *get_stats_qobject(VirtIOBalloon *dev)
{
QDict *dict = qdict_new();
uint64_t actual = ram_size - ((uint64_t) dev->actual <<
VIRTIO_BALLOON_PFN_SHIFT);
stat_put(dict, "actual", actual);
#if ENABLE_GUEST_STATS
stat_put(dict, "mem_swapped_in", dev->stats[VIRTIO_BALLOON_S_SWAP_IN]);
stat_put(dict, "mem_swapped_out", dev->stats[VIRTIO_BALLOON_S_SWAP_OUT]);
stat_put(dict, "major_page_faults", dev->stats[VIRTIO_BALLOON_S_MAJFLT]);
stat_put(dict, "minor_page_faults", dev->stats[VIRTIO_BALLOON_S_MINFLT]);
stat_put(dict, "free_mem", dev->stats[VIRTIO_BALLOON_S_MEMFREE]);
stat_put(dict, "total_mem", dev->stats[VIRTIO_BALLOON_S_MEMTOT]);
#endif
return QOBJECT(dict);
}
static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOBalloon *s = to_virtio_balloon(vdev);
@@ -131,20 +96,6 @@ static void virtio_balloon_handle_output(VirtIODevice *vdev, VirtQueue *vq)
}
}
static void complete_stats_request(VirtIOBalloon *vb)
{
QObject *stats;
if (!vb->stats_opaque_callback_data)
return;
stats = get_stats_qobject(vb);
vb->stats_callback(vb->stats_opaque_callback_data, stats);
qobject_decref(stats);
vb->stats_opaque_callback_data = NULL;
vb->stats_callback = NULL;
}
static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
{
VirtIOBalloon *s = DO_UPCAST(VirtIOBalloon, vdev, vdev);
@@ -172,8 +123,6 @@ static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
s->stats[tag] = val;
}
s->stats_vq_offset = offset;
complete_stats_request(s);
}
static void virtio_balloon_get_config(VirtIODevice *vdev, uint8_t *config_data)
@@ -202,32 +151,33 @@ static uint32_t virtio_balloon_get_features(VirtIODevice *vdev, uint32_t f)
return f;
}
static void virtio_balloon_stat(void *opaque, MonitorCompletion cb,
void *cb_data)
static void virtio_balloon_stat(void *opaque, BalloonInfo *info)
{
VirtIOBalloon *dev = opaque;
/* For now, only allow one request at a time. This restriction can be
* removed later by queueing callback and data pairs.
#if 0
/* Disable guest-provided stats for now. For more details please check:
* https://bugzilla.redhat.com/show_bug.cgi?id=623903
*
* If you do enable it (which is probably not going to happen as we
* need a new command for it), remember that you also need to fill the
* appropriate members of the BalloonInfo structure so that the stats
* are returned to the client.
*/
if (dev->stats_callback != NULL) {
return;
}
dev->stats_callback = cb;
dev->stats_opaque_callback_data = cb_data;
if (ENABLE_GUEST_STATS
&& (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ))) {
if (dev->vdev.guest_features & (1 << VIRTIO_BALLOON_F_STATS_VQ)) {
virtqueue_push(dev->svq, &dev->stats_vq_elem, dev->stats_vq_offset);
virtio_notify(&dev->vdev, dev->svq);
return;
}
#endif
/* Stats are not supported. Clear out any stale values that might
* have been set by a more featureful guest kernel.
*/
reset_stats(dev);
complete_stats_request(dev);
info->actual = ram_size - ((uint64_t) dev->actual <<
VIRTIO_BALLOON_PFN_SHIFT);
}
static void virtio_balloon_to_target(void *opaque, ram_addr_t target)
+17 -49
View File
@@ -26,7 +26,8 @@
#include "net.h"
#include "monitor.h"
#include "console.h"
#include "qjson.h"
#include "error.h"
#include "qmp-commands.h"
static QEMUPutKBDEvent *qemu_put_kbd_event;
static void *qemu_put_kbd_event_opaque;
@@ -211,60 +212,27 @@ int kbd_mouse_has_absolute(void)
return 0;
}
static void info_mice_iter(QObject *data, void *opaque)
{
QDict *mouse;
Monitor *mon = opaque;
mouse = qobject_to_qdict(data);
monitor_printf(mon, "%c Mouse #%" PRId64 ": %s%s\n",
(qdict_get_bool(mouse, "current") ? '*' : ' '),
qdict_get_int(mouse, "index"), qdict_get_str(mouse, "name"),
qdict_get_bool(mouse, "absolute") ? " (absolute)" : "");
}
void do_info_mice_print(Monitor *mon, const QObject *data)
{
QList *mice_list;
mice_list = qobject_to_qlist(data);
if (qlist_empty(mice_list)) {
monitor_printf(mon, "No mouse devices connected\n");
return;
}
qlist_iter(mice_list, info_mice_iter, mon);
}
void do_info_mice(Monitor *mon, QObject **ret_data)
MouseInfoList *qmp_query_mice(Error **errp)
{
MouseInfoList *mice_list = NULL;
QEMUPutMouseEntry *cursor;
QList *mice_list;
int current;
mice_list = qlist_new();
if (QTAILQ_EMPTY(&mouse_handlers)) {
goto out;
}
current = QTAILQ_FIRST(&mouse_handlers)->index;
bool current = true;
QTAILQ_FOREACH(cursor, &mouse_handlers, node) {
QObject *obj;
obj = qobject_from_jsonf("{ 'name': %s,"
" 'index': %d,"
" 'current': %i,"
" 'absolute': %i }",
cursor->qemu_put_mouse_event_name,
cursor->index,
cursor->index == current,
!!cursor->qemu_put_mouse_event_absolute);
qlist_append_obj(mice_list, obj);
MouseInfoList *info = g_malloc0(sizeof(*info));
info->value = g_malloc0(sizeof(*info->value));
info->value->name = g_strdup(cursor->qemu_put_mouse_event_name);
info->value->index = cursor->index;
info->value->absolute = !!cursor->qemu_put_mouse_event_absolute;
info->value->current = current;
current = false;
info->next = mice_list;
mice_list = info;
}
out:
*ret_data = QOBJECT(mice_list);
return mice_list;
}
void do_mouse_set(Monitor *mon, const QDict *qdict)
+23 -59
View File
@@ -19,7 +19,7 @@
#include "block.h"
#include "qemu_socket.h"
#include "block-migration.h"
#include "qemu-objects.h"
#include "qmp-commands.h"
//#define DEBUG_MIGRATION
@@ -107,53 +107,9 @@ uint64_t migrate_max_downtime(void)
return max_downtime;
}
static void migrate_print_status(Monitor *mon, const char *name,
const QDict *status_dict)
MigrationInfo *qmp_query_migrate(Error **errp)
{
QDict *qdict;
qdict = qobject_to_qdict(qdict_get(status_dict, name));
monitor_printf(mon, "transferred %s: %" PRIu64 " kbytes\n", name,
qdict_get_int(qdict, "transferred") >> 10);
monitor_printf(mon, "remaining %s: %" PRIu64 " kbytes\n", name,
qdict_get_int(qdict, "remaining") >> 10);
monitor_printf(mon, "total %s: %" PRIu64 " kbytes\n", name,
qdict_get_int(qdict, "total") >> 10);
}
void do_info_migrate_print(Monitor *mon, const QObject *data)
{
QDict *qdict;
qdict = qobject_to_qdict(data);
monitor_printf(mon, "Migration status: %s\n",
qdict_get_str(qdict, "status"));
if (qdict_haskey(qdict, "ram")) {
migrate_print_status(mon, "ram", qdict);
}
if (qdict_haskey(qdict, "disk")) {
migrate_print_status(mon, "disk", qdict);
}
}
static void migrate_put_status(QDict *qdict, const char *name,
uint64_t trans, uint64_t rem, uint64_t total)
{
QObject *obj;
obj = qobject_from_jsonf("{ 'transferred': %" PRId64 ", "
"'remaining': %" PRId64 ", "
"'total': %" PRId64 " }", trans, rem, total);
qdict_put_obj(qdict, name, obj);
}
void do_info_migrate(Monitor *mon, QObject **ret_data)
{
QDict *qdict;
MigrationInfo *info = g_malloc0(sizeof(*info));
MigrationState *s = migrate_get_current();
switch (s->state) {
@@ -161,30 +117,38 @@ void do_info_migrate(Monitor *mon, QObject **ret_data)
/* no migration has happened ever */
break;
case MIG_STATE_ACTIVE:
qdict = qdict_new();
qdict_put(qdict, "status", qstring_from_str("active"));
info->has_status = true;
info->status = g_strdup("active");
migrate_put_status(qdict, "ram", ram_bytes_transferred(),
ram_bytes_remaining(), ram_bytes_total());
info->has_ram = true;
info->ram = g_malloc0(sizeof(*info->ram));
info->ram->transferred = ram_bytes_transferred();
info->ram->remaining = ram_bytes_remaining();
info->ram->total = ram_bytes_total();
if (blk_mig_active()) {
migrate_put_status(qdict, "disk", blk_mig_bytes_transferred(),
blk_mig_bytes_remaining(),
blk_mig_bytes_total());
info->has_disk = true;
info->disk = g_malloc0(sizeof(*info->disk));
info->disk->transferred = blk_mig_bytes_transferred();
info->disk->remaining = blk_mig_bytes_remaining();
info->disk->total = blk_mig_bytes_total();
}
*ret_data = QOBJECT(qdict);
break;
case MIG_STATE_COMPLETED:
*ret_data = qobject_from_jsonf("{ 'status': 'completed' }");
info->has_status = true;
info->status = g_strdup("completed");
break;
case MIG_STATE_ERROR:
*ret_data = qobject_from_jsonf("{ 'status': 'failed' }");
info->has_status = true;
info->status = g_strdup("failed");
break;
case MIG_STATE_CANCELLED:
*ret_data = qobject_from_jsonf("{ 'status': 'cancelled' }");
info->has_status = true;
info->status = g_strdup("cancelled");
break;
}
return info;
}
/* shared migration helpers */
+24 -289
View File
@@ -123,8 +123,6 @@ typedef struct mon_cmd_t {
void (*user_print)(Monitor *mon, const QObject *data);
union {
void (*info)(Monitor *mon);
void (*info_new)(Monitor *mon, QObject **ret_data);
int (*info_async)(Monitor *mon, MonitorCompletion *cb, void *opaque);
void (*cmd)(Monitor *mon, const QDict *qdict);
int (*cmd_new)(Monitor *mon, const QDict *params, QObject **ret_data);
int (*cmd_async)(Monitor *mon, const QDict *params,
@@ -205,7 +203,6 @@ static const mon_cmd_t mon_cmds[];
static const mon_cmd_t info_cmds[];
static const mon_cmd_t qmp_cmds[];
static const mon_cmd_t qmp_query_cmds[];
Monitor *cur_mon;
Monitor *default_mon;
@@ -514,7 +511,6 @@ static int do_qmp_capabilities(Monitor *mon, const QDict *params,
return 0;
}
static int mon_set_cpu(int cpu_index);
static void handle_user_command(Monitor *mon, const char *cmdline);
static int do_hmp_passthrough(Monitor *mon, const QDict *params,
@@ -532,7 +528,7 @@ static int do_hmp_passthrough(Monitor *mon, const QDict *params,
cur_mon = &hmp;
if (qdict_haskey(params, "cpu-index")) {
ret = mon_set_cpu(qdict_get_int(params, "cpu-index"));
ret = monitor_set_cpu(qdict_get_int(params, "cpu-index"));
if (ret < 0) {
cur_mon = old_mon;
qerror_report(QERR_INVALID_PARAMETER_VALUE, "cpu-index", "a CPU number");
@@ -664,11 +660,6 @@ static int qmp_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
return cmd->mhandler.cmd_async(mon, params, qmp_monitor_complete, mon);
}
static void qmp_async_info_handler(Monitor *mon, const mon_cmd_t *cmd)
{
cmd->mhandler.info_async(mon, qmp_monitor_complete, mon);
}
static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
const QDict *params)
{
@@ -686,21 +677,6 @@ static void user_async_cmd_handler(Monitor *mon, const mon_cmd_t *cmd,
}
}
static void user_async_info_handler(Monitor *mon, const mon_cmd_t *cmd)
{
int ret;
MonitorCompletionData *cb_data = g_malloc(sizeof(*cb_data));
cb_data->mon = mon;
cb_data->user_print = cmd->user_print;
monitor_suspend(mon);
ret = cmd->mhandler.info_async(mon, user_monitor_complete, cb_data);
if (ret < 0) {
monitor_resume(mon);
g_free(cb_data);
}
}
static void do_info(Monitor *mon, const QDict *qdict)
{
const mon_cmd_t *cmd;
@@ -719,52 +695,23 @@ static void do_info(Monitor *mon, const QDict *qdict)
goto help;
}
if (handler_is_async(cmd)) {
user_async_info_handler(mon, cmd);
} else if (handler_is_qobject(cmd)) {
QObject *info_data = NULL;
cmd->mhandler.info_new(mon, &info_data);
if (info_data) {
cmd->user_print(mon, info_data);
qobject_decref(info_data);
}
} else {
cmd->mhandler.info(mon);
}
cmd->mhandler.info(mon);
return;
help:
help_cmd(mon, "info");
}
static CommandInfoList *alloc_cmd_entry(const char *cmd_name)
{
CommandInfoList *info;
info = g_malloc0(sizeof(*info));
info->value = g_malloc0(sizeof(*info->value));
info->value->name = g_strdup(cmd_name);
return info;
}
CommandInfoList *qmp_query_commands(Error **errp)
{
CommandInfoList *info, *cmd_list = NULL;
const mon_cmd_t *cmd;
for (cmd = qmp_cmds; cmd->name != NULL; cmd++) {
info = alloc_cmd_entry(cmd->name);
info->next = cmd_list;
cmd_list = info;
}
info = g_malloc0(sizeof(*info));
info->value = g_malloc0(sizeof(*info->value));
info->value->name = g_strdup(cmd->name);
for (cmd = qmp_query_cmds; cmd->name != NULL; cmd++) {
char buf[128];
snprintf(buf, sizeof(buf), "query-%s", cmd->name);
info = alloc_cmd_entry(buf);
info->next = cmd_list;
cmd_list = info;
}
@@ -772,8 +719,8 @@ CommandInfoList *qmp_query_commands(Error **errp)
return cmd_list;
}
/* get the current CPU defined by the user */
static int mon_set_cpu(int cpu_index)
/* set the current CPU defined by the user */
int monitor_set_cpu(int cpu_index)
{
CPUState *env;
@@ -789,12 +736,17 @@ static int mon_set_cpu(int cpu_index)
static CPUState *mon_get_cpu(void)
{
if (!cur_mon->mon_cpu) {
mon_set_cpu(0);
monitor_set_cpu(0);
}
cpu_synchronize_state(cur_mon->mon_cpu);
return cur_mon->mon_cpu;
}
int monitor_get_cpu_index(void)
{
return mon_get_cpu()->cpu_index;
}
static void do_info_registers(Monitor *mon)
{
CPUState *env;
@@ -808,107 +760,6 @@ static void do_info_registers(Monitor *mon)
#endif
}
static void print_cpu_iter(QObject *obj, void *opaque)
{
QDict *cpu;
int active = ' ';
Monitor *mon = opaque;
assert(qobject_type(obj) == QTYPE_QDICT);
cpu = qobject_to_qdict(obj);
if (qdict_get_bool(cpu, "current")) {
active = '*';
}
monitor_printf(mon, "%c CPU #%d: ", active, (int)qdict_get_int(cpu, "CPU"));
#if defined(TARGET_I386)
monitor_printf(mon, "pc=0x" TARGET_FMT_lx,
(target_ulong) qdict_get_int(cpu, "pc"));
#elif defined(TARGET_PPC)
monitor_printf(mon, "nip=0x" TARGET_FMT_lx,
(target_long) qdict_get_int(cpu, "nip"));
#elif defined(TARGET_SPARC)
monitor_printf(mon, "pc=0x" TARGET_FMT_lx,
(target_long) qdict_get_int(cpu, "pc"));
monitor_printf(mon, "npc=0x" TARGET_FMT_lx,
(target_long) qdict_get_int(cpu, "npc"));
#elif defined(TARGET_MIPS)
monitor_printf(mon, "PC=0x" TARGET_FMT_lx,
(target_long) qdict_get_int(cpu, "PC"));
#endif
if (qdict_get_bool(cpu, "halted")) {
monitor_printf(mon, " (halted)");
}
monitor_printf(mon, " thread_id=%" PRId64 " ",
qdict_get_int(cpu, "thread_id"));
monitor_printf(mon, "\n");
}
static void monitor_print_cpus(Monitor *mon, const QObject *data)
{
QList *cpu_list;
assert(qobject_type(data) == QTYPE_QLIST);
cpu_list = qobject_to_qlist(data);
qlist_iter(cpu_list, print_cpu_iter, mon);
}
static void do_info_cpus(Monitor *mon, QObject **ret_data)
{
CPUState *env;
QList *cpu_list;
cpu_list = qlist_new();
/* just to set the default cpu if not already done */
mon_get_cpu();
for(env = first_cpu; env != NULL; env = env->next_cpu) {
QDict *cpu;
QObject *obj;
cpu_synchronize_state(env);
obj = qobject_from_jsonf("{ 'CPU': %d, 'current': %i, 'halted': %i }",
env->cpu_index, env == mon->mon_cpu,
env->halted);
cpu = qobject_to_qdict(obj);
#if defined(TARGET_I386)
qdict_put(cpu, "pc", qint_from_int(env->eip + env->segs[R_CS].base));
#elif defined(TARGET_PPC)
qdict_put(cpu, "nip", qint_from_int(env->nip));
#elif defined(TARGET_SPARC)
qdict_put(cpu, "pc", qint_from_int(env->pc));
qdict_put(cpu, "npc", qint_from_int(env->npc));
#elif defined(TARGET_MIPS)
qdict_put(cpu, "PC", qint_from_int(env->active_tc.PC));
#endif
qdict_put(cpu, "thread_id", qint_from_int(env->thread_id));
qlist_append(cpu_list, cpu);
}
*ret_data = QOBJECT(cpu_list);
}
static int do_cpu_set(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
int index = qdict_get_int(qdict, "index");
if (mon_set_cpu(index) < 0) {
qerror_report(QERR_INVALID_PARAMETER_VALUE, "index",
"a CPU number");
return -1;
}
return 0;
}
static void do_info_jit(Monitor *mon)
{
dump_exec_info((FILE *)mon, monitor_fprintf);
@@ -2773,16 +2624,14 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show the block devices",
.user_print = bdrv_info_print,
.mhandler.info_new = bdrv_info,
.mhandler.info = hmp_info_block,
},
{
.name = "blockstats",
.args_type = "",
.params = "",
.help = "show block device statistics",
.user_print = bdrv_stats_print,
.mhandler.info_new = bdrv_info_stats,
.mhandler.info = hmp_info_blockstats,
},
{
.name = "registers",
@@ -2796,8 +2645,7 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show infos for each CPU",
.user_print = monitor_print_cpus,
.mhandler.info_new = do_info_cpus,
.mhandler.info = hmp_info_cpus,
},
{
.name = "history",
@@ -2840,8 +2688,7 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show PCI info",
.user_print = do_pci_info_print,
.mhandler.info_new = do_pci_info,
.mhandler.info = hmp_info_pci,
},
#if defined(TARGET_I386) || defined(TARGET_SH4) || defined(TARGET_SPARC) || \
defined(TARGET_PPC)
@@ -2944,16 +2791,14 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show which guest mouse is receiving events",
.user_print = do_info_mice_print,
.mhandler.info_new = do_info_mice,
.mhandler.info = hmp_info_mice,
},
{
.name = "vnc",
.args_type = "",
.params = "",
.help = "show the vnc server status",
.user_print = do_info_vnc_print,
.mhandler.info_new = do_info_vnc,
.mhandler.info = hmp_info_vnc,
},
#if defined(CONFIG_SPICE)
{
@@ -2961,8 +2806,7 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show the spice server status",
.user_print = do_info_spice_print,
.mhandler.info_new = do_info_spice,
.mhandler.info = hmp_info_spice,
},
#endif
{
@@ -3002,17 +2846,14 @@ static const mon_cmd_t info_cmds[] = {
.args_type = "",
.params = "",
.help = "show migration status",
.user_print = do_info_migrate_print,
.mhandler.info_new = do_info_migrate,
.mhandler.info = hmp_info_migrate,
},
{
.name = "balloon",
.args_type = "",
.params = "",
.help = "show balloon information",
.user_print = monitor_print_balloon,
.mhandler.info_async = do_info_balloon,
.flags = MONITOR_CMD_ASYNC,
.mhandler.info = hmp_info_balloon,
},
{
.name = "qtree",
@@ -3061,85 +2902,6 @@ static const mon_cmd_t qmp_cmds[] = {
{ /* NULL */ },
};
static const mon_cmd_t qmp_query_cmds[] = {
{
.name = "block",
.args_type = "",
.params = "",
.help = "show the block devices",
.user_print = bdrv_info_print,
.mhandler.info_new = bdrv_info,
},
{
.name = "blockstats",
.args_type = "",
.params = "",
.help = "show block device statistics",
.user_print = bdrv_stats_print,
.mhandler.info_new = bdrv_info_stats,
},
{
.name = "cpus",
.args_type = "",
.params = "",
.help = "show infos for each CPU",
.user_print = monitor_print_cpus,
.mhandler.info_new = do_info_cpus,
},
{
.name = "pci",
.args_type = "",
.params = "",
.help = "show PCI info",
.user_print = do_pci_info_print,
.mhandler.info_new = do_pci_info,
},
{
.name = "mice",
.args_type = "",
.params = "",
.help = "show which guest mouse is receiving events",
.user_print = do_info_mice_print,
.mhandler.info_new = do_info_mice,
},
{
.name = "vnc",
.args_type = "",
.params = "",
.help = "show the vnc server status",
.user_print = do_info_vnc_print,
.mhandler.info_new = do_info_vnc,
},
#if defined(CONFIG_SPICE)
{
.name = "spice",
.args_type = "",
.params = "",
.help = "show the spice server status",
.user_print = do_info_spice_print,
.mhandler.info_new = do_info_spice,
},
#endif
{
.name = "migrate",
.args_type = "",
.params = "",
.help = "show migration status",
.user_print = do_info_migrate_print,
.mhandler.info_new = do_info_migrate,
},
{
.name = "balloon",
.args_type = "",
.params = "",
.help = "show balloon information",
.user_print = monitor_print_balloon,
.mhandler.info_async = do_info_balloon,
.flags = MONITOR_CMD_ASYNC,
},
{ /* NULL */ },
};
/*******************************************************************/
static const char *pch;
@@ -3934,11 +3696,6 @@ static const mon_cmd_t *monitor_find_command(const char *cmdname)
return search_dispatch_table(mon_cmds, cmdname);
}
static const mon_cmd_t *qmp_find_query_cmd(const char *info_item)
{
return search_dispatch_table(qmp_query_cmds, info_item);
}
static const mon_cmd_t *qmp_find_cmd(const char *cmdname)
{
return search_dispatch_table(qmp_cmds, cmdname);
@@ -4862,22 +4619,6 @@ static QDict *qmp_check_input_obj(QObject *input_obj)
return input_dict;
}
static void qmp_call_query_cmd(Monitor *mon, const mon_cmd_t *cmd)
{
QObject *ret_data = NULL;
if (handler_is_async(cmd)) {
qmp_async_info_handler(mon, cmd);
if (monitor_has_error(mon)) {
monitor_protocol_emitter(mon, NULL);
}
} else {
cmd->mhandler.info_new(mon, &ret_data);
monitor_protocol_emitter(mon, ret_data);
qobject_decref(ret_data);
}
}
static void qmp_call_cmd(Monitor *mon, const mon_cmd_t *cmd,
const QDict *params)
{
@@ -4898,10 +4639,9 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
QObject *obj;
QDict *input, *args;
const mon_cmd_t *cmd;
const char *cmd_name;
Monitor *mon = cur_mon;
const char *cmd_name, *query_cmd;
query_cmd = NULL;
args = input = NULL;
obj = json_parser_parse(tokens, NULL);
@@ -4928,9 +4668,6 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
}
cmd = qmp_find_cmd(cmd_name);
if (!cmd && strstart(cmd_name, "query-", &query_cmd)) {
cmd = qmp_find_query_cmd(query_cmd);
}
if (!cmd) {
qerror_report(QERR_COMMAND_NOT_FOUND, cmd_name);
goto err_out;
@@ -4949,9 +4686,7 @@ static void handle_qmp_command(JSONMessageParser *parser, QList *tokens)
goto err_out;
}
if (query_cmd) {
qmp_call_query_cmd(mon, cmd);
} else if (handler_is_async(cmd)) {
if (handler_is_async(cmd)) {
err = qmp_async_cmd_handler(mon, cmd, args);
if (err) {
/* emit the error response */
+2
View File
@@ -57,6 +57,8 @@ void monitor_vprintf(Monitor *mon, const char *fmt, va_list ap)
void monitor_printf(Monitor *mon, const char *fmt, ...) GCC_FMT_ATTR(2, 3);
void monitor_print_filename(Monitor *mon, const char *filename);
void monitor_flush(Monitor *mon);
int monitor_set_cpu(int cpu_index);
int monitor_get_cpu_index(void);
typedef void (MonitorCompletion)(void *opaque, QObject *ret_data);
+616
View File
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More