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:
Peter Maydell 2020-03-09 19:49:53 +00:00
commit 7f368aed67
20 changed files with 1110 additions and 1104 deletions

View File

@ -1920,6 +1920,7 @@ Block QAPI, monitor, command line
M: Markus Armbruster <armbru@redhat.com> M: Markus Armbruster <armbru@redhat.com>
S: Supported S: Supported
F: blockdev.c F: blockdev.c
F: blockdev-hmp-cmds.c
F: block/qapi.c F: block/qapi.c
F: qapi/block*.json F: qapi/block*.json
F: qapi/transaction.json F: qapi/transaction.json

View File

@ -48,7 +48,7 @@ common-obj-y += dump/
common-obj-y += job-qmp.o common-obj-y += job-qmp.o
common-obj-y += monitor/ common-obj-y += monitor/
common-obj-y += net/ 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_WIN32) += os-win32.o
common-obj-$(CONFIG_POSIX) += os-posix.o common-obj-$(CONFIG_POSIX) += os-posix.o

View File

@ -45,6 +45,7 @@ block-obj-y += crypto.o
block-obj-y += aio_task.o block-obj-y += aio_task.o
block-obj-y += backup-top.o block-obj-y += backup-top.o
block-obj-y += filter-compress.o block-obj-y += filter-compress.o
common-obj-y += monitor/
block-obj-y += stream.o block-obj-y += stream.o

View File

@ -0,0 +1 @@
common-obj-y += block-hmp-cmds.o

File diff suppressed because it is too large Load Diff

View File

@ -64,9 +64,14 @@
#include "qemu/main-loop.h" #include "qemu/main-loop.h"
#include "qemu/throttle-options.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); 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] = { static const char *const if_name[IF_COUNT] = {
[IF_NONE] = "none", [IF_NONE] = "none",
[IF_IDE] = "ide", [IF_IDE] = "ide",
@ -640,7 +645,7 @@ err_no_opts:
} }
/* Takes the ownership of bs_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; int bdrv_flags = 0;
@ -1039,41 +1044,6 @@ static BlockDriverState *qmp_get_root_bs(const char *name, Error **errp)
return bs; 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) static void blockdev_do_action(TransactionAction *action, Error **errp)
{ {
TransactionActionList list; TransactionActionList list;
@ -2747,66 +2717,6 @@ BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node,
return ret; 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, void qmp_block_resize(bool has_device, const char *device,
bool has_node_name, const char *node_name, bool has_node_name, const char *node_name,
int64_t size, Error **errp) int64_t size, Error **errp)
@ -3814,37 +3724,6 @@ out:
aio_context_release(aio_context); 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) void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
{ {
BlockDriverState *bs; BlockDriverState *bs;
@ -3874,7 +3753,7 @@ void qmp_blockdev_add(BlockdevOptions *options, Error **errp)
goto fail; goto fail;
} }
QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list); bdrv_set_monitor_owned(bs);
fail: fail:
visit_free(v); visit_free(v);

View File

@ -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);
}
}

View File

@ -248,12 +248,6 @@ the 'wait' field, which is only applicable to sockets in server mode
Human Monitor Protocol (HMP) commands 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) ``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 The "autoload" parameter has been ignored since 2.12.0. All bitmaps
are automatically loaded from qcow2 images. 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 Related binaries
---------------- ----------------

View File

@ -1369,8 +1369,8 @@ ERST
#ifdef CONFIG_SLIRP #ifdef CONFIG_SLIRP
{ {
.name = "hostfwd_add", .name = "hostfwd_add",
.args_type = "arg1:s,arg2:s?,arg3:s?", .args_type = "arg1:s,arg2:s?",
.params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport", .params = "[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport",
.help = "redirect TCP or UDP connections from host to guest (requires -net user)", .help = "redirect TCP or UDP connections from host to guest (requires -net user)",
.cmd = hmp_hostfwd_add, .cmd = hmp_hostfwd_add,
}, },
@ -1383,8 +1383,8 @@ ERST
#ifdef CONFIG_SLIRP #ifdef CONFIG_SLIRP
{ {
.name = "hostfwd_remove", .name = "hostfwd_remove",
.args_type = "arg1:s,arg2:s?,arg3:s?", .args_type = "arg1:s,arg2:s?",
.params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport", .params = "[netdev_id] [tcp|udp]:[hostaddr]:hostport",
.help = "remove host-to-guest TCP or UDP redirection", .help = "remove host-to-guest TCP or UDP redirection",
.cmd = hmp_hostfwd_remove, .cmd = hmp_hostfwd_remove,
}, },

View File

@ -18,7 +18,6 @@
#include "hw/qdev-properties.h" #include "hw/qdev-properties.h"
#include "hw/scsi/scsi.h" #include "hw/scsi/scsi.h"
#include "migration/vmstate.h" #include "migration/vmstate.h"
#include "monitor/monitor.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/block-backend.h" #include "sysemu/block-backend.h"
#include "qapi/visitor.h" #include "qapi/visitor.h"

View 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

View File

@ -1216,8 +1216,6 @@ BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
BlockCompletionFunc *cb, void *opaque, BlockCompletionFunc *cb, void *opaque,
JobTxn *txn, Error **errp); JobTxn *txn, Error **errp);
void hmp_drive_add_node(Monitor *mon, const char *optstr);
BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs,
const char *child_name, const char *child_name,
const BdrvChildRole *child_role, 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); 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 */ #endif /* BLOCK_INT_H */

View File

@ -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_parameters(Monitor *mon, const QDict *qdict);
void hmp_info_migrate_cache_size(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_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_vnc(Monitor *mon, const QDict *qdict);
void hmp_info_spice(Monitor *mon, const QDict *qdict); void hmp_info_spice(Monitor *mon, const QDict *qdict);
void hmp_info_balloon(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_pic(Monitor *mon, const QDict *qdict);
void hmp_info_rdma(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_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_tpm(Monitor *mon, const QDict *qdict);
void hmp_info_iothreads(Monitor *mon, const QDict *qdict); void hmp_info_iothreads(Monitor *mon, const QDict *qdict);
void hmp_quit(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_system_wakeup(Monitor *mon, const QDict *qdict);
void hmp_nmi(Monitor *mon, const QDict *qdict); void hmp_nmi(Monitor *mon, const QDict *qdict);
void hmp_set_link(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_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_loadvm(Monitor *mon, const QDict *qdict);
void hmp_savevm(Monitor *mon, const QDict *qdict); void hmp_savevm(Monitor *mon, const QDict *qdict);
void hmp_delvm(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_cancel(Monitor *mon, const QDict *qdict);
void hmp_migrate_continue(Monitor *mon, const QDict *qdict); void hmp_migrate_continue(Monitor *mon, const QDict *qdict);
void hmp_migrate_incoming(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_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict);
void hmp_set_password(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_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_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_migrate(Monitor *mon, const QDict *qdict);
void hmp_device_add(Monitor *mon, const QDict *qdict); void hmp_device_add(Monitor *mon, const QDict *qdict);
void hmp_device_del(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_closefd(Monitor *mon, const QDict *qdict);
void hmp_sendkey(Monitor *mon, const QDict *qdict); void hmp_sendkey(Monitor *mon, const QDict *qdict);
void hmp_screendump(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_add(Monitor *mon, const QDict *qdict);
void hmp_chardev_change(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_remove(Monitor *mon, const QDict *qdict);
void hmp_chardev_send_break(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_cpu_add(Monitor *mon, const QDict *qdict);
void hmp_object_add(Monitor *mon, const QDict *qdict); void hmp_object_add(Monitor *mon, const QDict *qdict);
void hmp_object_del(Monitor *mon, const QDict *qdict); void hmp_object_del(Monitor *mon, const QDict *qdict);

View File

@ -57,8 +57,4 @@ QemuOpts *drive_add(BlockInterfaceType type, int index, const char *file,
DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type, DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type,
Error **errp); Error **errp);
/* device-hotplug */
void hmp_commit(Monitor *mon, const QDict *qdict);
void hmp_drive_del(Monitor *mon, const QDict *qdict);
#endif #endif

View File

@ -63,9 +63,6 @@ extern int nb_option_roms;
extern const char *prom_envs[MAX_PROM_ENVS]; extern const char *prom_envs[MAX_PROM_ENVS];
extern unsigned int nb_prom_envs; extern unsigned int nb_prom_envs;
/* generic hotplug */
void hmp_drive_add(Monitor *mon, const QDict *qdict);
/* pcie aer error injection */ /* pcie aer error injection */
void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict); void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict);

View File

@ -47,9 +47,6 @@
#include "qapi/string-output-visitor.h" #include "qapi/string-output-visitor.h"
#include "qom/object_interfaces.h" #include "qom/object_interfaces.h"
#include "ui/console.h" #include "ui/console.h"
#include "block/nbd.h"
#include "block/qapi.h"
#include "qemu-io.h"
#include "qemu/cutils.h" #include "qemu/cutils.h"
#include "qemu/error-report.h" #include "qemu/error-report.h"
#include "exec/ramlist.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); 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 #ifdef CONFIG_VNC
/* Helper for hmp_info_vnc_clients, _servers */ /* 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); 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) void hmp_info_tpm(Monitor *mon, const QDict *qdict)
{ {
TPMInfoList *info_list, *info; TPMInfoList *info_list, *info;
@ -1313,16 +1065,6 @@ void hmp_set_link(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, err); 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) void hmp_balloon(Monitor *mon, const QDict *qdict)
{ {
int64_t value = qdict_get_int(qdict, "value"); 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); 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) void hmp_loadvm(Monitor *mon, const QDict *qdict)
{ {
int saved_vm_running = runstate_is_running(); int saved_vm_running = runstate_is_running();
@ -1483,148 +1110,6 @@ void hmp_delvm(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, err); 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) void hmp_announce_self(Monitor *mon, const QDict *qdict)
{ {
const char *interfaces_str = qdict_get_try_str(qdict, "interfaces"); 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); 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 #ifdef CONFIG_VNC
static void hmp_change_read_arg(void *opaque, const char *password, 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); 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 typedef struct HMPMigrationStatus
{ {
QEMUTimer *timer; QEMUTimer *timer;
@ -2333,105 +1714,6 @@ void hmp_screendump(Monitor *mon, const QDict *qdict)
hmp_handle_error(mon, err); 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) void hmp_chardev_add(Monitor *mon, const QDict *qdict)
{ {
const char *args = qdict_get_str(qdict, "args"); 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); 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) void hmp_object_del(Monitor *mon, const QDict *qdict)
{ {
const char *id = qdict_get_str(qdict, "id"); const char *id = qdict_get_str(qdict, "id");

View File

@ -66,6 +66,7 @@
#include "qemu/option.h" #include "qemu/option.h"
#include "qemu/thread.h" #include "qemu/thread.h"
#include "block/qapi.h" #include "block/qapi.h"
#include "block/block-hmp-cmds.h"
#include "qapi/qapi-commands-char.h" #include "qapi/qapi-commands-char.h"
#include "qapi/qapi-commands-control.h" #include "qapi/qapi-commands-control.h"
#include "qapi/qapi-commands-migration.h" #include "qapi/qapi-commands-migration.h"

View File

@ -193,29 +193,6 @@ NetClientState *net_hub_add_port(int hub_id, const char *name,
return &port->nc; 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 * Find a available port on a hub; otherwise create one new port
*/ */

View File

@ -15,10 +15,8 @@
#ifndef NET_HUB_H #ifndef NET_HUB_H
#define NET_HUB_H #define NET_HUB_H
NetClientState *net_hub_add_port(int hub_id, const char *name, NetClientState *net_hub_add_port(int hub_id, const char *name,
NetClientState *hubpeer); NetClientState *hubpeer);
NetClientState *net_hub_find_client_by_name(int hub_id, const char *name);
void net_hub_info(Monitor *mon); void net_hub_info(Monitor *mon);
void net_hub_check_clients(void); void net_hub_check_clients(void);
bool net_hub_flush(NetClientState *nc); bool net_hub_flush(NetClientState *nc);

View File

@ -610,26 +610,14 @@ error:
return -1; return -1;
} }
static SlirpState *slirp_lookup(Monitor *mon, const char *hub_id, static SlirpState *slirp_lookup(Monitor *mon, const char *id)
const char *name)
{ {
if (name) { if (id) {
NetClientState *nc; NetClientState *nc = qemu_find_netdev(id);
if (hub_id) {
nc = net_hub_find_client_by_name(strtol(hub_id, NULL, 0), name);
if (!nc) { if (!nc) {
monitor_printf(mon, "unrecognized (hub-id, stackname) pair\n"); monitor_printf(mon, "unrecognized netdev id '%s'\n", id);
return NULL; 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")) { if (strcmp(nc->model, "user")) {
monitor_printf(mon, "invalid device specified\n"); monitor_printf(mon, "invalid device specified\n");
return NULL; return NULL;
@ -655,16 +643,12 @@ void hmp_hostfwd_remove(Monitor *mon, const QDict *qdict)
int err; int err;
const char *arg1 = qdict_get_str(qdict, "arg1"); const char *arg1 = qdict_get_str(qdict, "arg1");
const char *arg2 = qdict_get_try_str(qdict, "arg2"); const char *arg2 = qdict_get_try_str(qdict, "arg2");
const char *arg3 = qdict_get_try_str(qdict, "arg3");
if (arg3) { if (arg2) {
s = slirp_lookup(mon, arg1, arg2); s = slirp_lookup(mon, arg1);
src_str = arg3;
} else if (arg2) {
s = slirp_lookup(mon, NULL, arg1);
src_str = arg2; src_str = arg2;
} else { } else {
s = slirp_lookup(mon, NULL, NULL); s = slirp_lookup(mon, NULL);
src_str = arg1; src_str = arg1;
} }
if (!s) { if (!s) {
@ -784,16 +768,12 @@ void hmp_hostfwd_add(Monitor *mon, const QDict *qdict)
SlirpState *s; SlirpState *s;
const char *arg1 = qdict_get_str(qdict, "arg1"); const char *arg1 = qdict_get_str(qdict, "arg1");
const char *arg2 = qdict_get_try_str(qdict, "arg2"); const char *arg2 = qdict_get_try_str(qdict, "arg2");
const char *arg3 = qdict_get_try_str(qdict, "arg3");
if (arg3) { if (arg2) {
s = slirp_lookup(mon, arg1, arg2); s = slirp_lookup(mon, arg1);
redir_str = arg3;
} else if (arg2) {
s = slirp_lookup(mon, NULL, arg1);
redir_str = arg2; redir_str = arg2;
} else { } else {
s = slirp_lookup(mon, NULL, NULL); s = slirp_lookup(mon, NULL);
redir_str = arg1; redir_str = arg1;
} }
if (s) { if (s) {