HMP Pull 2020-03-09
Maxim's hmp block move, Thomas's deprecation in hostfwd. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEERfXHG0oMt/uXep+pBRYzHrxb/ecFAl5mnGUACgkQBRYzHrxb /ecC8A//QRdobRrhdFf7SmHN+SKPErB9ED3hvH7n7cBzG2+DfTUKoZg1SkMtEhj6 jS8Qkk4EXxAMo6rsSrUkiUwRaaLuCcfmDUKdkVqv/dGpASR+PeVvf7nU+G7TU2ha 5Ad/JS1dTBV0no8K9Hb9jzgWljgfj0LmNegtm5uf/6Ht961BaLF3RlT0IyWQKa3p FToLa8SQcdmV3GUNmVVH5kSjUcu3fWJNeHCbVekzuHGXBnHoUXrkB5H3V1SpuYi7 7rI7AiV3yWPrG81r6F6FMZlt+T6LdAcdfZoZMUaRE3+vXFzsUNGJ5rnEeyhnt5r3 ZCkD1ZR8MyZrc194FIK73GRFXJ8rhquZ/qShaHSBnAuINRkYMmu1e+bK+lZEvc6G 8EIfM7oeaHAYYY+n6niXFyC3F6RWsyYLiohN7wx4frgeODkYVQnW0wei6y8WJsHr 7SgqaWQ1UfCqfu/g/pjIovyqVhN4WV5KEaHILW+Cww7T1PQOG5j+1DC8qFoPxGeI TtHpQH5EILRz5Sf3EDMXdHWYOdxL0CTpyAQze6Qbc9A3tzIoCPv/wwwOEfDx9499 opIFWjAer0hQPJVavRLxvikrCY50xVOOJg3GLmArFOfpl8SgLhwevJiyX++8gv4k OiRNXntc4L9UizU12GIKdwEqusfZtpWdIjCjd3aLFjr6emxsKWs= =gE/h -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/dgilbert/tags/pull-hmp-20200309' into staging HMP Pull 2020-03-09 Maxim's hmp block move, Thomas's deprecation in hostfwd. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> # gpg: Signature made Mon 09 Mar 2020 19:43:33 GMT # gpg: using RSA key 45F5C71B4A0CB7FB977A9FA90516331EBC5BFDE7 # gpg: Good signature from "Dr. David Alan Gilbert (RH2) <dgilbert@redhat.com>" [full] # Primary key fingerprint: 45F5 C71B 4A0C B7FB 977A 9FA9 0516 331E BC5B FDE7 * remotes/dgilbert/tags/pull-hmp-20200309: net: Remove deprecated [hub_id name] tuple of 'hostfwd_add' / 'hostfwd_remove' monitor/hmp: Move hmp_drive_add_node to block-hmp-cmds.c monitor/hmp: move hmp_info_block* to block-hmp-cmds.c monitor/hmp: move remaining hmp_block* functions to block-hmp-cmds.c monitor/hmp: move hmp_nbd_server* to block-hmp-cmds.c monitor/hmp: move hmp_snapshot_* to block-hmp-cmds.c monitor/hmp: move hmp_block_job* to block-hmp-cmds.c monitor/hmp: move hmp_drive_mirror and hmp_drive_backup to block-hmp-cmds.c monitor/hmp: move hmp_drive_del and hmp_commit to block-hmp-cmds.c monitor/hmp: rename device-hotplug.c to block/monitor/block-hmp-cmds.c monitor/hmp: inline add_init_drive usb/dev-storage: remove unused include Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
7f368aed67
|
@ -1920,6 +1920,7 @@ Block QAPI, monitor, command line
|
|||
M: Markus Armbruster <armbru@redhat.com>
|
||||
S: Supported
|
||||
F: blockdev.c
|
||||
F: blockdev-hmp-cmds.c
|
||||
F: block/qapi.c
|
||||
F: qapi/block*.json
|
||||
F: qapi/transaction.json
|
||||
|
|
|
@ -48,7 +48,7 @@ common-obj-y += dump/
|
|||
common-obj-y += job-qmp.o
|
||||
common-obj-y += monitor/
|
||||
common-obj-y += net/
|
||||
common-obj-y += qdev-monitor.o device-hotplug.o
|
||||
common-obj-y += qdev-monitor.o
|
||||
common-obj-$(CONFIG_WIN32) += os-win32.o
|
||||
common-obj-$(CONFIG_POSIX) += os-posix.o
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ block-obj-y += crypto.o
|
|||
block-obj-y += aio_task.o
|
||||
block-obj-y += backup-top.o
|
||||
block-obj-y += filter-compress.o
|
||||
common-obj-y += monitor/
|
||||
|
||||
block-obj-y += stream.o
|
||||
|
||||
|
|
1
block/monitor/Makefile.objs
Normal file
1
block/monitor/Makefile.objs
Normal file
|
@ -0,0 +1 @@
|
|||
common-obj-y += block-hmp-cmds.o
|
1015
block/monitor/block-hmp-cmds.c
Normal file
1015
block/monitor/block-hmp-cmds.c
Normal file
File diff suppressed because it is too large
Load diff
137
blockdev.c
137
blockdev.c
|
@ -64,9 +64,14 @@
|
|||
#include "qemu/main-loop.h"
|
||||
#include "qemu/throttle-options.h"
|
||||
|
||||
static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
|
||||
QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
|
||||
QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states);
|
||||
|
||||
void bdrv_set_monitor_owned(BlockDriverState *bs)
|
||||
{
|
||||
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
|
||||
}
|
||||
|
||||
static const char *const if_name[IF_COUNT] = {
|
||||
[IF_NONE] = "none",
|
||||
[IF_IDE] = "ide",
|
||||
|
@ -640,7 +645,7 @@ err_no_opts:
|
|||
}
|
||||
|
||||
/* Takes the ownership of bs_opts */
|
||||
static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
|
||||
BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
|
||||
{
|
||||
int bdrv_flags = 0;
|
||||
|
||||
|
@ -1039,41 +1044,6 @@ static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp)
|
|||
return bs;
|
||||
}
|
||||
|
||||
void hmp_commit(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
BlockBackend *blk;
|
||||
int ret;
|
||||
|
||||
if (!strcmp(device, "all")) {
|
||||
ret = blk_commit_all();
|
||||
} else {
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
|
||||
blk = blk_by_name(device);
|
||||
if (!blk) {
|
||||
error_report("Device '%s' not found", device);
|
||||
return;
|
||||
}
|
||||
if (!blk_is_available(blk)) {
|
||||
error_report("Device '%s' has no medium", device);
|
||||
return;
|
||||
}
|
||||
|
||||
bs = blk_bs(blk);
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
ret = bdrv_commit(bs);
|
||||
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
if (ret < 0) {
|
||||
error_report("'commit' error for '%s': %s", device, strerror(-ret));
|
||||
}
|
||||
}
|
||||
|
||||
static void blockdev_do_action(TransactionAction *action, Error **errp)
|
||||
{
|
||||
TransactionActionList list;
|
||||
|
@ -2747,66 +2717,6 @@ BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
|
|||
return ret;
|
||||
}
|
||||
|
||||
void hmp_drive_del(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *id = qdict_get_str(qdict, "id");
|
||||
BlockBackend *blk;
|
||||
BlockDriverState *bs;
|
||||
AioContext *aio_context;
|
||||
Error *local_err = NULL;
|
||||
|
||||
bs = bdrv_find_node(id);
|
||||
if (bs) {
|
||||
qmp_blockdev_del(id, &local_err);
|
||||
if (local_err) {
|
||||
error_report_err(local_err);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
blk = blk_by_name(id);
|
||||
if (!blk) {
|
||||
error_report("Device '%s' not found", id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!blk_legacy_dinfo(blk)) {
|
||||
error_report("Deleting device added with blockdev-add"
|
||||
" is not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
aio_context = blk_get_aio_context(blk);
|
||||
aio_context_acquire(aio_context);
|
||||
|
||||
bs = blk_bs(blk);
|
||||
if (bs) {
|
||||
if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
|
||||
error_report_err(local_err);
|
||||
aio_context_release(aio_context);
|
||||
return;
|
||||
}
|
||||
|
||||
blk_remove_bs(blk);
|
||||
}
|
||||
|
||||
/* Make the BlockBackend and the attached BlockDriverState anonymous */
|
||||
monitor_remove_blk(blk);
|
||||
|
||||
/* If this BlockBackend has a device attached to it, its refcount will be
|
||||
* decremented when the device is removed; otherwise we have to do so here.
|
||||
*/
|
||||
if (blk_get_attached_dev(blk)) {
|
||||
/* Further I/O must not pause the guest */
|
||||
blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT,
|
||||
BLOCKDEV_ON_ERROR_REPORT);
|
||||
} else {
|
||||
blk_unref(blk);
|
||||
}
|
||||
|
||||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
void qmp_block_resize(bool has_device, const char *device,
|
||||
bool has_node_name, const char *node_name,
|
||||
int64_t size, Error **errp)
|
||||
|
@ -3814,37 +3724,6 @@ out:
|
|||
aio_context_release(aio_context);
|
||||
}
|
||||
|
||||
void hmp_drive_add_node(Monitor *mon, const char *optstr)
|
||||
{
|
||||
QemuOpts *opts;
|
||||
QDict *qdict;
|
||||
Error *local_err = NULL;
|
||||
|
||||
opts = qemu_opts_parse_noisily(&qemu_drive_opts, optstr, false);
|
||||
if (!opts) {
|
||||
return;
|
||||
}
|
||||
|
||||
qdict = qemu_opts_to_qdict(opts, NULL);
|
||||
|
||||
if (!qdict_get_try_str(qdict, "node-name")) {
|
||||
qobject_unref(qdict);
|
||||
error_report("'node-name' needs to be specified");
|
||||
goto out;
|
||||
}
|
||||
|
||||
BlockDriverState *bs = bds_tree_init(qdict, &local_err);
|
||||
if (!bs) {
|
||||
error_report_err(local_err);
|
||||
goto out;
|
||||
}
|
||||
|
||||
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
|
||||
|
||||
out:
|
||||
qemu_opts_del(opts);
|
||||
}
|
||||
|
||||
void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
|
@ -3874,7 +3753,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list);
|
||||
bdrv_set_monitor_owned(bs);
|
||||
|
||||
fail:
|
||||
visit_free(v);
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* QEMU device hotplug helpers
|
||||
*
|
||||
* Copyright (c) 2004 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/boards.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "sysemu/blockdev.h"
|
||||
#include "qapi/qmp/qdict.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/config-file.h"
|
||||
#include "qemu/option.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "block/block_int.h"
|
||||
|
||||
static DriveInfo *add_init_drive(const char *optstr)
|
||||
{
|
||||
Error *err = NULL;
|
||||
DriveInfo *dinfo;
|
||||
QemuOpts *opts;
|
||||
MachineClass *mc;
|
||||
|
||||
opts = drive_def(optstr);
|
||||
if (!opts)
|
||||
return NULL;
|
||||
|
||||
mc = MACHINE_GET_CLASS(current_machine);
|
||||
dinfo = drive_new(opts, mc->block_default_type, &err);
|
||||
if (err) {
|
||||
error_report_err(err);
|
||||
qemu_opts_del(opts);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dinfo;
|
||||
}
|
||||
|
||||
void hmp_drive_add(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
DriveInfo *dinfo = NULL;
|
||||
const char *opts = qdict_get_str(qdict, "opts");
|
||||
bool node = qdict_get_try_bool(qdict, "node", false);
|
||||
|
||||
if (node) {
|
||||
hmp_drive_add_node(mon, opts);
|
||||
return;
|
||||
}
|
||||
|
||||
dinfo = add_init_drive(opts);
|
||||
if (!dinfo) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (dinfo->type) {
|
||||
case IF_NONE:
|
||||
monitor_printf(mon, "OK\n");
|
||||
break;
|
||||
default:
|
||||
monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);
|
||||
goto err;
|
||||
}
|
||||
return;
|
||||
|
||||
err:
|
||||
if (dinfo) {
|
||||
BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
|
||||
monitor_remove_blk(blk);
|
||||
blk_unref(blk);
|
||||
}
|
||||
}
|
|
@ -248,12 +248,6 @@ the 'wait' field, which is only applicable to sockets in server mode
|
|||
Human Monitor Protocol (HMP) commands
|
||||
-------------------------------------
|
||||
|
||||
The ``hub_id`` parameter of ``hostfwd_add`` / ``hostfwd_remove`` (since 3.1)
|
||||
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and
|
||||
'hostfwd_remove' HMP commands has been replaced by ``netdev_id``.
|
||||
|
||||
``cpu-add`` (since 4.0)
|
||||
'''''''''''''''''''''''
|
||||
|
||||
|
@ -430,6 +424,15 @@ QEMU Machine Protocol (QMP) commands
|
|||
The "autoload" parameter has been ignored since 2.12.0. All bitmaps
|
||||
are automatically loaded from qcow2 images.
|
||||
|
||||
Human Monitor Protocol (HMP) commands
|
||||
-------------------------------------
|
||||
|
||||
The ``hub_id`` parameter of ``hostfwd_add`` / ``hostfwd_remove`` (removed in 5.0)
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and
|
||||
'hostfwd_remove' HMP commands has been replaced by ``netdev_id``.
|
||||
|
||||
Related binaries
|
||||
----------------
|
||||
|
||||
|
|
|
@ -1369,8 +1369,8 @@ ERST
|
|||
#ifdef CONFIG_SLIRP
|
||||
{
|
||||
.name = "hostfwd_add",
|
||||
.args_type = "arg1:s,arg2:s?,arg3:s?",
|
||||
.params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
|
||||
.args_type = "arg1:s,arg2:s?",
|
||||
.params = "[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
|
||||
.help = "redirect TCP or UDP connections from host to guest (requires -net user)",
|
||||
.cmd = hmp_hostfwd_add,
|
||||
},
|
||||
|
@ -1383,8 +1383,8 @@ ERST
|
|||
#ifdef CONFIG_SLIRP
|
||||
{
|
||||
.name = "hostfwd_remove",
|
||||
.args_type = "arg1:s,arg2:s?,arg3:s?",
|
||||
.params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport",
|
||||
.args_type = "arg1:s,arg2:s?",
|
||||
.params = "[netdev_id] [tcp|udp]:[hostaddr]:hostport",
|
||||
.help = "remove host-to-guest TCP or UDP redirection",
|
||||
.cmd = hmp_hostfwd_remove,
|
||||
},
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "hw/qdev-properties.h"
|
||||
#include "hw/scsi/scsi.h"
|
||||
#include "migration/vmstate.h"
|
||||
#include "monitor/monitor.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "sysemu/block-backend.h"
|
||||
#include "qapi/visitor.h"
|
||||
|
|
54
include/block/block-hmp-cmds.h
Normal file
54
include/block/block-hmp-cmds.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* HMP commands related to the block layer
|
||||
*
|
||||
* Copyright (c) 2003-2008 Fabrice Bellard
|
||||
* Copyright (c) 2020 Red Hat, Inc.
|
||||
* Copyright IBM, Corp. 2011
|
||||
*
|
||||
* Authors:
|
||||
* Anthony Liguori <aliguori@us.ibm.com>
|
||||
*
|
||||
* This work is licensed under the terms of the GNU GPL, version 2. See
|
||||
* the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef BLOCK_HMP_COMMANDS_H
|
||||
#define BLOCK_HMP_COMMANDS_H
|
||||
|
||||
void hmp_drive_add(Monitor *mon, const QDict *qdict);
|
||||
|
||||
void hmp_commit(Monitor *mon, const QDict *qdict);
|
||||
void hmp_drive_del(Monitor *mon, const QDict *qdict);
|
||||
|
||||
void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
|
||||
void hmp_drive_backup(Monitor *mon, const QDict *qdict);
|
||||
|
||||
void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
|
||||
|
||||
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
|
||||
void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
|
||||
void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
|
||||
|
||||
void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
|
||||
|
||||
void hmp_block_resize(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_stream(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_passwd(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
|
||||
void hmp_eject(Monitor *mon, const QDict *qdict);
|
||||
|
||||
void hmp_qemu_io(Monitor *mon, const QDict *qdict);
|
||||
|
||||
void hmp_info_block(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
|
||||
|
||||
#endif
|
|
@ -1216,8 +1216,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
|
|||
BlockCompletionFunc *cb, void *opaque,
|
||||
JobTxn *txn, Error **errp);
|
||||
|
||||
void hmp_drive_add_node(Monitor *mon, const char *optstr);
|
||||
|
||||
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
|
||||
const char *child_name,
|
||||
const BdrvChildRole *child_role,
|
||||
|
@ -1322,4 +1320,7 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, uint64_t src_offset,
|
|||
|
||||
int refresh_total_sectors(BlockDriverState *bs, int64_t hint);
|
||||
|
||||
void bdrv_set_monitor_owned(BlockDriverState *bs);
|
||||
BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp);
|
||||
|
||||
#endif /* BLOCK_INT_H */
|
||||
|
|
|
@ -30,8 +30,6 @@ void hmp_info_migrate_capabilities(Monitor *mon, const QDict *qdict);
|
|||
void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_cpus(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_block(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_blockstats(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_vnc(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_spice(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_balloon(Monitor *mon, const QDict *qdict);
|
||||
|
@ -39,7 +37,6 @@ void hmp_info_irq(Monitor *mon, const QDict *qdict);
|
|||
void hmp_info_pic(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_rdma(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_pci(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_tpm(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_iothreads(Monitor *mon, const QDict *qdict);
|
||||
void hmp_quit(Monitor *mon, const QDict *qdict);
|
||||
|
@ -58,18 +55,10 @@ void hmp_cont(Monitor *mon, const QDict *qdict);
|
|||
void hmp_system_wakeup(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nmi(Monitor *mon, const QDict *qdict);
|
||||
void hmp_set_link(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_passwd(Monitor *mon, const QDict *qdict);
|
||||
void hmp_balloon(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_resize(Monitor *mon, const QDict *qdict);
|
||||
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict);
|
||||
void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict);
|
||||
void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict);
|
||||
void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
|
||||
void hmp_drive_backup(Monitor *mon, const QDict *qdict);
|
||||
void hmp_loadvm(Monitor *mon, const QDict *qdict);
|
||||
void hmp_savevm(Monitor *mon, const QDict *qdict);
|
||||
void hmp_delvm(Monitor *mon, const QDict *qdict);
|
||||
void hmp_info_snapshots(Monitor *mon, const QDict *qdict);
|
||||
void hmp_migrate_cancel(Monitor *mon, const QDict *qdict);
|
||||
void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
|
||||
void hmp_migrate_incoming(Monitor *mon, const QDict *qdict);
|
||||
|
@ -85,15 +74,7 @@ void hmp_migrate_start_postcopy(Monitor *mon, const QDict *qdict);
|
|||
void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
|
||||
void hmp_set_password(Monitor *mon, const QDict *qdict);
|
||||
void hmp_expire_password(Monitor *mon, const QDict *qdict);
|
||||
void hmp_eject(Monitor *mon, const QDict *qdict);
|
||||
void hmp_change(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_stream(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_job_cancel(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_job_pause(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_job_resume(Monitor *mon, const QDict *qdict);
|
||||
void hmp_block_job_complete(Monitor *mon, const QDict *qdict);
|
||||
void hmp_migrate(Monitor *mon, const QDict *qdict);
|
||||
void hmp_device_add(Monitor *mon, const QDict *qdict);
|
||||
void hmp_device_del(Monitor *mon, const QDict *qdict);
|
||||
|
@ -104,15 +85,10 @@ void hmp_getfd(Monitor *mon, const QDict *qdict);
|
|||
void hmp_closefd(Monitor *mon, const QDict *qdict);
|
||||
void hmp_sendkey(Monitor *mon, const QDict *qdict);
|
||||
void hmp_screendump(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nbd_server_start(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nbd_server_add(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict);
|
||||
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
|
||||
void hmp_chardev_add(Monitor *mon, const QDict *qdict);
|
||||
void hmp_chardev_change(Monitor *mon, const QDict *qdict);
|
||||
void hmp_chardev_remove(Monitor *mon, const QDict *qdict);
|
||||
void hmp_chardev_send_break(Monitor *mon, const QDict *qdict);
|
||||
void hmp_qemu_io(Monitor *mon, const QDict *qdict);
|
||||
void hmp_cpu_add(Monitor *mon, const QDict *qdict);
|
||||
void hmp_object_add(Monitor *mon, const QDict *qdict);
|
||||
void hmp_object_del(Monitor *mon, const QDict *qdict);
|
||||
|
|
|
@ -57,8 +57,4 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
|
|||
DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type,
|
||||
Error **errp);
|
||||
|
||||
/* device-hotplug */
|
||||
|
||||
void hmp_commit(Monitor *mon, const QDict *qdict);
|
||||
void hmp_drive_del(Monitor *mon, const QDict *qdict);
|
||||
#endif
|
||||
|
|
|
@ -63,9 +63,6 @@ extern int nb_option_roms;
|
|||
extern const char *prom_envs[MAX_PROM_ENVS];
|
||||
extern unsigned int nb_prom_envs;
|
||||
|
||||
/* generic hotplug */
|
||||
void hmp_drive_add(Monitor *mon, const QDict *qdict);
|
||||
|
||||
/* pcie aer error injection */
|
||||
void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict);
|
||||
|
||||
|
|
|
@ -47,9 +47,6 @@
|
|||
#include "qapi/string-output-visitor.h"
|
||||
#include "qom/object_interfaces.h"
|
||||
#include "ui/console.h"
|
||||
#include "block/nbd.h"
|
||||
#include "block/qapi.h"
|
||||
#include "qemu-io.h"
|
||||
#include "qemu/cutils.h"
|
||||
#include "qemu/error-report.h"
|
||||
#include "exec/ramlist.h"
|
||||
|
@ -472,213 +469,6 @@ void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict)
|
|||
qmp_query_migrate_cache_size(NULL) >> 10);
|
||||
}
|
||||
|
||||
static void print_block_info(Monitor *mon, BlockInfo *info,
|
||||
BlockDeviceInfo *inserted, bool verbose)
|
||||
{
|
||||
ImageInfo *image_info;
|
||||
|
||||
assert(!info || !info->has_inserted || info->inserted == inserted);
|
||||
|
||||
if (info && *info->device) {
|
||||
monitor_printf(mon, "%s", info->device);
|
||||
if (inserted && inserted->has_node_name) {
|
||||
monitor_printf(mon, " (%s)", inserted->node_name);
|
||||
}
|
||||
} else {
|
||||
assert(info || inserted);
|
||||
monitor_printf(mon, "%s",
|
||||
inserted && inserted->has_node_name ? inserted->node_name
|
||||
: info && info->has_qdev ? info->qdev
|
||||
: "<anonymous>");
|
||||
}
|
||||
|
||||
if (inserted) {
|
||||
monitor_printf(mon, ": %s (%s%s%s)\n",
|
||||
inserted->file,
|
||||
inserted->drv,
|
||||
inserted->ro ? ", read-only" : "",
|
||||
inserted->encrypted ? ", encrypted" : "");
|
||||
} else {
|
||||
monitor_printf(mon, ": [not inserted]\n");
|
||||
}
|
||||
|
||||
if (info) {
|
||||
if (info->has_qdev) {
|
||||
monitor_printf(mon, " Attached to: %s\n", info->qdev);
|
||||
}
|
||||
if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
|
||||
monitor_printf(mon, " I/O status: %s\n",
|
||||
BlockDeviceIoStatus_str(info->io_status));
|
||||
}
|
||||
|
||||
if (info->removable) {
|
||||
monitor_printf(mon, " Removable device: %slocked, tray %s\n",
|
||||
info->locked ? "" : "not ",
|
||||
info->tray_open ? "open" : "closed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!inserted) {
|
||||
return;
|
||||
}
|
||||
|
||||
monitor_printf(mon, " Cache mode: %s%s%s\n",
|
||||
inserted->cache->writeback ? "writeback" : "writethrough",
|
||||
inserted->cache->direct ? ", direct" : "",
|
||||
inserted->cache->no_flush ? ", ignore flushes" : "");
|
||||
|
||||
if (inserted->has_backing_file) {
|
||||
monitor_printf(mon,
|
||||
" Backing file: %s "
|
||||
"(chain depth: %" PRId64 ")\n",
|
||||
inserted->backing_file,
|
||||
inserted->backing_file_depth);
|
||||
}
|
||||
|
||||
if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) {
|
||||
monitor_printf(mon, " Detect zeroes: %s\n",
|
||||
BlockdevDetectZeroesOptions_str(inserted->detect_zeroes));
|
||||
}
|
||||
|
||||
if (inserted->bps || inserted->bps_rd || inserted->bps_wr ||
|
||||
inserted->iops || inserted->iops_rd || inserted->iops_wr)
|
||||
{
|
||||
monitor_printf(mon, " I/O throttling: bps=%" PRId64
|
||||
" bps_rd=%" PRId64 " bps_wr=%" PRId64
|
||||
" bps_max=%" PRId64
|
||||
" bps_rd_max=%" PRId64
|
||||
" bps_wr_max=%" PRId64
|
||||
" iops=%" PRId64 " iops_rd=%" PRId64
|
||||
" iops_wr=%" PRId64
|
||||
" iops_max=%" PRId64
|
||||
" iops_rd_max=%" PRId64
|
||||
" iops_wr_max=%" PRId64
|
||||
" iops_size=%" PRId64
|
||||
" group=%s\n",
|
||||
inserted->bps,
|
||||
inserted->bps_rd,
|
||||
inserted->bps_wr,
|
||||
inserted->bps_max,
|
||||
inserted->bps_rd_max,
|
||||
inserted->bps_wr_max,
|
||||
inserted->iops,
|
||||
inserted->iops_rd,
|
||||
inserted->iops_wr,
|
||||
inserted->iops_max,
|
||||
inserted->iops_rd_max,
|
||||
inserted->iops_wr_max,
|
||||
inserted->iops_size,
|
||||
inserted->group);
|
||||
}
|
||||
|
||||
if (verbose) {
|
||||
monitor_printf(mon, "\nImages:\n");
|
||||
image_info = inserted->image;
|
||||
while (1) {
|
||||
bdrv_image_info_dump(image_info);
|
||||
if (image_info->has_backing_image) {
|
||||
image_info = image_info->backing_image;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hmp_info_block(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BlockInfoList *block_list, *info;
|
||||
BlockDeviceInfoList *blockdev_list, *blockdev;
|
||||
const char *device = qdict_get_try_str(qdict, "device");
|
||||
bool verbose = qdict_get_try_bool(qdict, "verbose", false);
|
||||
bool nodes = qdict_get_try_bool(qdict, "nodes", false);
|
||||
bool printed = false;
|
||||
|
||||
/* Print BlockBackend information */
|
||||
if (!nodes) {
|
||||
block_list = qmp_query_block(NULL);
|
||||
} else {
|
||||
block_list = NULL;
|
||||
}
|
||||
|
||||
for (info = block_list; info; info = info->next) {
|
||||
if (device && strcmp(device, info->value->device)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (info != block_list) {
|
||||
monitor_printf(mon, "\n");
|
||||
}
|
||||
|
||||
print_block_info(mon, info->value, info->value->has_inserted
|
||||
? info->value->inserted : NULL,
|
||||
verbose);
|
||||
printed = true;
|
||||
}
|
||||
|
||||
qapi_free_BlockInfoList(block_list);
|
||||
|
||||
if ((!device && !nodes) || printed) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Print node information */
|
||||
blockdev_list = qmp_query_named_block_nodes(false, false, NULL);
|
||||
for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) {
|
||||
assert(blockdev->value->has_node_name);
|
||||
if (device && strcmp(device, blockdev->value->node_name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (blockdev != blockdev_list) {
|
||||
monitor_printf(mon, "\n");
|
||||
}
|
||||
|
||||
print_block_info(mon, NULL, blockdev->value, verbose);
|
||||
}
|
||||
qapi_free_BlockDeviceInfoList(blockdev_list);
|
||||
}
|
||||
|
||||
void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BlockStatsList *stats_list, *stats;
|
||||
|
||||
stats_list = qmp_query_blockstats(false, false, 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
|
||||
" rd_merged=%" PRId64
|
||||
" wr_merged=%" PRId64
|
||||
" idle_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,
|
||||
stats->value->stats->rd_merged,
|
||||
stats->value->stats->wr_merged,
|
||||
stats->value->stats->idle_time_ns);
|
||||
}
|
||||
|
||||
qapi_free_BlockStatsList(stats_list);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VNC
|
||||
/* Helper for hmp_info_vnc_clients, _servers */
|
||||
|
@ -1058,44 +848,6 @@ void hmp_info_pci(Monitor *mon, const QDict *qdict)
|
|||
qapi_free_PciInfoList(info_list);
|
||||
}
|
||||
|
||||
void hmp_info_block_jobs(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BlockJobInfoList *list;
|
||||
Error *err = NULL;
|
||||
|
||||
list = qmp_query_block_jobs(&err);
|
||||
assert(!err);
|
||||
|
||||
if (!list) {
|
||||
monitor_printf(mon, "No active jobs\n");
|
||||
return;
|
||||
}
|
||||
|
||||
while (list) {
|
||||
if (strcmp(list->value->type, "stream") == 0) {
|
||||
monitor_printf(mon, "Streaming device %s: Completed %" PRId64
|
||||
" of %" PRId64 " bytes, speed limit %" PRId64
|
||||
" bytes/s\n",
|
||||
list->value->device,
|
||||
list->value->offset,
|
||||
list->value->len,
|
||||
list->value->speed);
|
||||
} else {
|
||||
monitor_printf(mon, "Type %s, device %s: Completed %" PRId64
|
||||
" of %" PRId64 " bytes, speed limit %" PRId64
|
||||
" bytes/s\n",
|
||||
list->value->type,
|
||||
list->value->device,
|
||||
list->value->offset,
|
||||
list->value->len,
|
||||
list->value->speed);
|
||||
}
|
||||
list = list->next;
|
||||
}
|
||||
|
||||
qapi_free_BlockJobInfoList(list);
|
||||
}
|
||||
|
||||
void hmp_info_tpm(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
TPMInfoList *info_list, *info;
|
||||
|
@ -1313,16 +1065,6 @@ void hmp_set_link(Monitor *mon, const QDict *qdict)
|
|||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_block_passwd(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
const char *password = qdict_get_str(qdict, "password");
|
||||
Error *err = NULL;
|
||||
|
||||
qmp_block_passwd(true, device, false, NULL, password, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_balloon(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
int64_t value = qdict_get_int(qdict, "value");
|
||||
|
@ -1332,121 +1074,6 @@ void hmp_balloon(Monitor *mon, const QDict *qdict)
|
|||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_block_resize(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
int64_t size = qdict_get_int(qdict, "size");
|
||||
Error *err = NULL;
|
||||
|
||||
qmp_block_resize(true, device, false, NULL, size, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *filename = qdict_get_str(qdict, "target");
|
||||
const char *format = qdict_get_try_str(qdict, "format");
|
||||
bool reuse = qdict_get_try_bool(qdict, "reuse", false);
|
||||
bool full = qdict_get_try_bool(qdict, "full", false);
|
||||
Error *err = NULL;
|
||||
DriveMirror mirror = {
|
||||
.device = (char *)qdict_get_str(qdict, "device"),
|
||||
.target = (char *)filename,
|
||||
.has_format = !!format,
|
||||
.format = (char *)format,
|
||||
.sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
|
||||
.has_mode = true,
|
||||
.mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
|
||||
.unmap = true,
|
||||
};
|
||||
|
||||
if (!filename) {
|
||||
error_setg(&err, QERR_MISSING_PARAMETER, "target");
|
||||
hmp_handle_error(mon, err);
|
||||
return;
|
||||
}
|
||||
qmp_drive_mirror(&mirror, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_drive_backup(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
const char *filename = qdict_get_str(qdict, "target");
|
||||
const char *format = qdict_get_try_str(qdict, "format");
|
||||
bool reuse = qdict_get_try_bool(qdict, "reuse", false);
|
||||
bool full = qdict_get_try_bool(qdict, "full", false);
|
||||
bool compress = qdict_get_try_bool(qdict, "compress", false);
|
||||
Error *err = NULL;
|
||||
DriveBackup backup = {
|
||||
.device = (char *)device,
|
||||
.target = (char *)filename,
|
||||
.has_format = !!format,
|
||||
.format = (char *)format,
|
||||
.sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
|
||||
.has_mode = true,
|
||||
.mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
|
||||
.has_compress = !!compress,
|
||||
.compress = compress,
|
||||
};
|
||||
|
||||
if (!filename) {
|
||||
error_setg(&err, QERR_MISSING_PARAMETER, "target");
|
||||
hmp_handle_error(mon, err);
|
||||
return;
|
||||
}
|
||||
|
||||
qmp_drive_backup(&backup, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
const char *filename = qdict_get_try_str(qdict, "snapshot-file");
|
||||
const char *format = qdict_get_try_str(qdict, "format");
|
||||
bool reuse = qdict_get_try_bool(qdict, "reuse", false);
|
||||
enum NewImageMode mode;
|
||||
Error *err = NULL;
|
||||
|
||||
if (!filename) {
|
||||
/* In the future, if 'snapshot-file' is not specified, the snapshot
|
||||
will be taken internally. Today it's actually required. */
|
||||
error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file");
|
||||
hmp_handle_error(mon, err);
|
||||
return;
|
||||
}
|
||||
|
||||
mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
|
||||
qmp_blockdev_snapshot_sync(true, device, false, NULL,
|
||||
filename, false, NULL,
|
||||
!!format, format,
|
||||
true, mode, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
const char *name = qdict_get_str(qdict, "name");
|
||||
Error *err = NULL;
|
||||
|
||||
qmp_blockdev_snapshot_internal_sync(device, name, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
const char *name = qdict_get_str(qdict, "name");
|
||||
const char *id = qdict_get_try_str(qdict, "id");
|
||||
Error *err = NULL;
|
||||
|
||||
qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
|
||||
true, name, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_loadvm(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
int saved_vm_running = runstate_is_running();
|
||||
|
@ -1483,148 +1110,6 @@ void hmp_delvm(Monitor *mon, const QDict *qdict)
|
|||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BlockDriverState *bs, *bs1;
|
||||
BdrvNextIterator it1;
|
||||
QEMUSnapshotInfo *sn_tab, *sn;
|
||||
bool no_snapshot = true;
|
||||
int nb_sns, i;
|
||||
int total;
|
||||
int *global_snapshots;
|
||||
AioContext *aio_context;
|
||||
|
||||
typedef struct SnapshotEntry {
|
||||
QEMUSnapshotInfo sn;
|
||||
QTAILQ_ENTRY(SnapshotEntry) next;
|
||||
} SnapshotEntry;
|
||||
|
||||
typedef struct ImageEntry {
|
||||
const char *imagename;
|
||||
QTAILQ_ENTRY(ImageEntry) next;
|
||||
QTAILQ_HEAD(, SnapshotEntry) snapshots;
|
||||
} ImageEntry;
|
||||
|
||||
QTAILQ_HEAD(, ImageEntry) image_list =
|
||||
QTAILQ_HEAD_INITIALIZER(image_list);
|
||||
|
||||
ImageEntry *image_entry, *next_ie;
|
||||
SnapshotEntry *snapshot_entry;
|
||||
|
||||
bs = bdrv_all_find_vmstate_bs();
|
||||
if (!bs) {
|
||||
monitor_printf(mon, "No available block device supports snapshots\n");
|
||||
return;
|
||||
}
|
||||
aio_context = bdrv_get_aio_context(bs);
|
||||
|
||||
aio_context_acquire(aio_context);
|
||||
nb_sns = bdrv_snapshot_list(bs, &sn_tab);
|
||||
aio_context_release(aio_context);
|
||||
|
||||
if (nb_sns < 0) {
|
||||
monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);
|
||||
return;
|
||||
}
|
||||
|
||||
for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) {
|
||||
int bs1_nb_sns = 0;
|
||||
ImageEntry *ie;
|
||||
SnapshotEntry *se;
|
||||
AioContext *ctx = bdrv_get_aio_context(bs1);
|
||||
|
||||
aio_context_acquire(ctx);
|
||||
if (bdrv_can_snapshot(bs1)) {
|
||||
sn = NULL;
|
||||
bs1_nb_sns = bdrv_snapshot_list(bs1, &sn);
|
||||
if (bs1_nb_sns > 0) {
|
||||
no_snapshot = false;
|
||||
ie = g_new0(ImageEntry, 1);
|
||||
ie->imagename = bdrv_get_device_name(bs1);
|
||||
QTAILQ_INIT(&ie->snapshots);
|
||||
QTAILQ_INSERT_TAIL(&image_list, ie, next);
|
||||
for (i = 0; i < bs1_nb_sns; i++) {
|
||||
se = g_new0(SnapshotEntry, 1);
|
||||
se->sn = sn[i];
|
||||
QTAILQ_INSERT_TAIL(&ie->snapshots, se, next);
|
||||
}
|
||||
}
|
||||
g_free(sn);
|
||||
}
|
||||
aio_context_release(ctx);
|
||||
}
|
||||
|
||||
if (no_snapshot) {
|
||||
monitor_printf(mon, "There is no snapshot available.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
global_snapshots = g_new0(int, nb_sns);
|
||||
total = 0;
|
||||
for (i = 0; i < nb_sns; i++) {
|
||||
SnapshotEntry *next_sn;
|
||||
if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) {
|
||||
global_snapshots[total] = i;
|
||||
total++;
|
||||
QTAILQ_FOREACH(image_entry, &image_list, next) {
|
||||
QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots,
|
||||
next, next_sn) {
|
||||
if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) {
|
||||
QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry,
|
||||
next);
|
||||
g_free(snapshot_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
monitor_printf(mon, "List of snapshots present on all disks:\n");
|
||||
|
||||
if (total > 0) {
|
||||
bdrv_snapshot_dump(NULL);
|
||||
monitor_printf(mon, "\n");
|
||||
for (i = 0; i < total; i++) {
|
||||
sn = &sn_tab[global_snapshots[i]];
|
||||
/* The ID is not guaranteed to be the same on all images, so
|
||||
* overwrite it.
|
||||
*/
|
||||
pstrcpy(sn->id_str, sizeof(sn->id_str), "--");
|
||||
bdrv_snapshot_dump(sn);
|
||||
monitor_printf(mon, "\n");
|
||||
}
|
||||
} else {
|
||||
monitor_printf(mon, "None\n");
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH(image_entry, &image_list, next) {
|
||||
if (QTAILQ_EMPTY(&image_entry->snapshots)) {
|
||||
continue;
|
||||
}
|
||||
monitor_printf(mon,
|
||||
"\nList of partial (non-loadable) snapshots on '%s':\n",
|
||||
image_entry->imagename);
|
||||
bdrv_snapshot_dump(NULL);
|
||||
monitor_printf(mon, "\n");
|
||||
QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) {
|
||||
bdrv_snapshot_dump(&snapshot_entry->sn);
|
||||
monitor_printf(mon, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) {
|
||||
SnapshotEntry *next_sn;
|
||||
QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next,
|
||||
next_sn) {
|
||||
g_free(snapshot_entry);
|
||||
}
|
||||
g_free(image_entry);
|
||||
}
|
||||
g_free(sn_tab);
|
||||
g_free(global_snapshots);
|
||||
|
||||
}
|
||||
|
||||
void hmp_announce_self(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
|
||||
|
@ -1946,15 +1431,6 @@ void hmp_expire_password(Monitor *mon, const QDict *qdict)
|
|||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_eject(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
bool force = qdict_get_try_bool(qdict, "force", false);
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
Error *err = NULL;
|
||||
|
||||
qmp_eject(true, device, false, NULL, true, force, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_VNC
|
||||
static void hmp_change_read_arg(void *opaque, const char *password,
|
||||
|
@ -2012,101 +1488,6 @@ void hmp_change(Monitor *mon, const QDict *qdict)
|
|||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *err = NULL;
|
||||
char *device = (char *) qdict_get_str(qdict, "device");
|
||||
BlockIOThrottle throttle = {
|
||||
.bps = qdict_get_int(qdict, "bps"),
|
||||
.bps_rd = qdict_get_int(qdict, "bps_rd"),
|
||||
.bps_wr = qdict_get_int(qdict, "bps_wr"),
|
||||
.iops = qdict_get_int(qdict, "iops"),
|
||||
.iops_rd = qdict_get_int(qdict, "iops_rd"),
|
||||
.iops_wr = qdict_get_int(qdict, "iops_wr"),
|
||||
};
|
||||
|
||||
/* qmp_block_set_io_throttle has separate parameters for the
|
||||
* (deprecated) block device name and the qdev ID but the HMP
|
||||
* version has only one, so we must decide which one to pass. */
|
||||
if (blk_by_name(device)) {
|
||||
throttle.has_device = true;
|
||||
throttle.device = device;
|
||||
} else {
|
||||
throttle.has_id = true;
|
||||
throttle.id = device;
|
||||
}
|
||||
|
||||
qmp_block_set_io_throttle(&throttle, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_block_stream(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *error = NULL;
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
const char *base = qdict_get_try_str(qdict, "base");
|
||||
int64_t speed = qdict_get_try_int(qdict, "speed", 0);
|
||||
|
||||
qmp_block_stream(true, device, device, base != NULL, base, false, NULL,
|
||||
false, NULL, qdict_haskey(qdict, "speed"), speed, true,
|
||||
BLOCKDEV_ON_ERROR_REPORT, false, false, false, false,
|
||||
&error);
|
||||
|
||||
hmp_handle_error(mon, error);
|
||||
}
|
||||
|
||||
void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *error = NULL;
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
int64_t value = qdict_get_int(qdict, "speed");
|
||||
|
||||
qmp_block_job_set_speed(device, value, &error);
|
||||
|
||||
hmp_handle_error(mon, error);
|
||||
}
|
||||
|
||||
void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *error = NULL;
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
bool force = qdict_get_try_bool(qdict, "force", false);
|
||||
|
||||
qmp_block_job_cancel(device, true, force, &error);
|
||||
|
||||
hmp_handle_error(mon, error);
|
||||
}
|
||||
|
||||
void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *error = NULL;
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
|
||||
qmp_block_job_pause(device, &error);
|
||||
|
||||
hmp_handle_error(mon, error);
|
||||
}
|
||||
|
||||
void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *error = NULL;
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
|
||||
qmp_block_job_resume(device, &error);
|
||||
|
||||
hmp_handle_error(mon, error);
|
||||
}
|
||||
|
||||
void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *error = NULL;
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
|
||||
qmp_block_job_complete(device, &error);
|
||||
|
||||
hmp_handle_error(mon, error);
|
||||
}
|
||||
|
||||
typedef struct HMPMigrationStatus
|
||||
{
|
||||
QEMUTimer *timer;
|
||||
|
@ -2333,105 +1714,6 @@ void hmp_screendump(Monitor *mon, const QDict *qdict)
|
|||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *uri = qdict_get_str(qdict, "uri");
|
||||
bool writable = qdict_get_try_bool(qdict, "writable", false);
|
||||
bool all = qdict_get_try_bool(qdict, "all", false);
|
||||
Error *local_err = NULL;
|
||||
BlockInfoList *block_list, *info;
|
||||
SocketAddress *addr;
|
||||
BlockExportNbd export;
|
||||
|
||||
if (writable && !all) {
|
||||
error_setg(&local_err, "-w only valid together with -a");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* First check if the address is valid and start the server. */
|
||||
addr = socket_parse(uri, &local_err);
|
||||
if (local_err != NULL) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
nbd_server_start(addr, NULL, NULL, &local_err);
|
||||
qapi_free_SocketAddress(addr);
|
||||
if (local_err != NULL) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!all) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Then try adding all block devices. If one fails, close all and
|
||||
* exit.
|
||||
*/
|
||||
block_list = qmp_query_block(NULL);
|
||||
|
||||
for (info = block_list; info; info = info->next) {
|
||||
if (!info->value->has_inserted) {
|
||||
continue;
|
||||
}
|
||||
|
||||
export = (BlockExportNbd) {
|
||||
.device = info->value->device,
|
||||
.has_writable = true,
|
||||
.writable = writable,
|
||||
};
|
||||
|
||||
qmp_nbd_server_add(&export, &local_err);
|
||||
|
||||
if (local_err != NULL) {
|
||||
qmp_nbd_server_stop(NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
qapi_free_BlockInfoList(block_list);
|
||||
|
||||
exit:
|
||||
hmp_handle_error(mon, local_err);
|
||||
}
|
||||
|
||||
void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *device = qdict_get_str(qdict, "device");
|
||||
const char *name = qdict_get_try_str(qdict, "name");
|
||||
bool writable = qdict_get_try_bool(qdict, "writable", false);
|
||||
Error *local_err = NULL;
|
||||
|
||||
BlockExportNbd export = {
|
||||
.device = (char *) device,
|
||||
.has_name = !!name,
|
||||
.name = (char *) name,
|
||||
.has_writable = true,
|
||||
.writable = writable,
|
||||
};
|
||||
|
||||
qmp_nbd_server_add(&export, &local_err);
|
||||
hmp_handle_error(mon, local_err);
|
||||
}
|
||||
|
||||
void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *name = qdict_get_str(qdict, "name");
|
||||
bool force = qdict_get_try_bool(qdict, "force", false);
|
||||
Error *err = NULL;
|
||||
|
||||
/* Rely on NBD_SERVER_REMOVE_MODE_SAFE being the default */
|
||||
qmp_nbd_server_remove(name, force, NBD_SERVER_REMOVE_MODE_HARD, &err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
Error *err = NULL;
|
||||
|
||||
qmp_nbd_server_stop(&err);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_chardev_add(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *args = qdict_get_str(qdict, "args");
|
||||
|
@ -2498,70 +1780,6 @@ void hmp_chardev_send_break(Monitor *mon, const QDict *qdict)
|
|||
hmp_handle_error(mon, local_err);
|
||||
}
|
||||
|
||||
void hmp_qemu_io(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
BlockBackend *blk;
|
||||
BlockBackend *local_blk = NULL;
|
||||
bool qdev = qdict_get_try_bool(qdict, "qdev", false);
|
||||
const char* device = qdict_get_str(qdict, "device");
|
||||
const char* command = qdict_get_str(qdict, "command");
|
||||
Error *err = NULL;
|
||||
int ret;
|
||||
|
||||
if (qdev) {
|
||||
blk = blk_by_qdev_id(device, &err);
|
||||
if (!blk) {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
blk = blk_by_name(device);
|
||||
if (!blk) {
|
||||
BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
|
||||
if (bs) {
|
||||
blk = local_blk = blk_new(bdrv_get_aio_context(bs),
|
||||
0, BLK_PERM_ALL);
|
||||
ret = blk_insert_bs(blk, bs, &err);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Notably absent: Proper permission management. This is sad, but it seems
|
||||
* almost impossible to achieve without changing the semantics and thereby
|
||||
* limiting the use cases of the qemu-io HMP command.
|
||||
*
|
||||
* In an ideal world we would unconditionally create a new BlockBackend for
|
||||
* qemuio_command(), but we have commands like 'reopen' and want them to
|
||||
* take effect on the exact BlockBackend whose name the user passed instead
|
||||
* of just on a temporary copy of it.
|
||||
*
|
||||
* Another problem is that deleting the temporary BlockBackend involves
|
||||
* draining all requests on it first, but some qemu-iotests cases want to
|
||||
* issue multiple aio_read/write requests and expect them to complete in
|
||||
* the background while the monitor has already returned.
|
||||
*
|
||||
* This is also what prevents us from saving the original permissions and
|
||||
* restoring them later: We can't revoke permissions until all requests
|
||||
* have completed, and we don't know when that is nor can we really let
|
||||
* anything else run before we have revoken them to avoid race conditions.
|
||||
*
|
||||
* What happens now is that command() in qemu-io-cmds.c can extend the
|
||||
* permissions if necessary for the qemu-io command. And they simply stay
|
||||
* extended, possibly resulting in a read-only guest device keeping write
|
||||
* permissions. Ugly, but it appears to be the lesser evil.
|
||||
*/
|
||||
qemuio_command(blk, command);
|
||||
|
||||
fail:
|
||||
blk_unref(local_blk);
|
||||
hmp_handle_error(mon, err);
|
||||
}
|
||||
|
||||
void hmp_object_del(Monitor *mon, const QDict *qdict)
|
||||
{
|
||||
const char *id = qdict_get_str(qdict, "id");
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include "qemu/option.h"
|
||||
#include "qemu/thread.h"
|
||||
#include "block/qapi.h"
|
||||
#include "block/block-hmp-cmds.h"
|
||||
#include "qapi/qapi-commands-char.h"
|
||||
#include "qapi/qapi-commands-control.h"
|
||||
#include "qapi/qapi-commands-migration.h"
|
||||
|
|
23
net/hub.c
23
net/hub.c
|
@ -193,29 +193,6 @@ NetClientState *net_hub_add_port(int hub_id, const char *name,
|
|||
return &port->nc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a specific client on a hub
|
||||
*/
|
||||
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name)
|
||||
{
|
||||
NetHub *hub;
|
||||
NetHubPort *port;
|
||||
NetClientState *peer;
|
||||
|
||||
QLIST_FOREACH(hub, &hubs, next) {
|
||||
if (hub->id == hub_id) {
|
||||
QLIST_FOREACH(port, &hub->ports, next) {
|
||||
peer = port->nc.peer;
|
||||
|
||||
if (peer && strcmp(peer->name, name) == 0) {
|
||||
return peer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a available port on a hub; otherwise create one new port
|
||||
*/
|
||||
|
|
|
@ -15,10 +15,8 @@
|
|||
#ifndef NET_HUB_H
|
||||
#define NET_HUB_H
|
||||
|
||||
|
||||
NetClientState *net_hub_add_port(int hub_id, const char *name,
|
||||
NetClientState *hubpeer);
|
||||
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
|
||||
void net_hub_info(Monitor *mon);
|
||||
void net_hub_check_clients(void);
|
||||
bool net_hub_flush(NetClientState *nc);
|
||||
|
|
40
net/slirp.c
40
net/slirp.c
|
@ -610,26 +610,14 @@ error:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static SlirpState *slirp_lookup(Monitor *mon, const char *hub_id,
|
||||
const char *name)
|
||||
static SlirpState *slirp_lookup(Monitor *mon, const char *id)
|
||||
{
|
||||
if (name) {
|
||||
NetClientState *nc;
|
||||
if (hub_id) {
|
||||
nc = net_hub_find_client_by_name(strtol(hub_id, NULL, 0), name);
|
||||
if (id) {
|
||||
NetClientState *nc = qemu_find_netdev(id);
|
||||
if (!nc) {
|
||||
monitor_printf(mon, "unrecognized (hub-id, stackname) pair\n");
|
||||
monitor_printf(mon, "unrecognized netdev id '%s'\n", id);
|
||||
return NULL;
|
||||
}
|
||||
warn_report("Using 'hub-id' is deprecated, specify the netdev id "
|
||||
"directly instead");
|
||||
} else {
|
||||
nc = qemu_find_netdev(name);
|
||||
if (!nc) {
|
||||
monitor_printf(mon, "unrecognized netdev id '%s'\n", name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (strcmp(nc->model, "user")) {
|
||||
monitor_printf(mon, "invalid device specified\n");
|
||||
return NULL;
|
||||
|
@ -655,16 +643,12 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
|
|||
int err;
|
||||
const char *arg1 = qdict_get_str(qdict, "arg1");
|
||||
const char *arg2 = qdict_get_try_str(qdict, "arg2");
|
||||
const char *arg3 = qdict_get_try_str(qdict, "arg3");
|
||||
|
||||
if (arg3) {
|
||||
s = slirp_lookup(mon, arg1, arg2);
|
||||
src_str = arg3;
|
||||
} else if (arg2) {
|
||||
s = slirp_lookup(mon, NULL, arg1);
|
||||
if (arg2) {
|
||||
s = slirp_lookup(mon, arg1);
|
||||
src_str = arg2;
|
||||
} else {
|
||||
s = slirp_lookup(mon, NULL, NULL);
|
||||
s = slirp_lookup(mon, NULL);
|
||||
src_str = arg1;
|
||||
}
|
||||
if (!s) {
|
||||
|
@ -784,16 +768,12 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
|
|||
SlirpState *s;
|
||||
const char *arg1 = qdict_get_str(qdict, "arg1");
|
||||
const char *arg2 = qdict_get_try_str(qdict, "arg2");
|
||||
const char *arg3 = qdict_get_try_str(qdict, "arg3");
|
||||
|
||||
if (arg3) {
|
||||
s = slirp_lookup(mon, arg1, arg2);
|
||||
redir_str = arg3;
|
||||
} else if (arg2) {
|
||||
s = slirp_lookup(mon, NULL, arg1);
|
||||
if (arg2) {
|
||||
s = slirp_lookup(mon, arg1);
|
||||
redir_str = arg2;
|
||||
} else {
|
||||
s = slirp_lookup(mon, NULL, NULL);
|
||||
s = slirp_lookup(mon, NULL);
|
||||
redir_str = arg1;
|
||||
}
|
||||
if (s) {
|
||||
|
|
Loading…
Reference in a new issue