Loading balloon.c +14 −58 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } /** Loading balloon.h +2 −4 Original line number Diff line number Diff line Loading @@ -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); Loading block.c +74 −160 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); } *ret_data = QOBJECT(bs_list); /* XXX: waiting for the qapi to support GSList */ if (!cur_item) { head = cur_item = info; } else { cur_item->next = info; cur_item = info; } static void bdrv_stats_iter(QObject *data, void *opaque) { QDict *qdict; Monitor *mon = opaque; qdict = qobject_to_qdict(data); monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); 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); return head; } static QObject* bdrv_info_stats_bs(BlockDriverState *bs) /* Consider exposing this as a full fledged QMP command */ static BlockStats *qmp_query_blockstat(const BlockDriverState *bs, Error **errp) { QObject *res; QDict *dict; BlockStats *s; 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); s = g_malloc0(sizeof(*s)); 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) Loading Loading @@ -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)); Loading @@ -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; } } Loading @@ -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; } } Loading block.h +0 −5 Original line number Diff line number Diff line Loading @@ -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); Loading block_int.h +3 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading Loading
balloon.c +14 −58 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } /** Loading
balloon.h +2 −4 Original line number Diff line number Diff line Loading @@ -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); Loading
block.c +74 −160 Original line number Diff line number Diff line Loading @@ -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> Loading Loading @@ -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); } *ret_data = QOBJECT(bs_list); /* XXX: waiting for the qapi to support GSList */ if (!cur_item) { head = cur_item = info; } else { cur_item->next = info; cur_item = info; } static void bdrv_stats_iter(QObject *data, void *opaque) { QDict *qdict; Monitor *mon = opaque; qdict = qobject_to_qdict(data); monitor_printf(mon, "%s:", qdict_get_str(qdict, "device")); 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); return head; } static QObject* bdrv_info_stats_bs(BlockDriverState *bs) /* Consider exposing this as a full fledged QMP command */ static BlockStats *qmp_query_blockstat(const BlockDriverState *bs, Error **errp) { QObject *res; QDict *dict; BlockStats *s; 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); s = g_malloc0(sizeof(*s)); 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) Loading Loading @@ -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)); Loading @@ -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; } } Loading @@ -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; } } Loading
block.h +0 −5 Original line number Diff line number Diff line Loading @@ -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); Loading
block_int.h +3 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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; Loading