monitor/hmp: move remaining hmp_block* functions to block-hmp-cmds.c
[qemu/ar7.git] / block / monitor / block-hmp-cmds.c
blob5beb7df2f7077b4cdfa35a277d2b175445b5c80a
1 /*
2 * Blockdev HMP commands
4 * Authors:
5 * Anthony Liguori <aliguori@us.ibm.com>
7 * Copyright (c) 2003-2008 Fabrice Bellard
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.
14 * This file incorporates work covered by the following copyright and
15 * permission notice:
17 * Copyright (c) 2003-2008 Fabrice Bellard
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:
26 * The above copyright notice and this permission notice shall be included in
27 * all copies or substantial portions of the Software.
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.
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 "sysemu/sysemu.h"
50 #include "monitor/monitor.h"
51 #include "monitor/hmp.h"
52 #include "block/nbd.h"
53 #include "block/block_int.h"
54 #include "block/block-hmp-cmds.h"
55 #include "qemu-io.h"
57 void hmp_drive_add(Monitor *mon, const QDict *qdict)
59 Error *err = NULL;
60 DriveInfo *dinfo;
61 QemuOpts *opts;
62 MachineClass *mc;
63 const char *optstr = qdict_get_str(qdict, "opts");
64 bool node = qdict_get_try_bool(qdict, "node", false);
66 if (node) {
67 hmp_drive_add_node(mon, optstr);
68 return;
71 opts = drive_def(optstr);
72 if (!opts)
73 return;
75 mc = MACHINE_GET_CLASS(current_machine);
76 dinfo = drive_new(opts, mc->block_default_type, &err);
77 if (err) {
78 error_report_err(err);
79 qemu_opts_del(opts);
80 goto err;
83 if (!dinfo) {
84 return;
87 switch (dinfo->type) {
88 case IF_NONE:
89 monitor_printf(mon, "OK\n");
90 break;
91 default:
92 monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);
93 goto err;
95 return;
97 err:
98 if (dinfo) {
99 BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
100 monitor_remove_blk(blk);
101 blk_unref(blk);
105 void hmp_drive_del(Monitor *mon, const QDict *qdict)
107 const char *id = qdict_get_str(qdict, "id");
108 BlockBackend *blk;
109 BlockDriverState *bs;
110 AioContext *aio_context;
111 Error *local_err = NULL;
113 bs = bdrv_find_node(id);
114 if (bs) {
115 qmp_blockdev_del(id, &local_err);
116 if (local_err) {
117 error_report_err(local_err);
119 return;
122 blk = blk_by_name(id);
123 if (!blk) {
124 error_report("Device '%s' not found", id);
125 return;
128 if (!blk_legacy_dinfo(blk)) {
129 error_report("Deleting device added with blockdev-add"
130 " is not supported");
131 return;
134 aio_context = blk_get_aio_context(blk);
135 aio_context_acquire(aio_context);
137 bs = blk_bs(blk);
138 if (bs) {
139 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_DRIVE_DEL, &local_err)) {
140 error_report_err(local_err);
141 aio_context_release(aio_context);
142 return;
145 blk_remove_bs(blk);
148 /* Make the BlockBackend and the attached BlockDriverState anonymous */
149 monitor_remove_blk(blk);
152 * If this BlockBackend has a device attached to it, its refcount will be
153 * decremented when the device is removed; otherwise we have to do so here.
155 if (blk_get_attached_dev(blk)) {
156 /* Further I/O must not pause the guest */
157 blk_set_on_error(blk, BLOCKDEV_ON_ERROR_REPORT,
158 BLOCKDEV_ON_ERROR_REPORT);
159 } else {
160 blk_unref(blk);
163 aio_context_release(aio_context);
166 void hmp_commit(Monitor *mon, const QDict *qdict)
168 const char *device = qdict_get_str(qdict, "device");
169 BlockBackend *blk;
170 int ret;
172 if (!strcmp(device, "all")) {
173 ret = blk_commit_all();
174 } else {
175 BlockDriverState *bs;
176 AioContext *aio_context;
178 blk = blk_by_name(device);
179 if (!blk) {
180 error_report("Device '%s' not found", device);
181 return;
183 if (!blk_is_available(blk)) {
184 error_report("Device '%s' has no medium", device);
185 return;
188 bs = blk_bs(blk);
189 aio_context = bdrv_get_aio_context(bs);
190 aio_context_acquire(aio_context);
192 ret = bdrv_commit(bs);
194 aio_context_release(aio_context);
196 if (ret < 0) {
197 error_report("'commit' error for '%s': %s", device, strerror(-ret));
201 void hmp_drive_mirror(Monitor *mon, const QDict *qdict)
203 const char *filename = qdict_get_str(qdict, "target");
204 const char *format = qdict_get_try_str(qdict, "format");
205 bool reuse = qdict_get_try_bool(qdict, "reuse", false);
206 bool full = qdict_get_try_bool(qdict, "full", false);
207 Error *err = NULL;
208 DriveMirror mirror = {
209 .device = (char *)qdict_get_str(qdict, "device"),
210 .target = (char *)filename,
211 .has_format = !!format,
212 .format = (char *)format,
213 .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
214 .has_mode = true,
215 .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
216 .unmap = true,
219 if (!filename) {
220 error_setg(&err, QERR_MISSING_PARAMETER, "target");
221 hmp_handle_error(mon, err);
222 return;
224 qmp_drive_mirror(&mirror, &err);
225 hmp_handle_error(mon, err);
228 void hmp_drive_backup(Monitor *mon, const QDict *qdict)
230 const char *device = qdict_get_str(qdict, "device");
231 const char *filename = qdict_get_str(qdict, "target");
232 const char *format = qdict_get_try_str(qdict, "format");
233 bool reuse = qdict_get_try_bool(qdict, "reuse", false);
234 bool full = qdict_get_try_bool(qdict, "full", false);
235 bool compress = qdict_get_try_bool(qdict, "compress", false);
236 Error *err = NULL;
237 DriveBackup backup = {
238 .device = (char *)device,
239 .target = (char *)filename,
240 .has_format = !!format,
241 .format = (char *)format,
242 .sync = full ? MIRROR_SYNC_MODE_FULL : MIRROR_SYNC_MODE_TOP,
243 .has_mode = true,
244 .mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS,
245 .has_compress = !!compress,
246 .compress = compress,
249 if (!filename) {
250 error_setg(&err, QERR_MISSING_PARAMETER, "target");
251 hmp_handle_error(mon, err);
252 return;
255 qmp_drive_backup(&backup, &err);
256 hmp_handle_error(mon, err);
259 void hmp_block_job_set_speed(Monitor *mon, const QDict *qdict)
261 Error *error = NULL;
262 const char *device = qdict_get_str(qdict, "device");
263 int64_t value = qdict_get_int(qdict, "speed");
265 qmp_block_job_set_speed(device, value, &error);
267 hmp_handle_error(mon, error);
270 void hmp_block_job_cancel(Monitor *mon, const QDict *qdict)
272 Error *error = NULL;
273 const char *device = qdict_get_str(qdict, "device");
274 bool force = qdict_get_try_bool(qdict, "force", false);
276 qmp_block_job_cancel(device, true, force, &error);
278 hmp_handle_error(mon, error);
281 void hmp_block_job_pause(Monitor *mon, const QDict *qdict)
283 Error *error = NULL;
284 const char *device = qdict_get_str(qdict, "device");
286 qmp_block_job_pause(device, &error);
288 hmp_handle_error(mon, error);
291 void hmp_block_job_resume(Monitor *mon, const QDict *qdict)
293 Error *error = NULL;
294 const char *device = qdict_get_str(qdict, "device");
296 qmp_block_job_resume(device, &error);
298 hmp_handle_error(mon, error);
301 void hmp_block_job_complete(Monitor *mon, const QDict *qdict)
303 Error *error = NULL;
304 const char *device = qdict_get_str(qdict, "device");
306 qmp_block_job_complete(device, &error);
308 hmp_handle_error(mon, error);
311 void hmp_snapshot_blkdev(Monitor *mon, const QDict *qdict)
313 const char *device = qdict_get_str(qdict, "device");
314 const char *filename = qdict_get_try_str(qdict, "snapshot-file");
315 const char *format = qdict_get_try_str(qdict, "format");
316 bool reuse = qdict_get_try_bool(qdict, "reuse", false);
317 enum NewImageMode mode;
318 Error *err = NULL;
320 if (!filename) {
322 * In the future, if 'snapshot-file' is not specified, the snapshot
323 * will be taken internally. Today it's actually required.
325 error_setg(&err, QERR_MISSING_PARAMETER, "snapshot-file");
326 hmp_handle_error(mon, err);
327 return;
330 mode = reuse ? NEW_IMAGE_MODE_EXISTING : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
331 qmp_blockdev_snapshot_sync(true, device, false, NULL,
332 filename, false, NULL,
333 !!format, format,
334 true, mode, &err);
335 hmp_handle_error(mon, err);
338 void hmp_snapshot_blkdev_internal(Monitor *mon, const QDict *qdict)
340 const char *device = qdict_get_str(qdict, "device");
341 const char *name = qdict_get_str(qdict, "name");
342 Error *err = NULL;
344 qmp_blockdev_snapshot_internal_sync(device, name, &err);
345 hmp_handle_error(mon, err);
348 void hmp_snapshot_delete_blkdev_internal(Monitor *mon, const QDict *qdict)
350 const char *device = qdict_get_str(qdict, "device");
351 const char *name = qdict_get_str(qdict, "name");
352 const char *id = qdict_get_try_str(qdict, "id");
353 Error *err = NULL;
355 qmp_blockdev_snapshot_delete_internal_sync(device, !!id, id,
356 true, name, &err);
357 hmp_handle_error(mon, err);
360 void hmp_nbd_server_start(Monitor *mon, const QDict *qdict)
362 const char *uri = qdict_get_str(qdict, "uri");
363 bool writable = qdict_get_try_bool(qdict, "writable", false);
364 bool all = qdict_get_try_bool(qdict, "all", false);
365 Error *local_err = NULL;
366 BlockInfoList *block_list, *info;
367 SocketAddress *addr;
368 BlockExportNbd export;
370 if (writable && !all) {
371 error_setg(&local_err, "-w only valid together with -a");
372 goto exit;
375 /* First check if the address is valid and start the server. */
376 addr = socket_parse(uri, &local_err);
377 if (local_err != NULL) {
378 goto exit;
381 nbd_server_start(addr, NULL, NULL, &local_err);
382 qapi_free_SocketAddress(addr);
383 if (local_err != NULL) {
384 goto exit;
387 if (!all) {
388 return;
391 /* Then try adding all block devices. If one fails, close all and
392 * exit.
394 block_list = qmp_query_block(NULL);
396 for (info = block_list; info; info = info->next) {
397 if (!info->value->has_inserted) {
398 continue;
401 export = (BlockExportNbd) {
402 .device = info->value->device,
403 .has_writable = true,
404 .writable = writable,
407 qmp_nbd_server_add(&export, &local_err);
409 if (local_err != NULL) {
410 qmp_nbd_server_stop(NULL);
411 break;
415 qapi_free_BlockInfoList(block_list);
417 exit:
418 hmp_handle_error(mon, local_err);
421 void hmp_nbd_server_add(Monitor *mon, const QDict *qdict)
423 const char *device = qdict_get_str(qdict, "device");
424 const char *name = qdict_get_try_str(qdict, "name");
425 bool writable = qdict_get_try_bool(qdict, "writable", false);
426 Error *local_err = NULL;
428 BlockExportNbd export = {
429 .device = (char *) device,
430 .has_name = !!name,
431 .name = (char *) name,
432 .has_writable = true,
433 .writable = writable,
436 qmp_nbd_server_add(&export, &local_err);
437 hmp_handle_error(mon, local_err);
440 void hmp_nbd_server_remove(Monitor *mon, const QDict *qdict)
442 const char *name = qdict_get_str(qdict, "name");
443 bool force = qdict_get_try_bool(qdict, "force", false);
444 Error *err = NULL;
446 /* Rely on NBD_SERVER_REMOVE_MODE_SAFE being the default */
447 qmp_nbd_server_remove(name, force, NBD_SERVER_REMOVE_MODE_HARD, &err);
448 hmp_handle_error(mon, err);
451 void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict)
453 Error *err = NULL;
455 qmp_nbd_server_stop(&err);
456 hmp_handle_error(mon, err);
459 void hmp_block_resize(Monitor *mon, const QDict *qdict)
461 const char *device = qdict_get_str(qdict, "device");
462 int64_t size = qdict_get_int(qdict, "size");
463 Error *err = NULL;
465 qmp_block_resize(true, device, false, NULL, size, &err);
466 hmp_handle_error(mon, err);
469 void hmp_block_stream(Monitor *mon, const QDict *qdict)
471 Error *error = NULL;
472 const char *device = qdict_get_str(qdict, "device");
473 const char *base = qdict_get_try_str(qdict, "base");
474 int64_t speed = qdict_get_try_int(qdict, "speed", 0);
476 qmp_block_stream(true, device, device, base != NULL, base, false, NULL,
477 false, NULL, qdict_haskey(qdict, "speed"), speed, true,
478 BLOCKDEV_ON_ERROR_REPORT, false, false, false, false,
479 &error);
481 hmp_handle_error(mon, error);
484 void hmp_block_passwd(Monitor *mon, const QDict *qdict)
486 const char *device = qdict_get_str(qdict, "device");
487 const char *password = qdict_get_str(qdict, "password");
488 Error *err = NULL;
490 qmp_block_passwd(true, device, false, NULL, password, &err);
491 hmp_handle_error(mon, err);
494 void hmp_block_set_io_throttle(Monitor *mon, const QDict *qdict)
496 Error *err = NULL;
497 char *device = (char *) qdict_get_str(qdict, "device");
498 BlockIOThrottle throttle = {
499 .bps = qdict_get_int(qdict, "bps"),
500 .bps_rd = qdict_get_int(qdict, "bps_rd"),
501 .bps_wr = qdict_get_int(qdict, "bps_wr"),
502 .iops = qdict_get_int(qdict, "iops"),
503 .iops_rd = qdict_get_int(qdict, "iops_rd"),
504 .iops_wr = qdict_get_int(qdict, "iops_wr"),
508 * qmp_block_set_io_throttle has separate parameters for the
509 * (deprecated) block device name and the qdev ID but the HMP
510 * version has only one, so we must decide which one to pass.
512 if (blk_by_name(device)) {
513 throttle.has_device = true;
514 throttle.device = device;
515 } else {
516 throttle.has_id = true;
517 throttle.id = device;
520 qmp_block_set_io_throttle(&throttle, &err);
521 hmp_handle_error(mon, err);
524 void hmp_eject(Monitor *mon, const QDict *qdict)
526 bool force = qdict_get_try_bool(qdict, "force", false);
527 const char *device = qdict_get_str(qdict, "device");
528 Error *err = NULL;
530 qmp_eject(true, device, false, NULL, true, force, &err);
531 hmp_handle_error(mon, err);
534 void hmp_qemu_io(Monitor *mon, const QDict *qdict)
536 BlockBackend *blk;
537 BlockBackend *local_blk = NULL;
538 bool qdev = qdict_get_try_bool(qdict, "qdev", false);
539 const char *device = qdict_get_str(qdict, "device");
540 const char *command = qdict_get_str(qdict, "command");
541 Error *err = NULL;
542 int ret;
544 if (qdev) {
545 blk = blk_by_qdev_id(device, &err);
546 if (!blk) {
547 goto fail;
549 } else {
550 blk = blk_by_name(device);
551 if (!blk) {
552 BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
553 if (bs) {
554 blk = local_blk = blk_new(bdrv_get_aio_context(bs),
555 0, BLK_PERM_ALL);
556 ret = blk_insert_bs(blk, bs, &err);
557 if (ret < 0) {
558 goto fail;
560 } else {
561 goto fail;
567 * Notably absent: Proper permission management. This is sad, but it seems
568 * almost impossible to achieve without changing the semantics and thereby
569 * limiting the use cases of the qemu-io HMP command.
571 * In an ideal world we would unconditionally create a new BlockBackend for
572 * qemuio_command(), but we have commands like 'reopen' and want them to
573 * take effect on the exact BlockBackend whose name the user passed instead
574 * of just on a temporary copy of it.
576 * Another problem is that deleting the temporary BlockBackend involves
577 * draining all requests on it first, but some qemu-iotests cases want to
578 * issue multiple aio_read/write requests and expect them to complete in
579 * the background while the monitor has already returned.
581 * This is also what prevents us from saving the original permissions and
582 * restoring them later: We can't revoke permissions until all requests
583 * have completed, and we don't know when that is nor can we really let
584 * anything else run before we have revoken them to avoid race conditions.
586 * What happens now is that command() in qemu-io-cmds.c can extend the
587 * permissions if necessary for the qemu-io command. And they simply stay
588 * extended, possibly resulting in a read-only guest device keeping write
589 * permissions. Ugly, but it appears to be the lesser evil.
591 qemuio_command(blk, command);
593 fail:
594 blk_unref(local_blk);
595 hmp_handle_error(mon, err);