2 * Blockdev HMP commands
4 * Copyright (c) 2003-2008 Fabrice Bellard
6 * This work is licensed under the terms of the GNU GPL, version 2 or
7 * later. See the COPYING file in the top-level directory.
9 * This file incorporates work covered by the following copyright and
12 * Copyright (c) 2003-2008 Fabrice Bellard
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this software and associated documentation files (the "Software"), to deal
16 * in the Software without restriction, including without limitation the rights
17 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 * copies of the Software, and to permit persons to whom the Software is
19 * furnished to do so, subject to the following conditions:
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33 #include "qemu/osdep.h"
34 #include "hw/boards.h"
35 #include "sysemu/block-backend.h"
36 #include "sysemu/blockdev.h"
37 #include "qapi/qapi-commands-block.h"
38 #include "qapi/qmp/qdict.h"
39 #include "qapi/error.h"
40 #include "qemu/config-file.h"
41 #include "qemu/option.h"
42 #include "sysemu/sysemu.h"
43 #include "monitor/monitor.h"
44 #include "block/block_int.h"
45 #include "block/block-hmp-cmds.h"
47 void hmp_drive_add(Monitor
*mon
, const QDict
*qdict
)
53 const char *optstr
= qdict_get_str(qdict
, "opts");
54 bool node
= qdict_get_try_bool(qdict
, "node", false);
57 hmp_drive_add_node(mon
, optstr
);
61 opts
= drive_def(optstr
);
65 mc
= MACHINE_GET_CLASS(current_machine
);
66 dinfo
= drive_new(opts
, mc
->block_default_type
, &err
);
68 error_report_err(err
);
77 switch (dinfo
->type
) {
79 monitor_printf(mon
, "OK\n");
82 monitor_printf(mon
, "Can't hot-add drive to type %d\n", dinfo
->type
);
89 BlockBackend
*blk
= blk_by_legacy_dinfo(dinfo
);
90 monitor_remove_blk(blk
);
95 void hmp_drive_del(Monitor
*mon
, const QDict
*qdict
)
97 const char *id
= qdict_get_str(qdict
, "id");
100 AioContext
*aio_context
;
101 Error
*local_err
= NULL
;
103 bs
= bdrv_find_node(id
);
105 qmp_blockdev_del(id
, &local_err
);
107 error_report_err(local_err
);
112 blk
= blk_by_name(id
);
114 error_report("Device '%s' not found", id
);
118 if (!blk_legacy_dinfo(blk
)) {
119 error_report("Deleting device added with blockdev-add"
120 " is not supported");
124 aio_context
= blk_get_aio_context(blk
);
125 aio_context_acquire(aio_context
);
129 if (bdrv_op_is_blocked(bs
, BLOCK_OP_TYPE_DRIVE_DEL
, &local_err
)) {
130 error_report_err(local_err
);
131 aio_context_release(aio_context
);
138 /* Make the BlockBackend and the attached BlockDriverState anonymous */
139 monitor_remove_blk(blk
);
142 * If this BlockBackend has a device attached to it, its refcount will be
143 * decremented when the device is removed; otherwise we have to do so here.
145 if (blk_get_attached_dev(blk
)) {
146 /* Further I/O must not pause the guest */
147 blk_set_on_error(blk
, BLOCKDEV_ON_ERROR_REPORT
,
148 BLOCKDEV_ON_ERROR_REPORT
);
153 aio_context_release(aio_context
);
156 void hmp_commit(Monitor
*mon
, const QDict
*qdict
)
158 const char *device
= qdict_get_str(qdict
, "device");
162 if (!strcmp(device
, "all")) {
163 ret
= blk_commit_all();
165 BlockDriverState
*bs
;
166 AioContext
*aio_context
;
168 blk
= blk_by_name(device
);
170 error_report("Device '%s' not found", device
);
173 if (!blk_is_available(blk
)) {
174 error_report("Device '%s' has no medium", device
);
179 aio_context
= bdrv_get_aio_context(bs
);
180 aio_context_acquire(aio_context
);
182 ret
= bdrv_commit(bs
);
184 aio_context_release(aio_context
);
187 error_report("'commit' error for '%s': %s", device
, strerror(-ret
));