#include "module.h"
#include "qemu-objects.h"
#include "qemu-coroutine.h"
+#include "qmp-commands.h"
#ifdef CONFIG_BSD
#include <sys/types.h>
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[BLOCK_DEVICE_IO_STATUS_MAX] = {
- [BLOCK_DEVICE_IO_STATUS_OK] = "ok",
- [BLOCK_DEVICE_IO_STATUS_FAILED] = "failed",
- [BLOCK_DEVICE_IO_STATUS_NOSPACE] = "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);
+ /* XXX: waiting for the qapi to support GSList */
+ if (!cur_item) {
+ head = cur_item = info;
+ } else {
+ cur_item->next = info;
+ cur_item = info;
}
- qlist_append_obj(bs_list, bs_obj);
}
- *ret_data = QOBJECT(bs_list);
+ return head;
}
static void bdrv_stats_iter(QObject *data, void *opaque)
BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
} BlockMonEventAction;
-typedef enum {
- BLOCK_DEVICE_IO_STATUS_OK, BLOCK_DEVICE_IO_STATUS_FAILED,
- BLOCK_DEVICE_IO_STATUS_NOSPACE, BLOCK_DEVICE_IO_STATUS_MAX
-} BlockIOStatus;
-
void bdrv_iostatus_enable(BlockDriverState *bs);
void bdrv_iostatus_reset(BlockDriverState *bs);
void bdrv_iostatus_disable(BlockDriverState *bs);
#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
int cyls, heads, secs, translation;
BlockErrorAction on_read_error, on_write_error;
bool iostatus_enabled;
- BlockIOStatus iostatus;
+ BlockDeviceIoStatus iostatus;
char device_name[32];
unsigned long *dirty_bitmap;
int64_t dirty_count;
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_quit(Monitor *mon, const QDict *qdict)
{
monitor_suspend(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_quit(Monitor *mon, const QDict *qdict);
void hmp_stop(Monitor *mon, const QDict *qdict);
void hmp_system_reset(Monitor *mon, const QDict *qdict);
.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",
};
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 = "",
##
{ 'command': 'query-cpus', 'returns': ['CpuInfo'] }
+##
+# @BlockDeviceInfo:
+#
+# Information about the backing device for a block device.
+#
+# @file: the filename of the backing device
+#
+# @ro: true if the backing device was open read-only
+#
+# @drv: the name of the block format used to open the backing device. As of
+# 0.14.0 this can be: 'blkdebug', 'bochs', 'cloop', 'cow', 'dmg',
+# 'file', 'file', 'ftp', 'ftps', 'host_cdrom', 'host_device',
+# 'host_floppy', 'http', 'https', 'nbd', 'parallels', 'qcow',
+# 'qcow2', 'raw', 'tftp', 'vdi', 'vmdk', 'vpc', 'vvfat'
+#
+# @backing_file: #optional the name of the backing file (for copy-on-write)
+#
+# @encrypted: true if the backing device is encrypted
+#
+# Since: 0.14.0
+#
+# Notes: This interface is only found in @BlockInfo.
+##
+{ 'type': 'BlockDeviceInfo',
+ 'data': { 'file': 'str', 'ro': 'bool', 'drv': 'str',
+ '*backing_file': 'str', 'encrypted': 'bool' } }
+
+##
+# @BlockDeviceIoStatus:
+#
+# An enumeration of block device I/O status.
+#
+# @ok: The last I/O operation has succeeded
+#
+# @failed: The last I/O operation has failed
+#
+# @nospace: The last I/O operation has failed due to a no-space condition
+#
+# Since: 1.0
+##
+{ 'enum': 'BlockDeviceIoStatus', 'data': [ 'ok', 'failed', 'nospace' ] }
+
+##
+# @BlockInfo:
+#
+# Block device information. This structure describes a virtual device and
+# the backing device associated with it.
+#
+# @device: The device name associated with the virtual device.
+#
+# @type: This field is returned only for compatibility reasons, it should
+# not be used (always returns 'unknown')
+#
+# @removable: True if the device supports removable media.
+#
+# @locked: True if the guest has locked this device from having its media
+# removed
+#
+# @tray_open: #optional True if the device has a tray and it is open
+# (only present if removable is true)
+#
+# @io-status: #optional @BlockDeviceIoStatus. Only present if the device
+# supports it and the VM is configured to stop on errors
+#
+# @inserted: #optional @BlockDeviceInfo describing the device if media is
+# present
+#
+# Since: 0.14.0
+##
+{ 'type': 'BlockInfo',
+ 'data': {'device': 'str', 'type': 'str', 'removable': 'bool',
+ 'locked': 'bool', '*inserted': 'BlockDeviceInfo',
+ '*tray_open': 'bool', '*io-status': 'BlockDeviceIoStatus'} }
+
+##
+# @query-block:
+#
+# Get a list of BlockInfo for all virtual block devices.
+#
+# Returns: a list of @BlockInfo describing each virtual block device
+#
+# Since: 0.14.0
+##
+{ 'command': 'query-block', 'returns': ['BlockInfo'] }
+
##
# @quit:
#
EQMP
+ {
+ .name = "query-block",
+ .args_type = "",
+ .mhandler.cmd_new = qmp_marshal_input_query_block,
+ },
+
SQMP
query-blockstats
----------------