qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

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>

+1110 -1104
+1
MAINTAINERS
··· 1920 1920 M: Markus Armbruster <armbru@redhat.com> 1921 1921 S: Supported 1922 1922 F: blockdev.c 1923 + F: blockdev-hmp-cmds.c 1923 1924 F: block/qapi.c 1924 1925 F: qapi/block*.json 1925 1926 F: qapi/transaction.json
+1 -1
Makefile.objs
··· 48 48 common-obj-y += job-qmp.o 49 49 common-obj-y += monitor/ 50 50 common-obj-y += net/ 51 - common-obj-y += qdev-monitor.o device-hotplug.o 51 + common-obj-y += qdev-monitor.o 52 52 common-obj-$(CONFIG_WIN32) += os-win32.o 53 53 common-obj-$(CONFIG_POSIX) += os-posix.o 54 54
+1
block/Makefile.objs
··· 45 45 block-obj-y += aio_task.o 46 46 block-obj-y += backup-top.o 47 47 block-obj-y += filter-compress.o 48 + common-obj-y += monitor/ 48 49 49 50 block-obj-y += stream.o 50 51
+1
block/monitor/Makefile.objs
··· 1 + common-obj-y += block-hmp-cmds.o
+1015
block/monitor/block-hmp-cmds.c
··· 1 + /* 2 + * Blockdev HMP commands 3 + * 4 + * Authors: 5 + * Anthony Liguori <aliguori@us.ibm.com> 6 + * 7 + * Copyright (c) 2003-2008 Fabrice Bellard 8 + * 9 + * This work is licensed under the terms of the GNU GPL, version 2. 10 + * See the COPYING file in the top-level directory. 11 + * Contributions after 2012-01-13 are licensed under the terms of the 12 + * GNU GPL, version 2 or (at your option) any later version. 13 + * 14 + * This file incorporates work covered by the following copyright and 15 + * permission notice: 16 + * 17 + * Copyright (c) 2003-2008 Fabrice Bellard 18 + * 19 + * Permission is hereby granted, free of charge, to any person obtaining a copy 20 + * of this software and associated documentation files (the "Software"), to deal 21 + * in the Software without restriction, including without limitation the rights 22 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 + * copies of the Software, and to permit persons to whom the Software is 24 + * furnished to do so, subject to the following conditions: 25 + * 26 + * The above copyright notice and this permission notice shall be included in 27 + * all copies or substantial portions of the Software. 28 + * 29 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 32 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 + * THE SOFTWARE. 36 + */ 37 + 38 + #include "qemu/osdep.h" 39 + #include "hw/boards.h" 40 + #include "sysemu/block-backend.h" 41 + #include "sysemu/blockdev.h" 42 + #include "qapi/qapi-commands-block.h" 43 + #include "qapi/qmp/qdict.h" 44 + #include "qapi/error.h" 45 + #include "qapi/qmp/qerror.h" 46 + #include "qemu/config-file.h" 47 + #include "qemu/option.h" 48 + #include "qemu/sockets.h" 49 + #include "qemu/cutils.h" 50 + #include "sysemu/sysemu.h" 51 + #include "monitor/monitor.h" 52 + #include "monitor/hmp.h" 53 + #include "block/nbd.h" 54 + #include "block/qapi.h" 55 + #include "block/block_int.h" 56 + #include "block/block-hmp-cmds.h" 57 + #include "qemu-io.h" 58 + 59 + static void hmp_drive_add_node(Monitor *mon, const char *optstr) 60 + { 61 + QemuOpts *opts; 62 + QDict *qdict; 63 + Error *local_err = NULL; 64 + 65 + opts = qemu_opts_parse_noisily(&qemu_drive_opts, optstr, false); 66 + if (!opts) { 67 + return; 68 + } 69 + 70 + qdict = qemu_opts_to_qdict(opts, NULL); 71 + 72 + if (!qdict_get_try_str(qdict, "node-name")) { 73 + qobject_unref(qdict); 74 + error_report("'node-name' needs to be specified"); 75 + goto out; 76 + } 77 + 78 + BlockDriverState *bs = bds_tree_init(qdict, &local_err); 79 + if (!bs) { 80 + error_report_err(local_err); 81 + goto out; 82 + } 83 + 84 + bdrv_set_monitor_owned(bs); 85 + out: 86 + qemu_opts_del(opts); 87 + } 88 + 89 + void hmp_drive_add(Monitor *mon, const QDict *qdict) 90 + { 91 + Error *err = NULL; 92 + DriveInfo *dinfo; 93 + QemuOpts *opts; 94 + MachineClass *mc; 95 + const char *optstr = qdict_get_str(qdict, "opts"); 96 + bool node = qdict_get_try_bool(qdict, "node", false); 97 + 98 + if (node) { 99 + hmp_drive_add_node(mon, optstr); 100 + return; 101 + } 102 + 103 + opts = drive_def(optstr); 104 + if (!opts) 105 + return; 106 + 107 + mc = MACHINE_GET_CLASS(current_machine); 108 + dinfo = drive_new(opts, mc->block_default_type, &err); 109 + if (err) { 110 + error_report_err(err); 111 + qemu_opts_del(opts); 112 + goto err; 113 + } 114 + 115 + if (!dinfo) { 116 + return; 117 + } 118 + 119 + switch (dinfo->type) { 120 + case IF_NONE: 121 + monitor_printf(mon, "OK\n"); 122 + break; 123 + default: 124 + monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type); 125 + goto err; 126 + } 127 + return; 128 + 129 + err: 130 + if (dinfo) { 131 + BlockBackend *blk = blk_by_legacy_dinfo(dinfo); 132 + monitor_remove_blk(blk); 133 + blk_unref(blk); 134 + } 135 + } 136 + 137 + void hmp_drive_del(Monitor *mon, const QDict *qdict) 138 + { 139 + const char *id = qdict_get_str(qdict, "id"); 140 + BlockBackend *blk; 141 + BlockDriverState *bs; 142 + AioContext *aio_context; 143 + Error *local_err = NULL; 144 + 145 + bs = bdrv_find_node(id); 146 + if (bs) { 147 + qmp_blockdev_del(id, &local_err); 148 + if (local_err) { 149 + error_report_err(local_err); 150 + } 151 + return; 152 + } 153 + 154 + blk = blk_by_name(id); 155 + if (!blk) { 156 + error_report("Device '%s' not found", id); 157 + return; 158 + } 159 + 160 + if (!blk_legacy_dinfo(blk)) { 161 + error_report("Deleting device added with blockdev-add" 162 + " is not supported"); 163 + return; 164 + } 165 + 166 + aio_context = blk_get_aio_context(blk); 167 + aio_context_acquire(aio_context); 168 + 169 + bs = blk_bs(blk); 170 + if (bs) { 171 + if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) { 172 + error_report_err(local_err); 173 + aio_context_release(aio_context); 174 + return; 175 + } 176 + 177 + blk_remove_bs(blk); 178 + } 179 + 180 + /* Make the BlockBackend and the attached BlockDriverState anonymous */ 181 + monitor_remove_blk(blk); 182 + 183 + /* 184 + * If this BlockBackend has a device attached to it, its refcount will be 185 + * decremented when the device is removed; otherwise we have to do so here. 186 + */ 187 + if (blk_get_attached_dev(blk)) { 188 + /* Further I/O must not pause the guest */ 189 + blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT, 190 + BLOCKDEV_ON_ERROR_REPORT); 191 + } else { 192 + blk_unref(blk); 193 + } 194 + 195 + aio_context_release(aio_context); 196 + } 197 + 198 + void hmp_commit(Monitor *mon, const QDict *qdict) 199 + { 200 + const char *device = qdict_get_str(qdict, "device"); 201 + BlockBackend *blk; 202 + int ret; 203 + 204 + if (!strcmp(device, "all")) { 205 + ret = blk_commit_all(); 206 + } else { 207 + BlockDriverState *bs; 208 + AioContext *aio_context; 209 + 210 + blk = blk_by_name(device); 211 + if (!blk) { 212 + error_report("Device '%s' not found", device); 213 + return; 214 + } 215 + if (!blk_is_available(blk)) { 216 + error_report("Device '%s' has no medium", device); 217 + return; 218 + } 219 + 220 + bs = blk_bs(blk); 221 + aio_context = bdrv_get_aio_context(bs); 222 + aio_context_acquire(aio_context); 223 + 224 + ret = bdrv_commit(bs); 225 + 226 + aio_context_release(aio_context); 227 + } 228 + if (ret < 0) { 229 + error_report("'commit' error for '%s': %s", device, strerror(-ret)); 230 + } 231 + } 232 + 233 + void hmp_drive_mirror(Monitor *mon, const QDict *qdict) 234 + { 235 + const char *filename = qdict_get_str(qdict, "target"); 236 + const char *format = qdict_get_try_str(qdict, "format"); 237 + bool reuse = qdict_get_try_bool(qdict, "reuse", false); 238 + bool full = qdict_get_try_bool(qdict, "full", false); 239 + Error *err = NULL; 240 + DriveMirror mirror = { 241 + .device = (char *)qdict_get_str(qdict, "device"), 242 + .target = (char *)filename, 243 + .has_format = !!format, 244 + .format = (char *)format, 245 + .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP, 246 + .has_mode = true, 247 + .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS, 248 + .unmap = true, 249 + }; 250 + 251 + if (!filename) { 252 + error_setg(&err, QERR_MISSING_PARAMETER, "target"); 253 + hmp_handle_error(mon, err); 254 + return; 255 + } 256 + qmp_drive_mirror(&mirror, &err); 257 + hmp_handle_error(mon, err); 258 + } 259 + 260 + void hmp_drive_backup(Monitor *mon, const QDict *qdict) 261 + { 262 + const char *device = qdict_get_str(qdict, "device"); 263 + const char *filename = qdict_get_str(qdict, "target"); 264 + const char *format = qdict_get_try_str(qdict, "format"); 265 + bool reuse = qdict_get_try_bool(qdict, "reuse", false); 266 + bool full = qdict_get_try_bool(qdict, "full", false); 267 + bool compress = qdict_get_try_bool(qdict, "compress", false); 268 + Error *err = NULL; 269 + DriveBackup backup = { 270 + .device = (char *)device, 271 + .target = (char *)filename, 272 + .has_format = !!format, 273 + .format = (char *)format, 274 + .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP, 275 + .has_mode = true, 276 + .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS, 277 + .has_compress = !!compress, 278 + .compress = compress, 279 + }; 280 + 281 + if (!filename) { 282 + error_setg(&err, QERR_MISSING_PARAMETER, "target"); 283 + hmp_handle_error(mon, err); 284 + return; 285 + } 286 + 287 + qmp_drive_backup(&backup, &err); 288 + hmp_handle_error(mon, err); 289 + } 290 + 291 + void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict) 292 + { 293 + Error *error = NULL; 294 + const char *device = qdict_get_str(qdict, "device"); 295 + int64_t value = qdict_get_int(qdict, "speed"); 296 + 297 + qmp_block_job_set_speed(device, value, &error); 298 + 299 + hmp_handle_error(mon, error); 300 + } 301 + 302 + void hmp_block_job_cancel(Monitor *mon, const QDict *qdict) 303 + { 304 + Error *error = NULL; 305 + const char *device = qdict_get_str(qdict, "device"); 306 + bool force = qdict_get_try_bool(qdict, "force", false); 307 + 308 + qmp_block_job_cancel(device, true, force, &error); 309 + 310 + hmp_handle_error(mon, error); 311 + } 312 + 313 + void hmp_block_job_pause(Monitor *mon, const QDict *qdict) 314 + { 315 + Error *error = NULL; 316 + const char *device = qdict_get_str(qdict, "device"); 317 + 318 + qmp_block_job_pause(device, &error); 319 + 320 + hmp_handle_error(mon, error); 321 + } 322 + 323 + void hmp_block_job_resume(Monitor *mon, const QDict *qdict) 324 + { 325 + Error *error = NULL; 326 + const char *device = qdict_get_str(qdict, "device"); 327 + 328 + qmp_block_job_resume(device, &error); 329 + 330 + hmp_handle_error(mon, error); 331 + } 332 + 333 + void hmp_block_job_complete(Monitor *mon, const QDict *qdict) 334 + { 335 + Error *error = NULL; 336 + const char *device = qdict_get_str(qdict, "device"); 337 + 338 + qmp_block_job_complete(device, &error); 339 + 340 + hmp_handle_error(mon, error); 341 + } 342 + 343 + void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict) 344 + { 345 + const char *device = qdict_get_str(qdict, "device"); 346 + const char *filename = qdict_get_try_str(qdict, "snapshot-file"); 347 + const char *format = qdict_get_try_str(qdict, "format"); 348 + bool reuse = qdict_get_try_bool(qdict, "reuse", false); 349 + enum NewImageMode mode; 350 + Error *err = NULL; 351 + 352 + if (!filename) { 353 + /* 354 + * In the future, if 'snapshot-file' is not specified, the snapshot 355 + * will be taken internally. Today it's actually required. 356 + */ 357 + error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file"); 358 + hmp_handle_error(mon, err); 359 + return; 360 + } 361 + 362 + mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS; 363 + qmp_blockdev_snapshot_sync(true, device, false, NULL, 364 + filename, false, NULL, 365 + !!format, format, 366 + true, mode, &err); 367 + hmp_handle_error(mon, err); 368 + } 369 + 370 + void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict) 371 + { 372 + const char *device = qdict_get_str(qdict, "device"); 373 + const char *name = qdict_get_str(qdict, "name"); 374 + Error *err = NULL; 375 + 376 + qmp_blockdev_snapshot_internal_sync(device, name, &err); 377 + hmp_handle_error(mon, err); 378 + } 379 + 380 + void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict) 381 + { 382 + const char *device = qdict_get_str(qdict, "device"); 383 + const char *name = qdict_get_str(qdict, "name"); 384 + const char *id = qdict_get_try_str(qdict, "id"); 385 + Error *err = NULL; 386 + 387 + qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id, 388 + true, name, &err); 389 + hmp_handle_error(mon, err); 390 + } 391 + 392 + void hmp_nbd_server_start(Monitor *mon, const QDict *qdict) 393 + { 394 + const char *uri = qdict_get_str(qdict, "uri"); 395 + bool writable = qdict_get_try_bool(qdict, "writable", false); 396 + bool all = qdict_get_try_bool(qdict, "all", false); 397 + Error *local_err = NULL; 398 + BlockInfoList *block_list, *info; 399 + SocketAddress *addr; 400 + BlockExportNbd export; 401 + 402 + if (writable && !all) { 403 + error_setg(&local_err, "-w only valid together with -a"); 404 + goto exit; 405 + } 406 + 407 + /* First check if the address is valid and start the server. */ 408 + addr = socket_parse(uri, &local_err); 409 + if (local_err != NULL) { 410 + goto exit; 411 + } 412 + 413 + nbd_server_start(addr, NULL, NULL, &local_err); 414 + qapi_free_SocketAddress(addr); 415 + if (local_err != NULL) { 416 + goto exit; 417 + } 418 + 419 + if (!all) { 420 + return; 421 + } 422 + 423 + /* Then try adding all block devices. If one fails, close all and 424 + * exit. 425 + */ 426 + block_list = qmp_query_block(NULL); 427 + 428 + for (info = block_list; info; info = info->next) { 429 + if (!info->value->has_inserted) { 430 + continue; 431 + } 432 + 433 + export = (BlockExportNbd) { 434 + .device = info->value->device, 435 + .has_writable = true, 436 + .writable = writable, 437 + }; 438 + 439 + qmp_nbd_server_add(&export, &local_err); 440 + 441 + if (local_err != NULL) { 442 + qmp_nbd_server_stop(NULL); 443 + break; 444 + } 445 + } 446 + 447 + qapi_free_BlockInfoList(block_list); 448 + 449 + exit: 450 + hmp_handle_error(mon, local_err); 451 + } 452 + 453 + void hmp_nbd_server_add(Monitor *mon, const QDict *qdict) 454 + { 455 + const char *device = qdict_get_str(qdict, "device"); 456 + const char *name = qdict_get_try_str(qdict, "name"); 457 + bool writable = qdict_get_try_bool(qdict, "writable", false); 458 + Error *local_err = NULL; 459 + 460 + BlockExportNbd export = { 461 + .device = (char *) device, 462 + .has_name = !!name, 463 + .name = (char *) name, 464 + .has_writable = true, 465 + .writable = writable, 466 + }; 467 + 468 + qmp_nbd_server_add(&export, &local_err); 469 + hmp_handle_error(mon, local_err); 470 + } 471 + 472 + void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict) 473 + { 474 + const char *name = qdict_get_str(qdict, "name"); 475 + bool force = qdict_get_try_bool(qdict, "force", false); 476 + Error *err = NULL; 477 + 478 + /* Rely on NBD_SERVER_REMOVE_MODE_SAFE being the default */ 479 + qmp_nbd_server_remove(name, force, NBD_SERVER_REMOVE_MODE_HARD, &err); 480 + hmp_handle_error(mon, err); 481 + } 482 + 483 + void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict) 484 + { 485 + Error *err = NULL; 486 + 487 + qmp_nbd_server_stop(&err); 488 + hmp_handle_error(mon, err); 489 + } 490 + 491 + void hmp_block_resize(Monitor *mon, const QDict *qdict) 492 + { 493 + const char *device = qdict_get_str(qdict, "device"); 494 + int64_t size = qdict_get_int(qdict, "size"); 495 + Error *err = NULL; 496 + 497 + qmp_block_resize(true, device, false, NULL, size, &err); 498 + hmp_handle_error(mon, err); 499 + } 500 + 501 + void hmp_block_stream(Monitor *mon, const QDict *qdict) 502 + { 503 + Error *error = NULL; 504 + const char *device = qdict_get_str(qdict, "device"); 505 + const char *base = qdict_get_try_str(qdict, "base"); 506 + int64_t speed = qdict_get_try_int(qdict, "speed", 0); 507 + 508 + qmp_block_stream(true, device, device, base != NULL, base, false, NULL, 509 + false, NULL, qdict_haskey(qdict, "speed"), speed, true, 510 + BLOCKDEV_ON_ERROR_REPORT, false, false, false, false, 511 + &error); 512 + 513 + hmp_handle_error(mon, error); 514 + } 515 + 516 + void hmp_block_passwd(Monitor *mon, const QDict *qdict) 517 + { 518 + const char *device = qdict_get_str(qdict, "device"); 519 + const char *password = qdict_get_str(qdict, "password"); 520 + Error *err = NULL; 521 + 522 + qmp_block_passwd(true, device, false, NULL, password, &err); 523 + hmp_handle_error(mon, err); 524 + } 525 + 526 + void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict) 527 + { 528 + Error *err = NULL; 529 + char *device = (char *) qdict_get_str(qdict, "device"); 530 + BlockIOThrottle throttle = { 531 + .bps = qdict_get_int(qdict, "bps"), 532 + .bps_rd = qdict_get_int(qdict, "bps_rd"), 533 + .bps_wr = qdict_get_int(qdict, "bps_wr"), 534 + .iops = qdict_get_int(qdict, "iops"), 535 + .iops_rd = qdict_get_int(qdict, "iops_rd"), 536 + .iops_wr = qdict_get_int(qdict, "iops_wr"), 537 + }; 538 + 539 + /* 540 + * qmp_block_set_io_throttle has separate parameters for the 541 + * (deprecated) block device name and the qdev ID but the HMP 542 + * version has only one, so we must decide which one to pass. 543 + */ 544 + if (blk_by_name(device)) { 545 + throttle.has_device = true; 546 + throttle.device = device; 547 + } else { 548 + throttle.has_id = true; 549 + throttle.id = device; 550 + } 551 + 552 + qmp_block_set_io_throttle(&throttle, &err); 553 + hmp_handle_error(mon, err); 554 + } 555 + 556 + void hmp_eject(Monitor *mon, const QDict *qdict) 557 + { 558 + bool force = qdict_get_try_bool(qdict, "force", false); 559 + const char *device = qdict_get_str(qdict, "device"); 560 + Error *err = NULL; 561 + 562 + qmp_eject(true, device, false, NULL, true, force, &err); 563 + hmp_handle_error(mon, err); 564 + } 565 + 566 + void hmp_qemu_io(Monitor *mon, const QDict *qdict) 567 + { 568 + BlockBackend *blk; 569 + BlockBackend *local_blk = NULL; 570 + bool qdev = qdict_get_try_bool(qdict, "qdev", false); 571 + const char *device = qdict_get_str(qdict, "device"); 572 + const char *command = qdict_get_str(qdict, "command"); 573 + Error *err = NULL; 574 + int ret; 575 + 576 + if (qdev) { 577 + blk = blk_by_qdev_id(device, &err); 578 + if (!blk) { 579 + goto fail; 580 + } 581 + } else { 582 + blk = blk_by_name(device); 583 + if (!blk) { 584 + BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err); 585 + if (bs) { 586 + blk = local_blk = blk_new(bdrv_get_aio_context(bs), 587 + 0, BLK_PERM_ALL); 588 + ret = blk_insert_bs(blk, bs, &err); 589 + if (ret < 0) { 590 + goto fail; 591 + } 592 + } else { 593 + goto fail; 594 + } 595 + } 596 + } 597 + 598 + /* 599 + * Notably absent: Proper permission management. This is sad, but it seems 600 + * almost impossible to achieve without changing the semantics and thereby 601 + * limiting the use cases of the qemu-io HMP command. 602 + * 603 + * In an ideal world we would unconditionally create a new BlockBackend for 604 + * qemuio_command(), but we have commands like 'reopen' and want them to 605 + * take effect on the exact BlockBackend whose name the user passed instead 606 + * of just on a temporary copy of it. 607 + * 608 + * Another problem is that deleting the temporary BlockBackend involves 609 + * draining all requests on it first, but some qemu-iotests cases want to 610 + * issue multiple aio_read/write requests and expect them to complete in 611 + * the background while the monitor has already returned. 612 + * 613 + * This is also what prevents us from saving the original permissions and 614 + * restoring them later: We can't revoke permissions until all requests 615 + * have completed, and we don't know when that is nor can we really let 616 + * anything else run before we have revoken them to avoid race conditions. 617 + * 618 + * What happens now is that command() in qemu-io-cmds.c can extend the 619 + * permissions if necessary for the qemu-io command. And they simply stay 620 + * extended, possibly resulting in a read-only guest device keeping write 621 + * permissions. Ugly, but it appears to be the lesser evil. 622 + */ 623 + qemuio_command(blk, command); 624 + 625 + fail: 626 + blk_unref(local_blk); 627 + hmp_handle_error(mon, err); 628 + } 629 + 630 + static void print_block_info(Monitor *mon, BlockInfo *info, 631 + BlockDeviceInfo *inserted, bool verbose) 632 + { 633 + ImageInfo *image_info; 634 + 635 + assert(!info || !info->has_inserted || info->inserted == inserted); 636 + 637 + if (info && *info->device) { 638 + monitor_printf(mon, "%s", info->device); 639 + if (inserted && inserted->has_node_name) { 640 + monitor_printf(mon, " (%s)", inserted->node_name); 641 + } 642 + } else { 643 + assert(info || inserted); 644 + monitor_printf(mon, "%s", 645 + inserted && inserted->has_node_name ? inserted->node_name 646 + : info && info->has_qdev ? info->qdev 647 + : "<anonymous>"); 648 + } 649 + 650 + if (inserted) { 651 + monitor_printf(mon, ": %s (%s%s%s)\n", 652 + inserted->file, 653 + inserted->drv, 654 + inserted->ro ? ", read-only" : "", 655 + inserted->encrypted ? ", encrypted" : ""); 656 + } else { 657 + monitor_printf(mon, ": [not inserted]\n"); 658 + } 659 + 660 + if (info) { 661 + if (info->has_qdev) { 662 + monitor_printf(mon, " Attached to: %s\n", info->qdev); 663 + } 664 + if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) { 665 + monitor_printf(mon, " I/O status: %s\n", 666 + BlockDeviceIoStatus_str(info->io_status)); 667 + } 668 + 669 + if (info->removable) { 670 + monitor_printf(mon, " Removable device: %slocked, tray %s\n", 671 + info->locked ? "" : "not ", 672 + info->tray_open ? "open" : "closed"); 673 + } 674 + } 675 + 676 + 677 + if (!inserted) { 678 + return; 679 + } 680 + 681 + monitor_printf(mon, " Cache mode: %s%s%s\n", 682 + inserted->cache->writeback ? "writeback" : "writethrough", 683 + inserted->cache->direct ? ", direct" : "", 684 + inserted->cache->no_flush ? ", ignore flushes" : ""); 685 + 686 + if (inserted->has_backing_file) { 687 + monitor_printf(mon, 688 + " Backing file: %s " 689 + "(chain depth: %" PRId64 ")\n", 690 + inserted->backing_file, 691 + inserted->backing_file_depth); 692 + } 693 + 694 + if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) { 695 + monitor_printf(mon, " Detect zeroes: %s\n", 696 + BlockdevDetectZeroesOptions_str(inserted->detect_zeroes)); 697 + } 698 + 699 + if (inserted->bps || inserted->bps_rd || inserted->bps_wr || 700 + inserted->iops || inserted->iops_rd || inserted->iops_wr) 701 + { 702 + monitor_printf(mon, " I/O throttling: bps=%" PRId64 703 + " bps_rd=%" PRId64 " bps_wr=%" PRId64 704 + " bps_max=%" PRId64 705 + " bps_rd_max=%" PRId64 706 + " bps_wr_max=%" PRId64 707 + " iops=%" PRId64 " iops_rd=%" PRId64 708 + " iops_wr=%" PRId64 709 + " iops_max=%" PRId64 710 + " iops_rd_max=%" PRId64 711 + " iops_wr_max=%" PRId64 712 + " iops_size=%" PRId64 713 + " group=%s\n", 714 + inserted->bps, 715 + inserted->bps_rd, 716 + inserted->bps_wr, 717 + inserted->bps_max, 718 + inserted->bps_rd_max, 719 + inserted->bps_wr_max, 720 + inserted->iops, 721 + inserted->iops_rd, 722 + inserted->iops_wr, 723 + inserted->iops_max, 724 + inserted->iops_rd_max, 725 + inserted->iops_wr_max, 726 + inserted->iops_size, 727 + inserted->group); 728 + } 729 + 730 + if (verbose) { 731 + monitor_printf(mon, "\nImages:\n"); 732 + image_info = inserted->image; 733 + while (1) { 734 + bdrv_image_info_dump(image_info); 735 + if (image_info->has_backing_image) { 736 + image_info = image_info->backing_image; 737 + } else { 738 + break; 739 + } 740 + } 741 + } 742 + } 743 + 744 + void hmp_info_block(Monitor *mon, const QDict *qdict) 745 + { 746 + BlockInfoList *block_list, *info; 747 + BlockDeviceInfoList *blockdev_list, *blockdev; 748 + const char *device = qdict_get_try_str(qdict, "device"); 749 + bool verbose = qdict_get_try_bool(qdict, "verbose", false); 750 + bool nodes = qdict_get_try_bool(qdict, "nodes", false); 751 + bool printed = false; 752 + 753 + /* Print BlockBackend information */ 754 + if (!nodes) { 755 + block_list = qmp_query_block(NULL); 756 + } else { 757 + block_list = NULL; 758 + } 759 + 760 + for (info = block_list; info; info = info->next) { 761 + if (device && strcmp(device, info->value->device)) { 762 + continue; 763 + } 764 + 765 + if (info != block_list) { 766 + monitor_printf(mon, "\n"); 767 + } 768 + 769 + print_block_info(mon, info->value, info->value->has_inserted 770 + ? info->value->inserted : NULL, 771 + verbose); 772 + printed = true; 773 + } 774 + 775 + qapi_free_BlockInfoList(block_list); 776 + 777 + if ((!device && !nodes) || printed) { 778 + return; 779 + } 780 + 781 + /* Print node information */ 782 + blockdev_list = qmp_query_named_block_nodes(false, false, NULL); 783 + for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) { 784 + assert(blockdev->value->has_node_name); 785 + if (device && strcmp(device, blockdev->value->node_name)) { 786 + continue; 787 + } 788 + 789 + if (blockdev != blockdev_list) { 790 + monitor_printf(mon, "\n"); 791 + } 792 + 793 + print_block_info(mon, NULL, blockdev->value, verbose); 794 + } 795 + qapi_free_BlockDeviceInfoList(blockdev_list); 796 + } 797 + 798 + void hmp_info_blockstats(Monitor *mon, const QDict *qdict) 799 + { 800 + BlockStatsList *stats_list, *stats; 801 + 802 + stats_list = qmp_query_blockstats(false, false, NULL); 803 + 804 + for (stats = stats_list; stats; stats = stats->next) { 805 + if (!stats->value->has_device) { 806 + continue; 807 + } 808 + 809 + monitor_printf(mon, "%s:", stats->value->device); 810 + monitor_printf(mon, " rd_bytes=%" PRId64 811 + " wr_bytes=%" PRId64 812 + " rd_operations=%" PRId64 813 + " wr_operations=%" PRId64 814 + " flush_operations=%" PRId64 815 + " wr_total_time_ns=%" PRId64 816 + " rd_total_time_ns=%" PRId64 817 + " flush_total_time_ns=%" PRId64 818 + " rd_merged=%" PRId64 819 + " wr_merged=%" PRId64 820 + " idle_time_ns=%" PRId64 821 + "\n", 822 + stats->value->stats->rd_bytes, 823 + stats->value->stats->wr_bytes, 824 + stats->value->stats->rd_operations, 825 + stats->value->stats->wr_operations, 826 + stats->value->stats->flush_operations, 827 + stats->value->stats->wr_total_time_ns, 828 + stats->value->stats->rd_total_time_ns, 829 + stats->value->stats->flush_total_time_ns, 830 + stats->value->stats->rd_merged, 831 + stats->value->stats->wr_merged, 832 + stats->value->stats->idle_time_ns); 833 + } 834 + 835 + qapi_free_BlockStatsList(stats_list); 836 + } 837 + 838 + void hmp_info_block_jobs(Monitor *mon, const QDict *qdict) 839 + { 840 + BlockJobInfoList *list; 841 + Error *err = NULL; 842 + 843 + list = qmp_query_block_jobs(&err); 844 + assert(!err); 845 + 846 + if (!list) { 847 + monitor_printf(mon, "No active jobs\n"); 848 + return; 849 + } 850 + 851 + while (list) { 852 + if (strcmp(list->value->type, "stream") == 0) { 853 + monitor_printf(mon, "Streaming device %s: Completed %" PRId64 854 + " of %" PRId64 " bytes, speed limit %" PRId64 855 + " bytes/s\n", 856 + list->value->device, 857 + list->value->offset, 858 + list->value->len, 859 + list->value->speed); 860 + } else { 861 + monitor_printf(mon, "Type %s, device %s: Completed %" PRId64 862 + " of %" PRId64 " bytes, speed limit %" PRId64 863 + " bytes/s\n", 864 + list->value->type, 865 + list->value->device, 866 + list->value->offset, 867 + list->value->len, 868 + list->value->speed); 869 + } 870 + list = list->next; 871 + } 872 + 873 + qapi_free_BlockJobInfoList(list); 874 + } 875 + 876 + void hmp_info_snapshots(Monitor *mon, const QDict *qdict) 877 + { 878 + BlockDriverState *bs, *bs1; 879 + BdrvNextIterator it1; 880 + QEMUSnapshotInfo *sn_tab, *sn; 881 + bool no_snapshot = true; 882 + int nb_sns, i; 883 + int total; 884 + int *global_snapshots; 885 + AioContext *aio_context; 886 + 887 + typedef struct SnapshotEntry { 888 + QEMUSnapshotInfo sn; 889 + QTAILQ_ENTRY(SnapshotEntry) next; 890 + } SnapshotEntry; 891 + 892 + typedef struct ImageEntry { 893 + const char *imagename; 894 + QTAILQ_ENTRY(ImageEntry) next; 895 + QTAILQ_HEAD(, SnapshotEntry) snapshots; 896 + } ImageEntry; 897 + 898 + QTAILQ_HEAD(, ImageEntry) image_list = 899 + QTAILQ_HEAD_INITIALIZER(image_list); 900 + 901 + ImageEntry *image_entry, *next_ie; 902 + SnapshotEntry *snapshot_entry; 903 + 904 + bs = bdrv_all_find_vmstate_bs(); 905 + if (!bs) { 906 + monitor_printf(mon, "No available block device supports snapshots\n"); 907 + return; 908 + } 909 + aio_context = bdrv_get_aio_context(bs); 910 + 911 + aio_context_acquire(aio_context); 912 + nb_sns = bdrv_snapshot_list(bs, &sn_tab); 913 + aio_context_release(aio_context); 914 + 915 + if (nb_sns < 0) { 916 + monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns); 917 + return; 918 + } 919 + 920 + for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) { 921 + int bs1_nb_sns = 0; 922 + ImageEntry *ie; 923 + SnapshotEntry *se; 924 + AioContext *ctx = bdrv_get_aio_context(bs1); 925 + 926 + aio_context_acquire(ctx); 927 + if (bdrv_can_snapshot(bs1)) { 928 + sn = NULL; 929 + bs1_nb_sns = bdrv_snapshot_list(bs1, &sn); 930 + if (bs1_nb_sns > 0) { 931 + no_snapshot = false; 932 + ie = g_new0(ImageEntry, 1); 933 + ie->imagename = bdrv_get_device_name(bs1); 934 + QTAILQ_INIT(&ie->snapshots); 935 + QTAILQ_INSERT_TAIL(&image_list, ie, next); 936 + for (i = 0; i < bs1_nb_sns; i++) { 937 + se = g_new0(SnapshotEntry, 1); 938 + se->sn = sn[i]; 939 + QTAILQ_INSERT_TAIL(&ie->snapshots, se, next); 940 + } 941 + } 942 + g_free(sn); 943 + } 944 + aio_context_release(ctx); 945 + } 946 + 947 + if (no_snapshot) { 948 + monitor_printf(mon, "There is no snapshot available.\n"); 949 + return; 950 + } 951 + 952 + global_snapshots = g_new0(int, nb_sns); 953 + total = 0; 954 + for (i = 0; i < nb_sns; i++) { 955 + SnapshotEntry *next_sn; 956 + if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) { 957 + global_snapshots[total] = i; 958 + total++; 959 + QTAILQ_FOREACH(image_entry, &image_list, next) { 960 + QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, 961 + next, next_sn) { 962 + if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) { 963 + QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry, 964 + next); 965 + g_free(snapshot_entry); 966 + } 967 + } 968 + } 969 + } 970 + } 971 + monitor_printf(mon, "List of snapshots present on all disks:\n"); 972 + 973 + if (total > 0) { 974 + bdrv_snapshot_dump(NULL); 975 + monitor_printf(mon, "\n"); 976 + for (i = 0; i < total; i++) { 977 + sn = &sn_tab[global_snapshots[i]]; 978 + /* 979 + * The ID is not guaranteed to be the same on all images, so 980 + * overwrite it. 981 + */ 982 + pstrcpy(sn->id_str, sizeof(sn->id_str), "--"); 983 + bdrv_snapshot_dump(sn); 984 + monitor_printf(mon, "\n"); 985 + } 986 + } else { 987 + monitor_printf(mon, "None\n"); 988 + } 989 + 990 + QTAILQ_FOREACH(image_entry, &image_list, next) { 991 + if (QTAILQ_EMPTY(&image_entry->snapshots)) { 992 + continue; 993 + } 994 + monitor_printf(mon, 995 + "\nList of partial (non-loadable) snapshots on '%s':\n", 996 + image_entry->imagename); 997 + bdrv_snapshot_dump(NULL); 998 + monitor_printf(mon, "\n"); 999 + QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) { 1000 + bdrv_snapshot_dump(&snapshot_entry->sn); 1001 + monitor_printf(mon, "\n"); 1002 + } 1003 + } 1004 + 1005 + QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) { 1006 + SnapshotEntry *next_sn; 1007 + QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next, 1008 + next_sn) { 1009 + g_free(snapshot_entry); 1010 + } 1011 + g_free(image_entry); 1012 + } 1013 + g_free(sn_tab); 1014 + g_free(global_snapshots); 1015 + }
+8 -129
blockdev.c
··· 64 64 #include "qemu/main-loop.h" 65 65 #include "qemu/throttle-options.h" 66 66 67 - static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states = 67 + QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states = 68 68 QTAILQ_HEAD_INITIALIZER(monitor_bdrv_states); 69 + 70 + void bdrv_set_monitor_owned(BlockDriverState *bs) 71 + { 72 + QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list); 73 + } 69 74 70 75 static const char *const if_name[IF_COUNT] = { 71 76 [IF_NONE] = "none", ··· 640 645 } 641 646 642 647 /* Takes the ownership of bs_opts */ 643 - static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp) 648 + BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp) 644 649 { 645 650 int bdrv_flags = 0; 646 651 ··· 1037 1042 } 1038 1043 1039 1044 return bs; 1040 - } 1041 - 1042 - void hmp_commit(Monitor *mon, const QDict *qdict) 1043 - { 1044 - const char *device = qdict_get_str(qdict, "device"); 1045 - BlockBackend *blk; 1046 - int ret; 1047 - 1048 - if (!strcmp(device, "all")) { 1049 - ret = blk_commit_all(); 1050 - } else { 1051 - BlockDriverState *bs; 1052 - AioContext *aio_context; 1053 - 1054 - blk = blk_by_name(device); 1055 - if (!blk) { 1056 - error_report("Device '%s' not found", device); 1057 - return; 1058 - } 1059 - if (!blk_is_available(blk)) { 1060 - error_report("Device '%s' has no medium", device); 1061 - return; 1062 - } 1063 - 1064 - bs = blk_bs(blk); 1065 - aio_context = bdrv_get_aio_context(bs); 1066 - aio_context_acquire(aio_context); 1067 - 1068 - ret = bdrv_commit(bs); 1069 - 1070 - aio_context_release(aio_context); 1071 - } 1072 - if (ret < 0) { 1073 - error_report("'commit' error for '%s': %s", device, strerror(-ret)); 1074 - } 1075 1045 } 1076 1046 1077 1047 static void blockdev_do_action(TransactionAction *action, Error **errp) ··· 2747 2717 return ret; 2748 2718 } 2749 2719 2750 - void hmp_drive_del(Monitor *mon, const QDict *qdict) 2751 - { 2752 - const char *id = qdict_get_str(qdict, "id"); 2753 - BlockBackend *blk; 2754 - BlockDriverState *bs; 2755 - AioContext *aio_context; 2756 - Error *local_err = NULL; 2757 - 2758 - bs = bdrv_find_node(id); 2759 - if (bs) { 2760 - qmp_blockdev_del(id, &local_err); 2761 - if (local_err) { 2762 - error_report_err(local_err); 2763 - } 2764 - return; 2765 - } 2766 - 2767 - blk = blk_by_name(id); 2768 - if (!blk) { 2769 - error_report("Device '%s' not found", id); 2770 - return; 2771 - } 2772 - 2773 - if (!blk_legacy_dinfo(blk)) { 2774 - error_report("Deleting device added with blockdev-add" 2775 - " is not supported"); 2776 - return; 2777 - } 2778 - 2779 - aio_context = blk_get_aio_context(blk); 2780 - aio_context_acquire(aio_context); 2781 - 2782 - bs = blk_bs(blk); 2783 - if (bs) { 2784 - if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) { 2785 - error_report_err(local_err); 2786 - aio_context_release(aio_context); 2787 - return; 2788 - } 2789 - 2790 - blk_remove_bs(blk); 2791 - } 2792 - 2793 - /* Make the BlockBackend and the attached BlockDriverState anonymous */ 2794 - monitor_remove_blk(blk); 2795 - 2796 - /* If this BlockBackend has a device attached to it, its refcount will be 2797 - * decremented when the device is removed; otherwise we have to do so here. 2798 - */ 2799 - if (blk_get_attached_dev(blk)) { 2800 - /* Further I/O must not pause the guest */ 2801 - blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT, 2802 - BLOCKDEV_ON_ERROR_REPORT); 2803 - } else { 2804 - blk_unref(blk); 2805 - } 2806 - 2807 - aio_context_release(aio_context); 2808 - } 2809 - 2810 2720 void qmp_block_resize(bool has_device, const char *device, 2811 2721 bool has_node_name, const char *node_name, 2812 2722 int64_t size, Error **errp) ··· 3814 3724 aio_context_release(aio_context); 3815 3725 } 3816 3726 3817 - void hmp_drive_add_node(Monitor *mon, const char *optstr) 3818 - { 3819 - QemuOpts *opts; 3820 - QDict *qdict; 3821 - Error *local_err = NULL; 3822 - 3823 - opts = qemu_opts_parse_noisily(&qemu_drive_opts, optstr, false); 3824 - if (!opts) { 3825 - return; 3826 - } 3827 - 3828 - qdict = qemu_opts_to_qdict(opts, NULL); 3829 - 3830 - if (!qdict_get_try_str(qdict, "node-name")) { 3831 - qobject_unref(qdict); 3832 - error_report("'node-name' needs to be specified"); 3833 - goto out; 3834 - } 3835 - 3836 - BlockDriverState *bs = bds_tree_init(qdict, &local_err); 3837 - if (!bs) { 3838 - error_report_err(local_err); 3839 - goto out; 3840 - } 3841 - 3842 - QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list); 3843 - 3844 - out: 3845 - qemu_opts_del(opts); 3846 - } 3847 - 3848 3727 void qmp_blockdev_add(BlockdevOptions *options, Error **errp) 3849 3728 { 3850 3729 BlockDriverState *bs; ··· 3874 3753 goto fail; 3875 3754 } 3876 3755 3877 - QTAILQ_INSERT_TAIL(&monitor_bdrv_states, bs, monitor_list); 3756 + bdrv_set_monitor_owned(bs); 3878 3757 3879 3758 fail: 3880 3759 visit_free(v);
-91
device-hotplug.c
··· 1 - /* 2 - * QEMU device hotplug helpers 3 - * 4 - * Copyright (c) 2004 Fabrice Bellard 5 - * 6 - * Permission is hereby granted, free of charge, to any person obtaining a copy 7 - * of this software and associated documentation files (the "Software"), to deal 8 - * in the Software without restriction, including without limitation the rights 9 - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 - * copies of the Software, and to permit persons to whom the Software is 11 - * furnished to do so, subject to the following conditions: 12 - * 13 - * The above copyright notice and this permission notice shall be included in 14 - * all copies or substantial portions of the Software. 15 - * 16 - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 - * THE SOFTWARE. 23 - */ 24 - 25 - #include "qemu/osdep.h" 26 - #include "hw/boards.h" 27 - #include "sysemu/block-backend.h" 28 - #include "sysemu/blockdev.h" 29 - #include "qapi/qmp/qdict.h" 30 - #include "qapi/error.h" 31 - #include "qemu/config-file.h" 32 - #include "qemu/option.h" 33 - #include "sysemu/sysemu.h" 34 - #include "monitor/monitor.h" 35 - #include "block/block_int.h" 36 - 37 - static DriveInfo *add_init_drive(const char *optstr) 38 - { 39 - Error *err = NULL; 40 - DriveInfo *dinfo; 41 - QemuOpts *opts; 42 - MachineClass *mc; 43 - 44 - opts = drive_def(optstr); 45 - if (!opts) 46 - return NULL; 47 - 48 - mc = MACHINE_GET_CLASS(current_machine); 49 - dinfo = drive_new(opts, mc->block_default_type, &err); 50 - if (err) { 51 - error_report_err(err); 52 - qemu_opts_del(opts); 53 - return NULL; 54 - } 55 - 56 - return dinfo; 57 - } 58 - 59 - void hmp_drive_add(Monitor *mon, const QDict *qdict) 60 - { 61 - DriveInfo *dinfo = NULL; 62 - const char *opts = qdict_get_str(qdict, "opts"); 63 - bool node = qdict_get_try_bool(qdict, "node", false); 64 - 65 - if (node) { 66 - hmp_drive_add_node(mon, opts); 67 - return; 68 - } 69 - 70 - dinfo = add_init_drive(opts); 71 - if (!dinfo) { 72 - goto err; 73 - } 74 - 75 - switch (dinfo->type) { 76 - case IF_NONE: 77 - monitor_printf(mon, "OK\n"); 78 - break; 79 - default: 80 - monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type); 81 - goto err; 82 - } 83 - return; 84 - 85 - err: 86 - if (dinfo) { 87 - BlockBackend *blk = blk_by_legacy_dinfo(dinfo); 88 - monitor_remove_blk(blk); 89 - blk_unref(blk); 90 - } 91 - }
+9 -6
docs/system/deprecated.rst
··· 248 248 Human Monitor Protocol (HMP) commands 249 249 ------------------------------------- 250 250 251 - The ``hub_id`` parameter of ``hostfwd_add`` / ``hostfwd_remove`` (since 3.1) 252 - '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 253 - 254 - The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and 255 - 'hostfwd_remove' HMP commands has been replaced by ``netdev_id``. 256 - 257 251 ``cpu-add`` (since 4.0) 258 252 ''''''''''''''''''''''' 259 253 ··· 429 423 430 424 The "autoload" parameter has been ignored since 2.12.0. All bitmaps 431 425 are automatically loaded from qcow2 images. 426 + 427 + Human Monitor Protocol (HMP) commands 428 + ------------------------------------- 429 + 430 + The ``hub_id`` parameter of ``hostfwd_add`` / ``hostfwd_remove`` (removed in 5.0) 431 + ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' 432 + 433 + The ``[hub_id name]`` parameter tuple of the 'hostfwd_add' and 434 + 'hostfwd_remove' HMP commands has been replaced by ``netdev_id``. 432 435 433 436 Related binaries 434 437 ----------------
+4 -4
hmp-commands.hx
··· 1369 1369 #ifdef CONFIG_SLIRP 1370 1370 { 1371 1371 .name = "hostfwd_add", 1372 - .args_type = "arg1:s,arg2:s?,arg3:s?", 1373 - .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport", 1372 + .args_type = "arg1:s,arg2:s?", 1373 + .params = "[netdev_id] [tcp|udp]:[hostaddr]:hostport-[guestaddr]:guestport", 1374 1374 .help = "redirect TCP or UDP connections from host to guest (requires -net user)", 1375 1375 .cmd = hmp_hostfwd_add, 1376 1376 }, ··· 1383 1383 #ifdef CONFIG_SLIRP 1384 1384 { 1385 1385 .name = "hostfwd_remove", 1386 - .args_type = "arg1:s,arg2:s?,arg3:s?", 1387 - .params = "[hub_id name]|[netdev_id] [tcp|udp]:[hostaddr]:hostport", 1386 + .args_type = "arg1:s,arg2:s?", 1387 + .params = "[netdev_id] [tcp|udp]:[hostaddr]:hostport", 1388 1388 .help = "remove host-to-guest TCP or UDP redirection", 1389 1389 .cmd = hmp_hostfwd_remove, 1390 1390 },
-1
hw/usb/dev-storage.c
··· 18 18 #include "hw/qdev-properties.h" 19 19 #include "hw/scsi/scsi.h" 20 20 #include "migration/vmstate.h" 21 - #include "monitor/monitor.h" 22 21 #include "sysemu/sysemu.h" 23 22 #include "sysemu/block-backend.h" 24 23 #include "qapi/visitor.h"
+54
include/block/block-hmp-cmds.h
··· 1 + /* 2 + * HMP commands related to the block layer 3 + * 4 + * Copyright (c) 2003-2008 Fabrice Bellard 5 + * Copyright (c) 2020 Red Hat, Inc. 6 + * Copyright IBM, Corp. 2011 7 + * 8 + * Authors: 9 + * Anthony Liguori <aliguori@us.ibm.com> 10 + * 11 + * This work is licensed under the terms of the GNU GPL, version 2. See 12 + * the COPYING file in the top-level directory. 13 + */ 14 + 15 + #ifndef BLOCK_HMP_COMMANDS_H 16 + #define BLOCK_HMP_COMMANDS_H 17 + 18 + void hmp_drive_add(Monitor *mon, const QDict *qdict); 19 + 20 + void hmp_commit(Monitor *mon, const QDict *qdict); 21 + void hmp_drive_del(Monitor *mon, const QDict *qdict); 22 + 23 + void hmp_drive_mirror(Monitor *mon, const QDict *qdict); 24 + void hmp_drive_backup(Monitor *mon, const QDict *qdict); 25 + 26 + void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict); 27 + void hmp_block_job_cancel(Monitor *mon, const QDict *qdict); 28 + void hmp_block_job_pause(Monitor *mon, const QDict *qdict); 29 + void hmp_block_job_resume(Monitor *mon, const QDict *qdict); 30 + void hmp_block_job_complete(Monitor *mon, const QDict *qdict); 31 + 32 + void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict); 33 + void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict); 34 + void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict); 35 + 36 + void hmp_nbd_server_start(Monitor *mon, const QDict *qdict); 37 + void hmp_nbd_server_add(Monitor *mon, const QDict *qdict); 38 + void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict); 39 + void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict); 40 + 41 + void hmp_block_resize(Monitor *mon, const QDict *qdict); 42 + void hmp_block_stream(Monitor *mon, const QDict *qdict); 43 + void hmp_block_passwd(Monitor *mon, const QDict *qdict); 44 + void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict); 45 + void hmp_eject(Monitor *mon, const QDict *qdict); 46 + 47 + void hmp_qemu_io(Monitor *mon, const QDict *qdict); 48 + 49 + void hmp_info_block(Monitor *mon, const QDict *qdict); 50 + void hmp_info_blockstats(Monitor *mon, const QDict *qdict); 51 + void hmp_info_block_jobs(Monitor *mon, const QDict *qdict); 52 + void hmp_info_snapshots(Monitor *mon, const QDict *qdict); 53 + 54 + #endif
+3 -2
include/block/block_int.h
··· 1216 1216 BlockCompletionFunc *cb, void *opaque, 1217 1217 JobTxn *txn, Error **errp); 1218 1218 1219 - void hmp_drive_add_node(Monitor *mon, const char *optstr); 1220 - 1221 1219 BdrvChild *bdrv_root_attach_child(BlockDriverState *child_bs, 1222 1220 const char *child_name, 1223 1221 const BdrvChildRole *child_role, ··· 1321 1319 BdrvRequestFlags write_flags); 1322 1320 1323 1321 int refresh_total_sectors(BlockDriverState *bs, int64_t hint); 1322 + 1323 + void bdrv_set_monitor_owned(BlockDriverState *bs); 1324 + BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp); 1324 1325 1325 1326 #endif /* BLOCK_INT_H */
-24
include/monitor/hmp.h
··· 30 30 void hmp_info_migrate_parameters(Monitor *mon, const QDict *qdict); 31 31 void hmp_info_migrate_cache_size(Monitor *mon, const QDict *qdict); 32 32 void hmp_info_cpus(Monitor *mon, const QDict *qdict); 33 - void hmp_info_block(Monitor *mon, const QDict *qdict); 34 - void hmp_info_blockstats(Monitor *mon, const QDict *qdict); 35 33 void hmp_info_vnc(Monitor *mon, const QDict *qdict); 36 34 void hmp_info_spice(Monitor *mon, const QDict *qdict); 37 35 void hmp_info_balloon(Monitor *mon, const QDict *qdict); ··· 39 37 void hmp_info_pic(Monitor *mon, const QDict *qdict); 40 38 void hmp_info_rdma(Monitor *mon, const QDict *qdict); 41 39 void hmp_info_pci(Monitor *mon, const QDict *qdict); 42 - void hmp_info_block_jobs(Monitor *mon, const QDict *qdict); 43 40 void hmp_info_tpm(Monitor *mon, const QDict *qdict); 44 41 void hmp_info_iothreads(Monitor *mon, const QDict *qdict); 45 42 void hmp_quit(Monitor *mon, const QDict *qdict); ··· 58 55 void hmp_system_wakeup(Monitor *mon, const QDict *qdict); 59 56 void hmp_nmi(Monitor *mon, const QDict *qdict); 60 57 void hmp_set_link(Monitor *mon, const QDict *qdict); 61 - void hmp_block_passwd(Monitor *mon, const QDict *qdict); 62 58 void hmp_balloon(Monitor *mon, const QDict *qdict); 63 - void hmp_block_resize(Monitor *mon, const QDict *qdict); 64 - void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict); 65 - void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict); 66 - void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict); 67 - void hmp_drive_mirror(Monitor *mon, const QDict *qdict); 68 - void hmp_drive_backup(Monitor *mon, const QDict *qdict); 69 59 void hmp_loadvm(Monitor *mon, const QDict *qdict); 70 60 void hmp_savevm(Monitor *mon, const QDict *qdict); 71 61 void hmp_delvm(Monitor *mon, const QDict *qdict); 72 - void hmp_info_snapshots(Monitor *mon, const QDict *qdict); 73 62 void hmp_migrate_cancel(Monitor *mon, const QDict *qdict); 74 63 void hmp_migrate_continue(Monitor *mon, const QDict *qdict); 75 64 void hmp_migrate_incoming(Monitor *mon, const QDict *qdict); ··· 85 74 void hmp_x_colo_lost_heartbeat(Monitor *mon, const QDict *qdict); 86 75 void hmp_set_password(Monitor *mon, const QDict *qdict); 87 76 void hmp_expire_password(Monitor *mon, const QDict *qdict); 88 - void hmp_eject(Monitor *mon, const QDict *qdict); 89 77 void hmp_change(Monitor *mon, const QDict *qdict); 90 - void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict); 91 - void hmp_block_stream(Monitor *mon, const QDict *qdict); 92 - void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict); 93 - void hmp_block_job_cancel(Monitor *mon, const QDict *qdict); 94 - void hmp_block_job_pause(Monitor *mon, const QDict *qdict); 95 - void hmp_block_job_resume(Monitor *mon, const QDict *qdict); 96 - void hmp_block_job_complete(Monitor *mon, const QDict *qdict); 97 78 void hmp_migrate(Monitor *mon, const QDict *qdict); 98 79 void hmp_device_add(Monitor *mon, const QDict *qdict); 99 80 void hmp_device_del(Monitor *mon, const QDict *qdict); ··· 104 85 void hmp_closefd(Monitor *mon, const QDict *qdict); 105 86 void hmp_sendkey(Monitor *mon, const QDict *qdict); 106 87 void hmp_screendump(Monitor *mon, const QDict *qdict); 107 - void hmp_nbd_server_start(Monitor *mon, const QDict *qdict); 108 - void hmp_nbd_server_add(Monitor *mon, const QDict *qdict); 109 - void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict); 110 - void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict); 111 88 void hmp_chardev_add(Monitor *mon, const QDict *qdict); 112 89 void hmp_chardev_change(Monitor *mon, const QDict *qdict); 113 90 void hmp_chardev_remove(Monitor *mon, const QDict *qdict); 114 91 void hmp_chardev_send_break(Monitor *mon, const QDict *qdict); 115 - void hmp_qemu_io(Monitor *mon, const QDict *qdict); 116 92 void hmp_cpu_add(Monitor *mon, const QDict *qdict); 117 93 void hmp_object_add(Monitor *mon, const QDict *qdict); 118 94 void hmp_object_del(Monitor *mon, const QDict *qdict);
-4
include/sysemu/blockdev.h
··· 57 57 DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType block_default_type, 58 58 Error **errp); 59 59 60 - /* device-hotplug */ 61 - 62 - void hmp_commit(Monitor *mon, const QDict *qdict); 63 - void hmp_drive_del(Monitor *mon, const QDict *qdict); 64 60 #endif
-3
include/sysemu/sysemu.h
··· 63 63 extern const char *prom_envs[MAX_PROM_ENVS]; 64 64 extern unsigned int nb_prom_envs; 65 65 66 - /* generic hotplug */ 67 - void hmp_drive_add(Monitor *mon, const QDict *qdict); 68 - 69 66 /* pcie aer error injection */ 70 67 void hmp_pcie_aer_inject_error(Monitor *mon, const QDict *qdict); 71 68
-782
monitor/hmp-cmds.c
··· 47 47 #include "qapi/string-output-visitor.h" 48 48 #include "qom/object_interfaces.h" 49 49 #include "ui/console.h" 50 - #include "block/nbd.h" 51 - #include "block/qapi.h" 52 - #include "qemu-io.h" 53 50 #include "qemu/cutils.h" 54 51 #include "qemu/error-report.h" 55 52 #include "exec/ramlist.h" ··· 472 469 qmp_query_migrate_cache_size(NULL) >> 10); 473 470 } 474 471 475 - static void print_block_info(Monitor *mon, BlockInfo *info, 476 - BlockDeviceInfo *inserted, bool verbose) 477 - { 478 - ImageInfo *image_info; 479 - 480 - assert(!info || !info->has_inserted || info->inserted == inserted); 481 - 482 - if (info && *info->device) { 483 - monitor_printf(mon, "%s", info->device); 484 - if (inserted && inserted->has_node_name) { 485 - monitor_printf(mon, " (%s)", inserted->node_name); 486 - } 487 - } else { 488 - assert(info || inserted); 489 - monitor_printf(mon, "%s", 490 - inserted && inserted->has_node_name ? inserted->node_name 491 - : info && info->has_qdev ? info->qdev 492 - : "<anonymous>"); 493 - } 494 - 495 - if (inserted) { 496 - monitor_printf(mon, ": %s (%s%s%s)\n", 497 - inserted->file, 498 - inserted->drv, 499 - inserted->ro ? ", read-only" : "", 500 - inserted->encrypted ? ", encrypted" : ""); 501 - } else { 502 - monitor_printf(mon, ": [not inserted]\n"); 503 - } 504 - 505 - if (info) { 506 - if (info->has_qdev) { 507 - monitor_printf(mon, " Attached to: %s\n", info->qdev); 508 - } 509 - if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) { 510 - monitor_printf(mon, " I/O status: %s\n", 511 - BlockDeviceIoStatus_str(info->io_status)); 512 - } 513 - 514 - if (info->removable) { 515 - monitor_printf(mon, " Removable device: %slocked, tray %s\n", 516 - info->locked ? "" : "not ", 517 - info->tray_open ? "open" : "closed"); 518 - } 519 - } 520 - 521 - 522 - if (!inserted) { 523 - return; 524 - } 525 - 526 - monitor_printf(mon, " Cache mode: %s%s%s\n", 527 - inserted->cache->writeback ? "writeback" : "writethrough", 528 - inserted->cache->direct ? ", direct" : "", 529 - inserted->cache->no_flush ? ", ignore flushes" : ""); 530 - 531 - if (inserted->has_backing_file) { 532 - monitor_printf(mon, 533 - " Backing file: %s " 534 - "(chain depth: %" PRId64 ")\n", 535 - inserted->backing_file, 536 - inserted->backing_file_depth); 537 - } 538 - 539 - if (inserted->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF) { 540 - monitor_printf(mon, " Detect zeroes: %s\n", 541 - BlockdevDetectZeroesOptions_str(inserted->detect_zeroes)); 542 - } 543 - 544 - if (inserted->bps || inserted->bps_rd || inserted->bps_wr || 545 - inserted->iops || inserted->iops_rd || inserted->iops_wr) 546 - { 547 - monitor_printf(mon, " I/O throttling: bps=%" PRId64 548 - " bps_rd=%" PRId64 " bps_wr=%" PRId64 549 - " bps_max=%" PRId64 550 - " bps_rd_max=%" PRId64 551 - " bps_wr_max=%" PRId64 552 - " iops=%" PRId64 " iops_rd=%" PRId64 553 - " iops_wr=%" PRId64 554 - " iops_max=%" PRId64 555 - " iops_rd_max=%" PRId64 556 - " iops_wr_max=%" PRId64 557 - " iops_size=%" PRId64 558 - " group=%s\n", 559 - inserted->bps, 560 - inserted->bps_rd, 561 - inserted->bps_wr, 562 - inserted->bps_max, 563 - inserted->bps_rd_max, 564 - inserted->bps_wr_max, 565 - inserted->iops, 566 - inserted->iops_rd, 567 - inserted->iops_wr, 568 - inserted->iops_max, 569 - inserted->iops_rd_max, 570 - inserted->iops_wr_max, 571 - inserted->iops_size, 572 - inserted->group); 573 - } 574 - 575 - if (verbose) { 576 - monitor_printf(mon, "\nImages:\n"); 577 - image_info = inserted->image; 578 - while (1) { 579 - bdrv_image_info_dump(image_info); 580 - if (image_info->has_backing_image) { 581 - image_info = image_info->backing_image; 582 - } else { 583 - break; 584 - } 585 - } 586 - } 587 - } 588 - 589 - void hmp_info_block(Monitor *mon, const QDict *qdict) 590 - { 591 - BlockInfoList *block_list, *info; 592 - BlockDeviceInfoList *blockdev_list, *blockdev; 593 - const char *device = qdict_get_try_str(qdict, "device"); 594 - bool verbose = qdict_get_try_bool(qdict, "verbose", false); 595 - bool nodes = qdict_get_try_bool(qdict, "nodes", false); 596 - bool printed = false; 597 - 598 - /* Print BlockBackend information */ 599 - if (!nodes) { 600 - block_list = qmp_query_block(NULL); 601 - } else { 602 - block_list = NULL; 603 - } 604 - 605 - for (info = block_list; info; info = info->next) { 606 - if (device && strcmp(device, info->value->device)) { 607 - continue; 608 - } 609 - 610 - if (info != block_list) { 611 - monitor_printf(mon, "\n"); 612 - } 613 - 614 - print_block_info(mon, info->value, info->value->has_inserted 615 - ? info->value->inserted : NULL, 616 - verbose); 617 - printed = true; 618 - } 619 - 620 - qapi_free_BlockInfoList(block_list); 621 - 622 - if ((!device && !nodes) || printed) { 623 - return; 624 - } 625 - 626 - /* Print node information */ 627 - blockdev_list = qmp_query_named_block_nodes(false, false, NULL); 628 - for (blockdev = blockdev_list; blockdev; blockdev = blockdev->next) { 629 - assert(blockdev->value->has_node_name); 630 - if (device && strcmp(device, blockdev->value->node_name)) { 631 - continue; 632 - } 633 - 634 - if (blockdev != blockdev_list) { 635 - monitor_printf(mon, "\n"); 636 - } 637 - 638 - print_block_info(mon, NULL, blockdev->value, verbose); 639 - } 640 - qapi_free_BlockDeviceInfoList(blockdev_list); 641 - } 642 - 643 - void hmp_info_blockstats(Monitor *mon, const QDict *qdict) 644 - { 645 - BlockStatsList *stats_list, *stats; 646 - 647 - stats_list = qmp_query_blockstats(false, false, NULL); 648 - 649 - for (stats = stats_list; stats; stats = stats->next) { 650 - if (!stats->value->has_device) { 651 - continue; 652 - } 653 - 654 - monitor_printf(mon, "%s:", stats->value->device); 655 - monitor_printf(mon, " rd_bytes=%" PRId64 656 - " wr_bytes=%" PRId64 657 - " rd_operations=%" PRId64 658 - " wr_operations=%" PRId64 659 - " flush_operations=%" PRId64 660 - " wr_total_time_ns=%" PRId64 661 - " rd_total_time_ns=%" PRId64 662 - " flush_total_time_ns=%" PRId64 663 - " rd_merged=%" PRId64 664 - " wr_merged=%" PRId64 665 - " idle_time_ns=%" PRId64 666 - "\n", 667 - stats->value->stats->rd_bytes, 668 - stats->value->stats->wr_bytes, 669 - stats->value->stats->rd_operations, 670 - stats->value->stats->wr_operations, 671 - stats->value->stats->flush_operations, 672 - stats->value->stats->wr_total_time_ns, 673 - stats->value->stats->rd_total_time_ns, 674 - stats->value->stats->flush_total_time_ns, 675 - stats->value->stats->rd_merged, 676 - stats->value->stats->wr_merged, 677 - stats->value->stats->idle_time_ns); 678 - } 679 - 680 - qapi_free_BlockStatsList(stats_list); 681 - } 682 472 683 473 #ifdef CONFIG_VNC 684 474 /* Helper for hmp_info_vnc_clients, _servers */ ··· 1058 848 qapi_free_PciInfoList(info_list); 1059 849 } 1060 850 1061 - void hmp_info_block_jobs(Monitor *mon, const QDict *qdict) 1062 - { 1063 - BlockJobInfoList *list; 1064 - Error *err = NULL; 1065 - 1066 - list = qmp_query_block_jobs(&err); 1067 - assert(!err); 1068 - 1069 - if (!list) { 1070 - monitor_printf(mon, "No active jobs\n"); 1071 - return; 1072 - } 1073 - 1074 - while (list) { 1075 - if (strcmp(list->value->type, "stream") == 0) { 1076 - monitor_printf(mon, "Streaming device %s: Completed %" PRId64 1077 - " of %" PRId64 " bytes, speed limit %" PRId64 1078 - " bytes/s\n", 1079 - list->value->device, 1080 - list->value->offset, 1081 - list->value->len, 1082 - list->value->speed); 1083 - } else { 1084 - monitor_printf(mon, "Type %s, device %s: Completed %" PRId64 1085 - " of %" PRId64 " bytes, speed limit %" PRId64 1086 - " bytes/s\n", 1087 - list->value->type, 1088 - list->value->device, 1089 - list->value->offset, 1090 - list->value->len, 1091 - list->value->speed); 1092 - } 1093 - list = list->next; 1094 - } 1095 - 1096 - qapi_free_BlockJobInfoList(list); 1097 - } 1098 - 1099 851 void hmp_info_tpm(Monitor *mon, const QDict *qdict) 1100 852 { 1101 853 TPMInfoList *info_list, *info; ··· 1313 1065 hmp_handle_error(mon, err); 1314 1066 } 1315 1067 1316 - void hmp_block_passwd(Monitor *mon, const QDict *qdict) 1317 - { 1318 - const char *device = qdict_get_str(qdict, "device"); 1319 - const char *password = qdict_get_str(qdict, "password"); 1320 - Error *err = NULL; 1321 - 1322 - qmp_block_passwd(true, device, false, NULL, password, &err); 1323 - hmp_handle_error(mon, err); 1324 - } 1325 - 1326 1068 void hmp_balloon(Monitor *mon, const QDict *qdict) 1327 1069 { 1328 1070 int64_t value = qdict_get_int(qdict, "value"); ··· 1332 1074 hmp_handle_error(mon, err); 1333 1075 } 1334 1076 1335 - void hmp_block_resize(Monitor *mon, const QDict *qdict) 1336 - { 1337 - const char *device = qdict_get_str(qdict, "device"); 1338 - int64_t size = qdict_get_int(qdict, "size"); 1339 - Error *err = NULL; 1340 - 1341 - qmp_block_resize(true, device, false, NULL, size, &err); 1342 - hmp_handle_error(mon, err); 1343 - } 1344 - 1345 - void hmp_drive_mirror(Monitor *mon, const QDict *qdict) 1346 - { 1347 - const char *filename = qdict_get_str(qdict, "target"); 1348 - const char *format = qdict_get_try_str(qdict, "format"); 1349 - bool reuse = qdict_get_try_bool(qdict, "reuse", false); 1350 - bool full = qdict_get_try_bool(qdict, "full", false); 1351 - Error *err = NULL; 1352 - DriveMirror mirror = { 1353 - .device = (char *)qdict_get_str(qdict, "device"), 1354 - .target = (char *)filename, 1355 - .has_format = !!format, 1356 - .format = (char *)format, 1357 - .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP, 1358 - .has_mode = true, 1359 - .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS, 1360 - .unmap = true, 1361 - }; 1362 - 1363 - if (!filename) { 1364 - error_setg(&err, QERR_MISSING_PARAMETER, "target"); 1365 - hmp_handle_error(mon, err); 1366 - return; 1367 - } 1368 - qmp_drive_mirror(&mirror, &err); 1369 - hmp_handle_error(mon, err); 1370 - } 1371 - 1372 - void hmp_drive_backup(Monitor *mon, const QDict *qdict) 1373 - { 1374 - const char *device = qdict_get_str(qdict, "device"); 1375 - const char *filename = qdict_get_str(qdict, "target"); 1376 - const char *format = qdict_get_try_str(qdict, "format"); 1377 - bool reuse = qdict_get_try_bool(qdict, "reuse", false); 1378 - bool full = qdict_get_try_bool(qdict, "full", false); 1379 - bool compress = qdict_get_try_bool(qdict, "compress", false); 1380 - Error *err = NULL; 1381 - DriveBackup backup = { 1382 - .device = (char *)device, 1383 - .target = (char *)filename, 1384 - .has_format = !!format, 1385 - .format = (char *)format, 1386 - .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP, 1387 - .has_mode = true, 1388 - .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS, 1389 - .has_compress = !!compress, 1390 - .compress = compress, 1391 - }; 1392 - 1393 - if (!filename) { 1394 - error_setg(&err, QERR_MISSING_PARAMETER, "target"); 1395 - hmp_handle_error(mon, err); 1396 - return; 1397 - } 1398 - 1399 - qmp_drive_backup(&backup, &err); 1400 - hmp_handle_error(mon, err); 1401 - } 1402 - 1403 - void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict) 1404 - { 1405 - const char *device = qdict_get_str(qdict, "device"); 1406 - const char *filename = qdict_get_try_str(qdict, "snapshot-file"); 1407 - const char *format = qdict_get_try_str(qdict, "format"); 1408 - bool reuse = qdict_get_try_bool(qdict, "reuse", false); 1409 - enum NewImageMode mode; 1410 - Error *err = NULL; 1411 - 1412 - if (!filename) { 1413 - /* In the future, if 'snapshot-file' is not specified, the snapshot 1414 - will be taken internally. Today it's actually required. */ 1415 - error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file"); 1416 - hmp_handle_error(mon, err); 1417 - return; 1418 - } 1419 - 1420 - mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS; 1421 - qmp_blockdev_snapshot_sync(true, device, false, NULL, 1422 - filename, false, NULL, 1423 - !!format, format, 1424 - true, mode, &err); 1425 - hmp_handle_error(mon, err); 1426 - } 1427 - 1428 - void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict) 1429 - { 1430 - const char *device = qdict_get_str(qdict, "device"); 1431 - const char *name = qdict_get_str(qdict, "name"); 1432 - Error *err = NULL; 1433 - 1434 - qmp_blockdev_snapshot_internal_sync(device, name, &err); 1435 - hmp_handle_error(mon, err); 1436 - } 1437 - 1438 - void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict) 1439 - { 1440 - const char *device = qdict_get_str(qdict, "device"); 1441 - const char *name = qdict_get_str(qdict, "name"); 1442 - const char *id = qdict_get_try_str(qdict, "id"); 1443 - Error *err = NULL; 1444 - 1445 - qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id, 1446 - true, name, &err); 1447 - hmp_handle_error(mon, err); 1448 - } 1449 - 1450 1077 void hmp_loadvm(Monitor *mon, const QDict *qdict) 1451 1078 { 1452 1079 int saved_vm_running = runstate_is_running(); ··· 1483 1110 hmp_handle_error(mon, err); 1484 1111 } 1485 1112 1486 - void hmp_info_snapshots(Monitor *mon, const QDict *qdict) 1487 - { 1488 - BlockDriverState *bs, *bs1; 1489 - BdrvNextIterator it1; 1490 - QEMUSnapshotInfo *sn_tab, *sn; 1491 - bool no_snapshot = true; 1492 - int nb_sns, i; 1493 - int total; 1494 - int *global_snapshots; 1495 - AioContext *aio_context; 1496 - 1497 - typedef struct SnapshotEntry { 1498 - QEMUSnapshotInfo sn; 1499 - QTAILQ_ENTRY(SnapshotEntry) next; 1500 - } SnapshotEntry; 1501 - 1502 - typedef struct ImageEntry { 1503 - const char *imagename; 1504 - QTAILQ_ENTRY(ImageEntry) next; 1505 - QTAILQ_HEAD(, SnapshotEntry) snapshots; 1506 - } ImageEntry; 1507 - 1508 - QTAILQ_HEAD(, ImageEntry) image_list = 1509 - QTAILQ_HEAD_INITIALIZER(image_list); 1510 - 1511 - ImageEntry *image_entry, *next_ie; 1512 - SnapshotEntry *snapshot_entry; 1513 - 1514 - bs = bdrv_all_find_vmstate_bs(); 1515 - if (!bs) { 1516 - monitor_printf(mon, "No available block device supports snapshots\n"); 1517 - return; 1518 - } 1519 - aio_context = bdrv_get_aio_context(bs); 1520 - 1521 - aio_context_acquire(aio_context); 1522 - nb_sns = bdrv_snapshot_list(bs, &sn_tab); 1523 - aio_context_release(aio_context); 1524 - 1525 - if (nb_sns < 0) { 1526 - monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns); 1527 - return; 1528 - } 1529 - 1530 - for (bs1 = bdrv_first(&it1); bs1; bs1 = bdrv_next(&it1)) { 1531 - int bs1_nb_sns = 0; 1532 - ImageEntry *ie; 1533 - SnapshotEntry *se; 1534 - AioContext *ctx = bdrv_get_aio_context(bs1); 1535 - 1536 - aio_context_acquire(ctx); 1537 - if (bdrv_can_snapshot(bs1)) { 1538 - sn = NULL; 1539 - bs1_nb_sns = bdrv_snapshot_list(bs1, &sn); 1540 - if (bs1_nb_sns > 0) { 1541 - no_snapshot = false; 1542 - ie = g_new0(ImageEntry, 1); 1543 - ie->imagename = bdrv_get_device_name(bs1); 1544 - QTAILQ_INIT(&ie->snapshots); 1545 - QTAILQ_INSERT_TAIL(&image_list, ie, next); 1546 - for (i = 0; i < bs1_nb_sns; i++) { 1547 - se = g_new0(SnapshotEntry, 1); 1548 - se->sn = sn[i]; 1549 - QTAILQ_INSERT_TAIL(&ie->snapshots, se, next); 1550 - } 1551 - } 1552 - g_free(sn); 1553 - } 1554 - aio_context_release(ctx); 1555 - } 1556 - 1557 - if (no_snapshot) { 1558 - monitor_printf(mon, "There is no snapshot available.\n"); 1559 - return; 1560 - } 1561 - 1562 - global_snapshots = g_new0(int, nb_sns); 1563 - total = 0; 1564 - for (i = 0; i < nb_sns; i++) { 1565 - SnapshotEntry *next_sn; 1566 - if (bdrv_all_find_snapshot(sn_tab[i].name, &bs1) == 0) { 1567 - global_snapshots[total] = i; 1568 - total++; 1569 - QTAILQ_FOREACH(image_entry, &image_list, next) { 1570 - QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, 1571 - next, next_sn) { 1572 - if (!strcmp(sn_tab[i].name, snapshot_entry->sn.name)) { 1573 - QTAILQ_REMOVE(&image_entry->snapshots, snapshot_entry, 1574 - next); 1575 - g_free(snapshot_entry); 1576 - } 1577 - } 1578 - } 1579 - } 1580 - } 1581 - 1582 - monitor_printf(mon, "List of snapshots present on all disks:\n"); 1583 - 1584 - if (total > 0) { 1585 - bdrv_snapshot_dump(NULL); 1586 - monitor_printf(mon, "\n"); 1587 - for (i = 0; i < total; i++) { 1588 - sn = &sn_tab[global_snapshots[i]]; 1589 - /* The ID is not guaranteed to be the same on all images, so 1590 - * overwrite it. 1591 - */ 1592 - pstrcpy(sn->id_str, sizeof(sn->id_str), "--"); 1593 - bdrv_snapshot_dump(sn); 1594 - monitor_printf(mon, "\n"); 1595 - } 1596 - } else { 1597 - monitor_printf(mon, "None\n"); 1598 - } 1599 - 1600 - QTAILQ_FOREACH(image_entry, &image_list, next) { 1601 - if (QTAILQ_EMPTY(&image_entry->snapshots)) { 1602 - continue; 1603 - } 1604 - monitor_printf(mon, 1605 - "\nList of partial (non-loadable) snapshots on '%s':\n", 1606 - image_entry->imagename); 1607 - bdrv_snapshot_dump(NULL); 1608 - monitor_printf(mon, "\n"); 1609 - QTAILQ_FOREACH(snapshot_entry, &image_entry->snapshots, next) { 1610 - bdrv_snapshot_dump(&snapshot_entry->sn); 1611 - monitor_printf(mon, "\n"); 1612 - } 1613 - } 1614 - 1615 - QTAILQ_FOREACH_SAFE(image_entry, &image_list, next, next_ie) { 1616 - SnapshotEntry *next_sn; 1617 - QTAILQ_FOREACH_SAFE(snapshot_entry, &image_entry->snapshots, next, 1618 - next_sn) { 1619 - g_free(snapshot_entry); 1620 - } 1621 - g_free(image_entry); 1622 - } 1623 - g_free(sn_tab); 1624 - g_free(global_snapshots); 1625 - 1626 - } 1627 - 1628 1113 void hmp_announce_self(Monitor *mon, const QDict *qdict) 1629 1114 { 1630 1115 const char *interfaces_str = qdict_get_try_str(qdict, "interfaces"); ··· 1946 1431 hmp_handle_error(mon, err); 1947 1432 } 1948 1433 1949 - void hmp_eject(Monitor *mon, const QDict *qdict) 1950 - { 1951 - bool force = qdict_get_try_bool(qdict, "force", false); 1952 - const char *device = qdict_get_str(qdict, "device"); 1953 - Error *err = NULL; 1954 - 1955 - qmp_eject(true, device, false, NULL, true, force, &err); 1956 - hmp_handle_error(mon, err); 1957 - } 1958 1434 1959 1435 #ifdef CONFIG_VNC 1960 1436 static void hmp_change_read_arg(void *opaque, const char *password, ··· 2012 1488 hmp_handle_error(mon, err); 2013 1489 } 2014 1490 2015 - void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict) 2016 - { 2017 - Error *err = NULL; 2018 - char *device = (char *) qdict_get_str(qdict, "device"); 2019 - BlockIOThrottle throttle = { 2020 - .bps = qdict_get_int(qdict, "bps"), 2021 - .bps_rd = qdict_get_int(qdict, "bps_rd"), 2022 - .bps_wr = qdict_get_int(qdict, "bps_wr"), 2023 - .iops = qdict_get_int(qdict, "iops"), 2024 - .iops_rd = qdict_get_int(qdict, "iops_rd"), 2025 - .iops_wr = qdict_get_int(qdict, "iops_wr"), 2026 - }; 2027 - 2028 - /* qmp_block_set_io_throttle has separate parameters for the 2029 - * (deprecated) block device name and the qdev ID but the HMP 2030 - * version has only one, so we must decide which one to pass. */ 2031 - if (blk_by_name(device)) { 2032 - throttle.has_device = true; 2033 - throttle.device = device; 2034 - } else { 2035 - throttle.has_id = true; 2036 - throttle.id = device; 2037 - } 2038 - 2039 - qmp_block_set_io_throttle(&throttle, &err); 2040 - hmp_handle_error(mon, err); 2041 - } 2042 - 2043 - void hmp_block_stream(Monitor *mon, const QDict *qdict) 2044 - { 2045 - Error *error = NULL; 2046 - const char *device = qdict_get_str(qdict, "device"); 2047 - const char *base = qdict_get_try_str(qdict, "base"); 2048 - int64_t speed = qdict_get_try_int(qdict, "speed", 0); 2049 - 2050 - qmp_block_stream(true, device, device, base != NULL, base, false, NULL, 2051 - false, NULL, qdict_haskey(qdict, "speed"), speed, true, 2052 - BLOCKDEV_ON_ERROR_REPORT, false, false, false, false, 2053 - &error); 2054 - 2055 - hmp_handle_error(mon, error); 2056 - } 2057 - 2058 - void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict) 2059 - { 2060 - Error *error = NULL; 2061 - const char *device = qdict_get_str(qdict, "device"); 2062 - int64_t value = qdict_get_int(qdict, "speed"); 2063 - 2064 - qmp_block_job_set_speed(device, value, &error); 2065 - 2066 - hmp_handle_error(mon, error); 2067 - } 2068 - 2069 - void hmp_block_job_cancel(Monitor *mon, const QDict *qdict) 2070 - { 2071 - Error *error = NULL; 2072 - const char *device = qdict_get_str(qdict, "device"); 2073 - bool force = qdict_get_try_bool(qdict, "force", false); 2074 - 2075 - qmp_block_job_cancel(device, true, force, &error); 2076 - 2077 - hmp_handle_error(mon, error); 2078 - } 2079 - 2080 - void hmp_block_job_pause(Monitor *mon, const QDict *qdict) 2081 - { 2082 - Error *error = NULL; 2083 - const char *device = qdict_get_str(qdict, "device"); 2084 - 2085 - qmp_block_job_pause(device, &error); 2086 - 2087 - hmp_handle_error(mon, error); 2088 - } 2089 - 2090 - void hmp_block_job_resume(Monitor *mon, const QDict *qdict) 2091 - { 2092 - Error *error = NULL; 2093 - const char *device = qdict_get_str(qdict, "device"); 2094 - 2095 - qmp_block_job_resume(device, &error); 2096 - 2097 - hmp_handle_error(mon, error); 2098 - } 2099 - 2100 - void hmp_block_job_complete(Monitor *mon, const QDict *qdict) 2101 - { 2102 - Error *error = NULL; 2103 - const char *device = qdict_get_str(qdict, "device"); 2104 - 2105 - qmp_block_job_complete(device, &error); 2106 - 2107 - hmp_handle_error(mon, error); 2108 - } 2109 - 2110 1491 typedef struct HMPMigrationStatus 2111 1492 { 2112 1493 QEMUTimer *timer; ··· 2333 1714 hmp_handle_error(mon, err); 2334 1715 } 2335 1716 2336 - void hmp_nbd_server_start(Monitor *mon, const QDict *qdict) 2337 - { 2338 - const char *uri = qdict_get_str(qdict, "uri"); 2339 - bool writable = qdict_get_try_bool(qdict, "writable", false); 2340 - bool all = qdict_get_try_bool(qdict, "all", false); 2341 - Error *local_err = NULL; 2342 - BlockInfoList *block_list, *info; 2343 - SocketAddress *addr; 2344 - BlockExportNbd export; 2345 - 2346 - if (writable && !all) { 2347 - error_setg(&local_err, "-w only valid together with -a"); 2348 - goto exit; 2349 - } 2350 - 2351 - /* First check if the address is valid and start the server. */ 2352 - addr = socket_parse(uri, &local_err); 2353 - if (local_err != NULL) { 2354 - goto exit; 2355 - } 2356 - 2357 - nbd_server_start(addr, NULL, NULL, &local_err); 2358 - qapi_free_SocketAddress(addr); 2359 - if (local_err != NULL) { 2360 - goto exit; 2361 - } 2362 - 2363 - if (!all) { 2364 - return; 2365 - } 2366 - 2367 - /* Then try adding all block devices. If one fails, close all and 2368 - * exit. 2369 - */ 2370 - block_list = qmp_query_block(NULL); 2371 - 2372 - for (info = block_list; info; info = info->next) { 2373 - if (!info->value->has_inserted) { 2374 - continue; 2375 - } 2376 - 2377 - export = (BlockExportNbd) { 2378 - .device = info->value->device, 2379 - .has_writable = true, 2380 - .writable = writable, 2381 - }; 2382 - 2383 - qmp_nbd_server_add(&export, &local_err); 2384 - 2385 - if (local_err != NULL) { 2386 - qmp_nbd_server_stop(NULL); 2387 - break; 2388 - } 2389 - } 2390 - 2391 - qapi_free_BlockInfoList(block_list); 2392 - 2393 - exit: 2394 - hmp_handle_error(mon, local_err); 2395 - } 2396 - 2397 - void hmp_nbd_server_add(Monitor *mon, const QDict *qdict) 2398 - { 2399 - const char *device = qdict_get_str(qdict, "device"); 2400 - const char *name = qdict_get_try_str(qdict, "name"); 2401 - bool writable = qdict_get_try_bool(qdict, "writable", false); 2402 - Error *local_err = NULL; 2403 - 2404 - BlockExportNbd export = { 2405 - .device = (char *) device, 2406 - .has_name = !!name, 2407 - .name = (char *) name, 2408 - .has_writable = true, 2409 - .writable = writable, 2410 - }; 2411 - 2412 - qmp_nbd_server_add(&export, &local_err); 2413 - hmp_handle_error(mon, local_err); 2414 - } 2415 - 2416 - void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict) 2417 - { 2418 - const char *name = qdict_get_str(qdict, "name"); 2419 - bool force = qdict_get_try_bool(qdict, "force", false); 2420 - Error *err = NULL; 2421 - 2422 - /* Rely on NBD_SERVER_REMOVE_MODE_SAFE being the default */ 2423 - qmp_nbd_server_remove(name, force, NBD_SERVER_REMOVE_MODE_HARD, &err); 2424 - hmp_handle_error(mon, err); 2425 - } 2426 - 2427 - void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict) 2428 - { 2429 - Error *err = NULL; 2430 - 2431 - qmp_nbd_server_stop(&err); 2432 - hmp_handle_error(mon, err); 2433 - } 2434 - 2435 1717 void hmp_chardev_add(Monitor *mon, const QDict *qdict) 2436 1718 { 2437 1719 const char *args = qdict_get_str(qdict, "args"); ··· 2496 1778 2497 1779 qmp_chardev_send_break(qdict_get_str(qdict, "id"), &local_err); 2498 1780 hmp_handle_error(mon, local_err); 2499 - } 2500 - 2501 - void hmp_qemu_io(Monitor *mon, const QDict *qdict) 2502 - { 2503 - BlockBackend *blk; 2504 - BlockBackend *local_blk = NULL; 2505 - bool qdev = qdict_get_try_bool(qdict, "qdev", false); 2506 - const char* device = qdict_get_str(qdict, "device"); 2507 - const char* command = qdict_get_str(qdict, "command"); 2508 - Error *err = NULL; 2509 - int ret; 2510 - 2511 - if (qdev) { 2512 - blk = blk_by_qdev_id(device, &err); 2513 - if (!blk) { 2514 - goto fail; 2515 - } 2516 - } else { 2517 - blk = blk_by_name(device); 2518 - if (!blk) { 2519 - BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err); 2520 - if (bs) { 2521 - blk = local_blk = blk_new(bdrv_get_aio_context(bs), 2522 - 0, BLK_PERM_ALL); 2523 - ret = blk_insert_bs(blk, bs, &err); 2524 - if (ret < 0) { 2525 - goto fail; 2526 - } 2527 - } else { 2528 - goto fail; 2529 - } 2530 - } 2531 - } 2532 - 2533 - /* 2534 - * Notably absent: Proper permission management. This is sad, but it seems 2535 - * almost impossible to achieve without changing the semantics and thereby 2536 - * limiting the use cases of the qemu-io HMP command. 2537 - * 2538 - * In an ideal world we would unconditionally create a new BlockBackend for 2539 - * qemuio_command(), but we have commands like 'reopen' and want them to 2540 - * take effect on the exact BlockBackend whose name the user passed instead 2541 - * of just on a temporary copy of it. 2542 - * 2543 - * Another problem is that deleting the temporary BlockBackend involves 2544 - * draining all requests on it first, but some qemu-iotests cases want to 2545 - * issue multiple aio_read/write requests and expect them to complete in 2546 - * the background while the monitor has already returned. 2547 - * 2548 - * This is also what prevents us from saving the original permissions and 2549 - * restoring them later: We can't revoke permissions until all requests 2550 - * have completed, and we don't know when that is nor can we really let 2551 - * anything else run before we have revoken them to avoid race conditions. 2552 - * 2553 - * What happens now is that command() in qemu-io-cmds.c can extend the 2554 - * permissions if necessary for the qemu-io command. And they simply stay 2555 - * extended, possibly resulting in a read-only guest device keeping write 2556 - * permissions. Ugly, but it appears to be the lesser evil. 2557 - */ 2558 - qemuio_command(blk, command); 2559 - 2560 - fail: 2561 - blk_unref(local_blk); 2562 - hmp_handle_error(mon, err); 2563 1781 } 2564 1782 2565 1783 void hmp_object_del(Monitor *mon, const QDict *qdict)
+1
monitor/misc.c
··· 66 66 #include "qemu/option.h" 67 67 #include "qemu/thread.h" 68 68 #include "block/qapi.h" 69 + #include "block/block-hmp-cmds.h" 69 70 #include "qapi/qapi-commands-char.h" 70 71 #include "qapi/qapi-commands-control.h" 71 72 #include "qapi/qapi-commands-migration.h"
-23
net/hub.c
··· 194 194 } 195 195 196 196 /** 197 - * Find a specific client on a hub 198 - */ 199 - NetClientState *net_hub_find_client_by_name(int hub_id, const char *name) 200 - { 201 - NetHub *hub; 202 - NetHubPort *port; 203 - NetClientState *peer; 204 - 205 - QLIST_FOREACH(hub, &hubs, next) { 206 - if (hub->id == hub_id) { 207 - QLIST_FOREACH(port, &hub->ports, next) { 208 - peer = port->nc.peer; 209 - 210 - if (peer && strcmp(peer->name, name) == 0) { 211 - return peer; 212 - } 213 - } 214 - } 215 - } 216 - return NULL; 217 - } 218 - 219 - /** 220 197 * Find a available port on a hub; otherwise create one new port 221 198 */ 222 199 NetClientState *net_hub_port_find(int hub_id)
-2
net/hub.h
··· 15 15 #ifndef NET_HUB_H 16 16 #define NET_HUB_H 17 17 18 - 19 18 NetClientState *net_hub_add_port(int hub_id, const char *name, 20 19 NetClientState *hubpeer); 21 - NetClientState *net_hub_find_client_by_name(int hub_id, const char *name); 22 20 void net_hub_info(Monitor *mon); 23 21 void net_hub_check_clients(void); 24 22 bool net_hub_flush(NetClientState *nc);
+12 -32
net/slirp.c
··· 610 610 return -1; 611 611 } 612 612 613 - static SlirpState *slirp_lookup(Monitor *mon, const char *hub_id, 614 - const char *name) 613 + static SlirpState *slirp_lookup(Monitor *mon, const char *id) 615 614 { 616 - if (name) { 617 - NetClientState *nc; 618 - if (hub_id) { 619 - nc = net_hub_find_client_by_name(strtol(hub_id, NULL, 0), name); 620 - if (!nc) { 621 - monitor_printf(mon, "unrecognized (hub-id, stackname) pair\n"); 622 - return NULL; 623 - } 624 - warn_report("Using 'hub-id' is deprecated, specify the netdev id " 625 - "directly instead"); 626 - } else { 627 - nc = qemu_find_netdev(name); 628 - if (!nc) { 629 - monitor_printf(mon, "unrecognized netdev id '%s'\n", name); 630 - return NULL; 631 - } 615 + if (id) { 616 + NetClientState *nc = qemu_find_netdev(id); 617 + if (!nc) { 618 + monitor_printf(mon, "unrecognized netdev id '%s'\n", id); 619 + return NULL; 632 620 } 633 621 if (strcmp(nc->model, "user")) { 634 622 monitor_printf(mon, "invalid device specified\n"); ··· 655 643 int err; 656 644 const char *arg1 = qdict_get_str(qdict, "arg1"); 657 645 const char *arg2 = qdict_get_try_str(qdict, "arg2"); 658 - const char *arg3 = qdict_get_try_str(qdict, "arg3"); 659 646 660 - if (arg3) { 661 - s = slirp_lookup(mon, arg1, arg2); 662 - src_str = arg3; 663 - } else if (arg2) { 664 - s = slirp_lookup(mon, NULL, arg1); 647 + if (arg2) { 648 + s = slirp_lookup(mon, arg1); 665 649 src_str = arg2; 666 650 } else { 667 - s = slirp_lookup(mon, NULL, NULL); 651 + s = slirp_lookup(mon, NULL); 668 652 src_str = arg1; 669 653 } 670 654 if (!s) { ··· 784 768 SlirpState *s; 785 769 const char *arg1 = qdict_get_str(qdict, "arg1"); 786 770 const char *arg2 = qdict_get_try_str(qdict, "arg2"); 787 - const char *arg3 = qdict_get_try_str(qdict, "arg3"); 788 771 789 - if (arg3) { 790 - s = slirp_lookup(mon, arg1, arg2); 791 - redir_str = arg3; 792 - } else if (arg2) { 793 - s = slirp_lookup(mon, NULL, arg1); 772 + if (arg2) { 773 + s = slirp_lookup(mon, arg1); 794 774 redir_str = arg2; 795 775 } else { 796 - s = slirp_lookup(mon, NULL, NULL); 776 + s = slirp_lookup(mon, NULL); 797 777 redir_str = arg1; 798 778 } 799 779 if (s) {