monitor/hmp: move hmp_drive_del and hmp_commit to block-hmp-cmds.c
[qemu/ar7.git] / block / monitor / block-hmp-cmds.c
blobad727a6b08d42c5e451f5b13120dad14f3990c44
1 /*
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
10 * permission notice:
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
30 * THE SOFTWARE.
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)
49 Error *err = NULL;
50 DriveInfo *dinfo;
51 QemuOpts *opts;
52 MachineClass *mc;
53 const char *optstr = qdict_get_str(qdict, "opts");
54 bool node = qdict_get_try_bool(qdict, "node", false);
56 if (node) {
57 hmp_drive_add_node(mon, optstr);
58 return;
61 opts = drive_def(optstr);
62 if (!opts)
63 return;
65 mc = MACHINE_GET_CLASS(current_machine);
66 dinfo = drive_new(opts, mc->block_default_type, &err);
67 if (err) {
68 error_report_err(err);
69 qemu_opts_del(opts);
70 goto err;
73 if (!dinfo) {
74 return;
77 switch (dinfo->type) {
78 case IF_NONE:
79 monitor_printf(mon, "OK\n");
80 break;
81 default:
82 monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type);
83 goto err;
85 return;
87 err:
88 if (dinfo) {
89 BlockBackend *blk = blk_by_legacy_dinfo(dinfo);
90 monitor_remove_blk(blk);
91 blk_unref(blk);
95 void hmp_drive_del(Monitor *mon, const QDict *qdict)
97 const char *id = qdict_get_str(qdict, "id");
98 BlockBackend *blk;
99 BlockDriverState *bs;
100 AioContext *aio_context;
101 Error *local_err = NULL;
103 bs = bdrv_find_node(id);
104 if (bs) {
105 qmp_blockdev_del(id, &local_err);
106 if (local_err) {
107 error_report_err(local_err);
109 return;
112 blk = blk_by_name(id);
113 if (!blk) {
114 error_report("Device '%s' not found", id);
115 return;
118 if (!blk_legacy_dinfo(blk)) {
119 error_report("Deleting device added with blockdev-add"
120 " is not supported");
121 return;
124 aio_context = blk_get_aio_context(blk);
125 aio_context_acquire(aio_context);
127 bs = blk_bs(blk);
128 if (bs) {
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);
132 return;
135 blk_remove_bs(blk);
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);
149 } else {
150 blk_unref(blk);
153 aio_context_release(aio_context);
156 void hmp_commit(Monitor *mon, const QDict *qdict)
158 const char *device = qdict_get_str(qdict, "device");
159 BlockBackend *blk;
160 int ret;
162 if (!strcmp(device, "all")) {
163 ret = blk_commit_all();
164 } else {
165 BlockDriverState *bs;
166 AioContext *aio_context;
168 blk = blk_by_name(device);
169 if (!blk) {
170 error_report("Device '%s' not found", device);
171 return;
173 if (!blk_is_available(blk)) {
174 error_report("Device '%s' has no medium", device);
175 return;
178 bs = blk_bs(blk);
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);
186 if (ret < 0) {
187 error_report("'commit' error for '%s': %s", device, strerror(-ret));