132cad1ffSPhilippe Mathieu-Daudé /*
232cad1ffSPhilippe Mathieu-Daudé * QMP command handlers specific to the system emulators
332cad1ffSPhilippe Mathieu-Daudé *
432cad1ffSPhilippe Mathieu-Daudé * Copyright (c) 2003-2008 Fabrice Bellard
532cad1ffSPhilippe Mathieu-Daudé *
632cad1ffSPhilippe Mathieu-Daudé * This work is licensed under the terms of the GNU GPL, version 2 or
732cad1ffSPhilippe Mathieu-Daudé * later. See the COPYING file in the top-level directory.
832cad1ffSPhilippe Mathieu-Daudé *
932cad1ffSPhilippe Mathieu-Daudé * This file incorporates work covered by the following copyright and
1032cad1ffSPhilippe Mathieu-Daudé * permission notice:
1132cad1ffSPhilippe Mathieu-Daudé *
1232cad1ffSPhilippe Mathieu-Daudé * Copyright (c) 2003-2008 Fabrice Bellard
1332cad1ffSPhilippe Mathieu-Daudé *
1432cad1ffSPhilippe Mathieu-Daudé * Permission is hereby granted, free of charge, to any person obtaining a copy
1532cad1ffSPhilippe Mathieu-Daudé * of this software and associated documentation files (the "Software"), to deal
1632cad1ffSPhilippe Mathieu-Daudé * in the Software without restriction, including without limitation the rights
1732cad1ffSPhilippe Mathieu-Daudé * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1832cad1ffSPhilippe Mathieu-Daudé * copies of the Software, and to permit persons to whom the Software is
1932cad1ffSPhilippe Mathieu-Daudé * furnished to do so, subject to the following conditions:
2032cad1ffSPhilippe Mathieu-Daudé *
2132cad1ffSPhilippe Mathieu-Daudé * The above copyright notice and this permission notice shall be included in
2232cad1ffSPhilippe Mathieu-Daudé * all copies or substantial portions of the Software.
2332cad1ffSPhilippe Mathieu-Daudé *
2432cad1ffSPhilippe Mathieu-Daudé * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2532cad1ffSPhilippe Mathieu-Daudé * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2632cad1ffSPhilippe Mathieu-Daudé * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
2732cad1ffSPhilippe Mathieu-Daudé * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2832cad1ffSPhilippe Mathieu-Daudé * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2932cad1ffSPhilippe Mathieu-Daudé * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3032cad1ffSPhilippe Mathieu-Daudé * THE SOFTWARE.
3132cad1ffSPhilippe Mathieu-Daudé */
3232cad1ffSPhilippe Mathieu-Daudé
3332cad1ffSPhilippe Mathieu-Daudé #include "qemu/osdep.h"
3432cad1ffSPhilippe Mathieu-Daudé
3532cad1ffSPhilippe Mathieu-Daudé #include "block/block_int.h"
3632cad1ffSPhilippe Mathieu-Daudé #include "qapi/error.h"
3732cad1ffSPhilippe Mathieu-Daudé #include "qapi/qapi-commands-block.h"
38*407bc4bfSDaniel P. Berrangé #include "qobject/qdict.h"
3932cad1ffSPhilippe Mathieu-Daudé #include "system/block-backend.h"
4032cad1ffSPhilippe Mathieu-Daudé #include "system/blockdev.h"
4132cad1ffSPhilippe Mathieu-Daudé
qmp_get_blk(const char * blk_name,const char * qdev_id,Error ** errp)4232cad1ffSPhilippe Mathieu-Daudé static BlockBackend *qmp_get_blk(const char *blk_name, const char *qdev_id,
4332cad1ffSPhilippe Mathieu-Daudé Error **errp)
4432cad1ffSPhilippe Mathieu-Daudé {
4532cad1ffSPhilippe Mathieu-Daudé BlockBackend *blk;
4632cad1ffSPhilippe Mathieu-Daudé
4732cad1ffSPhilippe Mathieu-Daudé if (!blk_name == !qdev_id) {
4832cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Need exactly one of 'device' and 'id'");
4932cad1ffSPhilippe Mathieu-Daudé return NULL;
5032cad1ffSPhilippe Mathieu-Daudé }
5132cad1ffSPhilippe Mathieu-Daudé
5232cad1ffSPhilippe Mathieu-Daudé if (qdev_id) {
5332cad1ffSPhilippe Mathieu-Daudé blk = blk_by_qdev_id(qdev_id, errp);
5432cad1ffSPhilippe Mathieu-Daudé } else {
5532cad1ffSPhilippe Mathieu-Daudé blk = blk_by_name(blk_name);
5632cad1ffSPhilippe Mathieu-Daudé if (blk == NULL) {
5732cad1ffSPhilippe Mathieu-Daudé error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
5832cad1ffSPhilippe Mathieu-Daudé "Device '%s' not found", blk_name);
5932cad1ffSPhilippe Mathieu-Daudé }
6032cad1ffSPhilippe Mathieu-Daudé }
6132cad1ffSPhilippe Mathieu-Daudé
6232cad1ffSPhilippe Mathieu-Daudé return blk;
6332cad1ffSPhilippe Mathieu-Daudé }
6432cad1ffSPhilippe Mathieu-Daudé
6532cad1ffSPhilippe Mathieu-Daudé /*
6632cad1ffSPhilippe Mathieu-Daudé * Attempt to open the tray of @device.
6732cad1ffSPhilippe Mathieu-Daudé * If @force, ignore its tray lock.
6832cad1ffSPhilippe Mathieu-Daudé * Else, if the tray is locked, don't open it, but ask the guest to open it.
6932cad1ffSPhilippe Mathieu-Daudé * On error, store an error through @errp and return -errno.
7032cad1ffSPhilippe Mathieu-Daudé * If @device does not exist, return -ENODEV.
7132cad1ffSPhilippe Mathieu-Daudé * If it has no removable media, return -ENOTSUP.
7232cad1ffSPhilippe Mathieu-Daudé * If it has no tray, return -ENOSYS.
7332cad1ffSPhilippe Mathieu-Daudé * If the guest was asked to open the tray, return -EINPROGRESS.
7432cad1ffSPhilippe Mathieu-Daudé * Else, return 0.
7532cad1ffSPhilippe Mathieu-Daudé */
do_open_tray(const char * blk_name,const char * qdev_id,bool force,Error ** errp)7632cad1ffSPhilippe Mathieu-Daudé static int do_open_tray(const char *blk_name, const char *qdev_id,
7732cad1ffSPhilippe Mathieu-Daudé bool force, Error **errp)
7832cad1ffSPhilippe Mathieu-Daudé {
7932cad1ffSPhilippe Mathieu-Daudé BlockBackend *blk;
8032cad1ffSPhilippe Mathieu-Daudé const char *device = qdev_id ?: blk_name;
8132cad1ffSPhilippe Mathieu-Daudé bool locked;
8232cad1ffSPhilippe Mathieu-Daudé
8332cad1ffSPhilippe Mathieu-Daudé blk = qmp_get_blk(blk_name, qdev_id, errp);
8432cad1ffSPhilippe Mathieu-Daudé if (!blk) {
8532cad1ffSPhilippe Mathieu-Daudé return -ENODEV;
8632cad1ffSPhilippe Mathieu-Daudé }
8732cad1ffSPhilippe Mathieu-Daudé
8832cad1ffSPhilippe Mathieu-Daudé if (!blk_dev_has_removable_media(blk)) {
8932cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device '%s' is not removable", device);
9032cad1ffSPhilippe Mathieu-Daudé return -ENOTSUP;
9132cad1ffSPhilippe Mathieu-Daudé }
9232cad1ffSPhilippe Mathieu-Daudé
9332cad1ffSPhilippe Mathieu-Daudé if (!blk_dev_has_tray(blk)) {
9432cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device '%s' does not have a tray", device);
9532cad1ffSPhilippe Mathieu-Daudé return -ENOSYS;
9632cad1ffSPhilippe Mathieu-Daudé }
9732cad1ffSPhilippe Mathieu-Daudé
9832cad1ffSPhilippe Mathieu-Daudé if (blk_dev_is_tray_open(blk)) {
9932cad1ffSPhilippe Mathieu-Daudé return 0;
10032cad1ffSPhilippe Mathieu-Daudé }
10132cad1ffSPhilippe Mathieu-Daudé
10232cad1ffSPhilippe Mathieu-Daudé locked = blk_dev_is_medium_locked(blk);
10332cad1ffSPhilippe Mathieu-Daudé if (locked) {
10432cad1ffSPhilippe Mathieu-Daudé blk_dev_eject_request(blk, force);
10532cad1ffSPhilippe Mathieu-Daudé }
10632cad1ffSPhilippe Mathieu-Daudé
10732cad1ffSPhilippe Mathieu-Daudé if (!locked || force) {
10832cad1ffSPhilippe Mathieu-Daudé blk_dev_change_media_cb(blk, false, &error_abort);
10932cad1ffSPhilippe Mathieu-Daudé }
11032cad1ffSPhilippe Mathieu-Daudé
11132cad1ffSPhilippe Mathieu-Daudé if (locked && !force) {
11232cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device '%s' is locked and force was not specified, "
11332cad1ffSPhilippe Mathieu-Daudé "wait for tray to open and try again", device);
11432cad1ffSPhilippe Mathieu-Daudé return -EINPROGRESS;
11532cad1ffSPhilippe Mathieu-Daudé }
11632cad1ffSPhilippe Mathieu-Daudé
11732cad1ffSPhilippe Mathieu-Daudé return 0;
11832cad1ffSPhilippe Mathieu-Daudé }
11932cad1ffSPhilippe Mathieu-Daudé
qmp_blockdev_open_tray(const char * device,const char * id,bool has_force,bool force,Error ** errp)12032cad1ffSPhilippe Mathieu-Daudé void qmp_blockdev_open_tray(const char *device,
12132cad1ffSPhilippe Mathieu-Daudé const char *id,
12232cad1ffSPhilippe Mathieu-Daudé bool has_force, bool force,
12332cad1ffSPhilippe Mathieu-Daudé Error **errp)
12432cad1ffSPhilippe Mathieu-Daudé {
12532cad1ffSPhilippe Mathieu-Daudé Error *local_err = NULL;
12632cad1ffSPhilippe Mathieu-Daudé int rc;
12732cad1ffSPhilippe Mathieu-Daudé
12832cad1ffSPhilippe Mathieu-Daudé if (!has_force) {
12932cad1ffSPhilippe Mathieu-Daudé force = false;
13032cad1ffSPhilippe Mathieu-Daudé }
13132cad1ffSPhilippe Mathieu-Daudé rc = do_open_tray(device, id, force, &local_err);
13232cad1ffSPhilippe Mathieu-Daudé if (rc && rc != -ENOSYS && rc != -EINPROGRESS) {
13332cad1ffSPhilippe Mathieu-Daudé error_propagate(errp, local_err);
13432cad1ffSPhilippe Mathieu-Daudé return;
13532cad1ffSPhilippe Mathieu-Daudé }
13632cad1ffSPhilippe Mathieu-Daudé error_free(local_err);
13732cad1ffSPhilippe Mathieu-Daudé }
13832cad1ffSPhilippe Mathieu-Daudé
qmp_blockdev_close_tray(const char * device,const char * id,Error ** errp)13932cad1ffSPhilippe Mathieu-Daudé void qmp_blockdev_close_tray(const char *device,
14032cad1ffSPhilippe Mathieu-Daudé const char *id,
14132cad1ffSPhilippe Mathieu-Daudé Error **errp)
14232cad1ffSPhilippe Mathieu-Daudé {
14332cad1ffSPhilippe Mathieu-Daudé BlockBackend *blk;
14432cad1ffSPhilippe Mathieu-Daudé Error *local_err = NULL;
14532cad1ffSPhilippe Mathieu-Daudé
14632cad1ffSPhilippe Mathieu-Daudé blk = qmp_get_blk(device, id, errp);
14732cad1ffSPhilippe Mathieu-Daudé if (!blk) {
14832cad1ffSPhilippe Mathieu-Daudé return;
14932cad1ffSPhilippe Mathieu-Daudé }
15032cad1ffSPhilippe Mathieu-Daudé
15132cad1ffSPhilippe Mathieu-Daudé if (!blk_dev_has_removable_media(blk)) {
15232cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device '%s' is not removable", device ?: id);
15332cad1ffSPhilippe Mathieu-Daudé return;
15432cad1ffSPhilippe Mathieu-Daudé }
15532cad1ffSPhilippe Mathieu-Daudé
15632cad1ffSPhilippe Mathieu-Daudé if (!blk_dev_has_tray(blk)) {
15732cad1ffSPhilippe Mathieu-Daudé /* Ignore this command on tray-less devices */
15832cad1ffSPhilippe Mathieu-Daudé return;
15932cad1ffSPhilippe Mathieu-Daudé }
16032cad1ffSPhilippe Mathieu-Daudé
16132cad1ffSPhilippe Mathieu-Daudé if (!blk_dev_is_tray_open(blk)) {
16232cad1ffSPhilippe Mathieu-Daudé return;
16332cad1ffSPhilippe Mathieu-Daudé }
16432cad1ffSPhilippe Mathieu-Daudé
16532cad1ffSPhilippe Mathieu-Daudé blk_dev_change_media_cb(blk, true, &local_err);
16632cad1ffSPhilippe Mathieu-Daudé if (local_err) {
16732cad1ffSPhilippe Mathieu-Daudé error_propagate(errp, local_err);
16832cad1ffSPhilippe Mathieu-Daudé return;
16932cad1ffSPhilippe Mathieu-Daudé }
17032cad1ffSPhilippe Mathieu-Daudé }
17132cad1ffSPhilippe Mathieu-Daudé
17232cad1ffSPhilippe Mathieu-Daudé static void GRAPH_UNLOCKED
blockdev_remove_medium(const char * device,const char * id,Error ** errp)17332cad1ffSPhilippe Mathieu-Daudé blockdev_remove_medium(const char *device, const char *id, Error **errp)
17432cad1ffSPhilippe Mathieu-Daudé {
17532cad1ffSPhilippe Mathieu-Daudé BlockBackend *blk;
17632cad1ffSPhilippe Mathieu-Daudé BlockDriverState *bs;
17732cad1ffSPhilippe Mathieu-Daudé bool has_attached_device;
17832cad1ffSPhilippe Mathieu-Daudé
17932cad1ffSPhilippe Mathieu-Daudé GLOBAL_STATE_CODE();
18032cad1ffSPhilippe Mathieu-Daudé
18132cad1ffSPhilippe Mathieu-Daudé blk = qmp_get_blk(device, id, errp);
18232cad1ffSPhilippe Mathieu-Daudé if (!blk) {
18332cad1ffSPhilippe Mathieu-Daudé return;
18432cad1ffSPhilippe Mathieu-Daudé }
18532cad1ffSPhilippe Mathieu-Daudé
18632cad1ffSPhilippe Mathieu-Daudé /* For BBs without a device, we can exchange the BDS tree at will */
18732cad1ffSPhilippe Mathieu-Daudé has_attached_device = blk_get_attached_dev(blk);
18832cad1ffSPhilippe Mathieu-Daudé
18932cad1ffSPhilippe Mathieu-Daudé if (has_attached_device && !blk_dev_has_removable_media(blk)) {
19032cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device '%s' is not removable", device ?: id);
19132cad1ffSPhilippe Mathieu-Daudé return;
19232cad1ffSPhilippe Mathieu-Daudé }
19332cad1ffSPhilippe Mathieu-Daudé
19432cad1ffSPhilippe Mathieu-Daudé if (has_attached_device && blk_dev_has_tray(blk) &&
19532cad1ffSPhilippe Mathieu-Daudé !blk_dev_is_tray_open(blk))
19632cad1ffSPhilippe Mathieu-Daudé {
19732cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Tray of device '%s' is not open", device ?: id);
19832cad1ffSPhilippe Mathieu-Daudé return;
19932cad1ffSPhilippe Mathieu-Daudé }
20032cad1ffSPhilippe Mathieu-Daudé
20132cad1ffSPhilippe Mathieu-Daudé bs = blk_bs(blk);
20232cad1ffSPhilippe Mathieu-Daudé if (!bs) {
20332cad1ffSPhilippe Mathieu-Daudé return;
20432cad1ffSPhilippe Mathieu-Daudé }
20532cad1ffSPhilippe Mathieu-Daudé
20632cad1ffSPhilippe Mathieu-Daudé bdrv_graph_rdlock_main_loop();
20732cad1ffSPhilippe Mathieu-Daudé if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
20832cad1ffSPhilippe Mathieu-Daudé bdrv_graph_rdunlock_main_loop();
20932cad1ffSPhilippe Mathieu-Daudé return;
21032cad1ffSPhilippe Mathieu-Daudé }
21132cad1ffSPhilippe Mathieu-Daudé bdrv_graph_rdunlock_main_loop();
21232cad1ffSPhilippe Mathieu-Daudé
21332cad1ffSPhilippe Mathieu-Daudé blk_remove_bs(blk);
21432cad1ffSPhilippe Mathieu-Daudé
21532cad1ffSPhilippe Mathieu-Daudé if (!blk_dev_has_tray(blk)) {
21632cad1ffSPhilippe Mathieu-Daudé /* For tray-less devices, blockdev-open-tray is a no-op (or may not be
21732cad1ffSPhilippe Mathieu-Daudé * called at all); therefore, the medium needs to be ejected here.
21832cad1ffSPhilippe Mathieu-Daudé * Do it after blk_remove_bs() so blk_is_inserted(blk) returns the @load
21932cad1ffSPhilippe Mathieu-Daudé * value passed here (i.e. false). */
22032cad1ffSPhilippe Mathieu-Daudé blk_dev_change_media_cb(blk, false, &error_abort);
22132cad1ffSPhilippe Mathieu-Daudé }
22232cad1ffSPhilippe Mathieu-Daudé }
22332cad1ffSPhilippe Mathieu-Daudé
qmp_blockdev_remove_medium(const char * id,Error ** errp)22432cad1ffSPhilippe Mathieu-Daudé void qmp_blockdev_remove_medium(const char *id, Error **errp)
22532cad1ffSPhilippe Mathieu-Daudé {
22632cad1ffSPhilippe Mathieu-Daudé blockdev_remove_medium(NULL, id, errp);
22732cad1ffSPhilippe Mathieu-Daudé }
22832cad1ffSPhilippe Mathieu-Daudé
qmp_blockdev_insert_anon_medium(BlockBackend * blk,BlockDriverState * bs,Error ** errp)22932cad1ffSPhilippe Mathieu-Daudé static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
23032cad1ffSPhilippe Mathieu-Daudé BlockDriverState *bs, Error **errp)
23132cad1ffSPhilippe Mathieu-Daudé {
23232cad1ffSPhilippe Mathieu-Daudé Error *local_err = NULL;
23332cad1ffSPhilippe Mathieu-Daudé bool has_device;
23432cad1ffSPhilippe Mathieu-Daudé int ret;
23532cad1ffSPhilippe Mathieu-Daudé
23632cad1ffSPhilippe Mathieu-Daudé /* For BBs without a device, we can exchange the BDS tree at will */
23732cad1ffSPhilippe Mathieu-Daudé has_device = blk_get_attached_dev(blk);
23832cad1ffSPhilippe Mathieu-Daudé
23932cad1ffSPhilippe Mathieu-Daudé if (has_device && !blk_dev_has_removable_media(blk)) {
24032cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device is not removable");
24132cad1ffSPhilippe Mathieu-Daudé return;
24232cad1ffSPhilippe Mathieu-Daudé }
24332cad1ffSPhilippe Mathieu-Daudé
24432cad1ffSPhilippe Mathieu-Daudé if (has_device && blk_dev_has_tray(blk) && !blk_dev_is_tray_open(blk)) {
24532cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Tray of the device is not open");
24632cad1ffSPhilippe Mathieu-Daudé return;
24732cad1ffSPhilippe Mathieu-Daudé }
24832cad1ffSPhilippe Mathieu-Daudé
24932cad1ffSPhilippe Mathieu-Daudé if (blk_bs(blk)) {
25032cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "There already is a medium in the device");
25132cad1ffSPhilippe Mathieu-Daudé return;
25232cad1ffSPhilippe Mathieu-Daudé }
25332cad1ffSPhilippe Mathieu-Daudé
25432cad1ffSPhilippe Mathieu-Daudé ret = blk_insert_bs(blk, bs, errp);
25532cad1ffSPhilippe Mathieu-Daudé if (ret < 0) {
25632cad1ffSPhilippe Mathieu-Daudé return;
25732cad1ffSPhilippe Mathieu-Daudé }
25832cad1ffSPhilippe Mathieu-Daudé
25932cad1ffSPhilippe Mathieu-Daudé if (!blk_dev_has_tray(blk)) {
26032cad1ffSPhilippe Mathieu-Daudé /* For tray-less devices, blockdev-close-tray is a no-op (or may not be
26132cad1ffSPhilippe Mathieu-Daudé * called at all); therefore, the medium needs to be pushed into the
26232cad1ffSPhilippe Mathieu-Daudé * slot here.
26332cad1ffSPhilippe Mathieu-Daudé * Do it after blk_insert_bs() so blk_is_inserted(blk) returns the @load
26432cad1ffSPhilippe Mathieu-Daudé * value passed here (i.e. true). */
26532cad1ffSPhilippe Mathieu-Daudé blk_dev_change_media_cb(blk, true, &local_err);
26632cad1ffSPhilippe Mathieu-Daudé if (local_err) {
26732cad1ffSPhilippe Mathieu-Daudé error_propagate(errp, local_err);
26832cad1ffSPhilippe Mathieu-Daudé blk_remove_bs(blk);
26932cad1ffSPhilippe Mathieu-Daudé return;
27032cad1ffSPhilippe Mathieu-Daudé }
27132cad1ffSPhilippe Mathieu-Daudé }
27232cad1ffSPhilippe Mathieu-Daudé }
27332cad1ffSPhilippe Mathieu-Daudé
blockdev_insert_medium(const char * device,const char * id,const char * node_name,Error ** errp)27432cad1ffSPhilippe Mathieu-Daudé static void blockdev_insert_medium(const char *device, const char *id,
27532cad1ffSPhilippe Mathieu-Daudé const char *node_name, Error **errp)
27632cad1ffSPhilippe Mathieu-Daudé {
27732cad1ffSPhilippe Mathieu-Daudé BlockBackend *blk;
27832cad1ffSPhilippe Mathieu-Daudé BlockDriverState *bs;
27932cad1ffSPhilippe Mathieu-Daudé
28032cad1ffSPhilippe Mathieu-Daudé GRAPH_RDLOCK_GUARD_MAINLOOP();
28132cad1ffSPhilippe Mathieu-Daudé
28232cad1ffSPhilippe Mathieu-Daudé blk = qmp_get_blk(device, id, errp);
28332cad1ffSPhilippe Mathieu-Daudé if (!blk) {
28432cad1ffSPhilippe Mathieu-Daudé return;
28532cad1ffSPhilippe Mathieu-Daudé }
28632cad1ffSPhilippe Mathieu-Daudé
28732cad1ffSPhilippe Mathieu-Daudé bs = bdrv_find_node(node_name);
28832cad1ffSPhilippe Mathieu-Daudé if (!bs) {
28932cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Node '%s' not found", node_name);
29032cad1ffSPhilippe Mathieu-Daudé return;
29132cad1ffSPhilippe Mathieu-Daudé }
29232cad1ffSPhilippe Mathieu-Daudé
29332cad1ffSPhilippe Mathieu-Daudé if (bdrv_has_blk(bs)) {
29432cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Node '%s' is already in use", node_name);
29532cad1ffSPhilippe Mathieu-Daudé return;
29632cad1ffSPhilippe Mathieu-Daudé }
29732cad1ffSPhilippe Mathieu-Daudé
29832cad1ffSPhilippe Mathieu-Daudé qmp_blockdev_insert_anon_medium(blk, bs, errp);
29932cad1ffSPhilippe Mathieu-Daudé }
30032cad1ffSPhilippe Mathieu-Daudé
qmp_blockdev_insert_medium(const char * id,const char * node_name,Error ** errp)30132cad1ffSPhilippe Mathieu-Daudé void qmp_blockdev_insert_medium(const char *id, const char *node_name,
30232cad1ffSPhilippe Mathieu-Daudé Error **errp)
30332cad1ffSPhilippe Mathieu-Daudé {
30432cad1ffSPhilippe Mathieu-Daudé blockdev_insert_medium(NULL, id, node_name, errp);
30532cad1ffSPhilippe Mathieu-Daudé }
30632cad1ffSPhilippe Mathieu-Daudé
qmp_blockdev_change_medium(const char * device,const char * id,const char * filename,const char * format,bool has_force,bool force,bool has_read_only,BlockdevChangeReadOnlyMode read_only,Error ** errp)30732cad1ffSPhilippe Mathieu-Daudé void qmp_blockdev_change_medium(const char *device,
30832cad1ffSPhilippe Mathieu-Daudé const char *id,
30932cad1ffSPhilippe Mathieu-Daudé const char *filename,
31032cad1ffSPhilippe Mathieu-Daudé const char *format,
31132cad1ffSPhilippe Mathieu-Daudé bool has_force, bool force,
31232cad1ffSPhilippe Mathieu-Daudé bool has_read_only,
31332cad1ffSPhilippe Mathieu-Daudé BlockdevChangeReadOnlyMode read_only,
31432cad1ffSPhilippe Mathieu-Daudé Error **errp)
31532cad1ffSPhilippe Mathieu-Daudé {
31632cad1ffSPhilippe Mathieu-Daudé BlockBackend *blk;
31732cad1ffSPhilippe Mathieu-Daudé BlockDriverState *medium_bs = NULL;
31832cad1ffSPhilippe Mathieu-Daudé int bdrv_flags;
31932cad1ffSPhilippe Mathieu-Daudé bool detect_zeroes;
32032cad1ffSPhilippe Mathieu-Daudé int rc;
32132cad1ffSPhilippe Mathieu-Daudé QDict *options = NULL;
32232cad1ffSPhilippe Mathieu-Daudé Error *err = NULL;
32332cad1ffSPhilippe Mathieu-Daudé
32432cad1ffSPhilippe Mathieu-Daudé blk = qmp_get_blk(device, id, errp);
32532cad1ffSPhilippe Mathieu-Daudé if (!blk) {
32632cad1ffSPhilippe Mathieu-Daudé goto fail;
32732cad1ffSPhilippe Mathieu-Daudé }
32832cad1ffSPhilippe Mathieu-Daudé
32932cad1ffSPhilippe Mathieu-Daudé if (blk_bs(blk)) {
33032cad1ffSPhilippe Mathieu-Daudé blk_update_root_state(blk);
33132cad1ffSPhilippe Mathieu-Daudé }
33232cad1ffSPhilippe Mathieu-Daudé
33332cad1ffSPhilippe Mathieu-Daudé bdrv_flags = blk_get_open_flags_from_root_state(blk);
33432cad1ffSPhilippe Mathieu-Daudé bdrv_flags &= ~(BDRV_O_TEMPORARY | BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING |
33532cad1ffSPhilippe Mathieu-Daudé BDRV_O_PROTOCOL | BDRV_O_AUTO_RDONLY);
33632cad1ffSPhilippe Mathieu-Daudé
33732cad1ffSPhilippe Mathieu-Daudé if (!has_read_only) {
33832cad1ffSPhilippe Mathieu-Daudé read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
33932cad1ffSPhilippe Mathieu-Daudé }
34032cad1ffSPhilippe Mathieu-Daudé
34132cad1ffSPhilippe Mathieu-Daudé switch (read_only) {
34232cad1ffSPhilippe Mathieu-Daudé case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
34332cad1ffSPhilippe Mathieu-Daudé break;
34432cad1ffSPhilippe Mathieu-Daudé
34532cad1ffSPhilippe Mathieu-Daudé case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_ONLY:
34632cad1ffSPhilippe Mathieu-Daudé bdrv_flags &= ~BDRV_O_RDWR;
34732cad1ffSPhilippe Mathieu-Daudé break;
34832cad1ffSPhilippe Mathieu-Daudé
34932cad1ffSPhilippe Mathieu-Daudé case BLOCKDEV_CHANGE_READ_ONLY_MODE_READ_WRITE:
35032cad1ffSPhilippe Mathieu-Daudé bdrv_flags |= BDRV_O_RDWR;
35132cad1ffSPhilippe Mathieu-Daudé break;
35232cad1ffSPhilippe Mathieu-Daudé
35332cad1ffSPhilippe Mathieu-Daudé default:
35432cad1ffSPhilippe Mathieu-Daudé abort();
35532cad1ffSPhilippe Mathieu-Daudé }
35632cad1ffSPhilippe Mathieu-Daudé
35732cad1ffSPhilippe Mathieu-Daudé options = qdict_new();
35832cad1ffSPhilippe Mathieu-Daudé detect_zeroes = blk_get_detect_zeroes_from_root_state(blk);
35932cad1ffSPhilippe Mathieu-Daudé qdict_put_str(options, "detect-zeroes", detect_zeroes ? "on" : "off");
36032cad1ffSPhilippe Mathieu-Daudé
36132cad1ffSPhilippe Mathieu-Daudé if (format) {
36232cad1ffSPhilippe Mathieu-Daudé qdict_put_str(options, "driver", format);
36332cad1ffSPhilippe Mathieu-Daudé }
36432cad1ffSPhilippe Mathieu-Daudé
36532cad1ffSPhilippe Mathieu-Daudé medium_bs = bdrv_open(filename, NULL, options, bdrv_flags, errp);
36632cad1ffSPhilippe Mathieu-Daudé
36732cad1ffSPhilippe Mathieu-Daudé if (!medium_bs) {
36832cad1ffSPhilippe Mathieu-Daudé goto fail;
36932cad1ffSPhilippe Mathieu-Daudé }
37032cad1ffSPhilippe Mathieu-Daudé
37132cad1ffSPhilippe Mathieu-Daudé rc = do_open_tray(device, id, force, &err);
37232cad1ffSPhilippe Mathieu-Daudé if (rc && rc != -ENOSYS) {
37332cad1ffSPhilippe Mathieu-Daudé error_propagate(errp, err);
37432cad1ffSPhilippe Mathieu-Daudé goto fail;
37532cad1ffSPhilippe Mathieu-Daudé }
37632cad1ffSPhilippe Mathieu-Daudé error_free(err);
37732cad1ffSPhilippe Mathieu-Daudé err = NULL;
37832cad1ffSPhilippe Mathieu-Daudé
37932cad1ffSPhilippe Mathieu-Daudé blockdev_remove_medium(device, id, &err);
38032cad1ffSPhilippe Mathieu-Daudé if (err) {
38132cad1ffSPhilippe Mathieu-Daudé error_propagate(errp, err);
38232cad1ffSPhilippe Mathieu-Daudé goto fail;
38332cad1ffSPhilippe Mathieu-Daudé }
38432cad1ffSPhilippe Mathieu-Daudé
38532cad1ffSPhilippe Mathieu-Daudé qmp_blockdev_insert_anon_medium(blk, medium_bs, &err);
38632cad1ffSPhilippe Mathieu-Daudé if (err) {
38732cad1ffSPhilippe Mathieu-Daudé error_propagate(errp, err);
38832cad1ffSPhilippe Mathieu-Daudé goto fail;
38932cad1ffSPhilippe Mathieu-Daudé }
39032cad1ffSPhilippe Mathieu-Daudé
39132cad1ffSPhilippe Mathieu-Daudé qmp_blockdev_close_tray(device, id, errp);
39232cad1ffSPhilippe Mathieu-Daudé
39332cad1ffSPhilippe Mathieu-Daudé fail:
39432cad1ffSPhilippe Mathieu-Daudé /* If the medium has been inserted, the device has its own reference, so
39532cad1ffSPhilippe Mathieu-Daudé * ours must be relinquished; and if it has not been inserted successfully,
39632cad1ffSPhilippe Mathieu-Daudé * the reference must be relinquished anyway */
39732cad1ffSPhilippe Mathieu-Daudé bdrv_unref(medium_bs);
39832cad1ffSPhilippe Mathieu-Daudé }
39932cad1ffSPhilippe Mathieu-Daudé
qmp_eject(const char * device,const char * id,bool has_force,bool force,Error ** errp)40032cad1ffSPhilippe Mathieu-Daudé void qmp_eject(const char *device, const char *id,
40132cad1ffSPhilippe Mathieu-Daudé bool has_force, bool force, Error **errp)
40232cad1ffSPhilippe Mathieu-Daudé {
40332cad1ffSPhilippe Mathieu-Daudé Error *local_err = NULL;
40432cad1ffSPhilippe Mathieu-Daudé int rc;
40532cad1ffSPhilippe Mathieu-Daudé
40632cad1ffSPhilippe Mathieu-Daudé if (!has_force) {
40732cad1ffSPhilippe Mathieu-Daudé force = false;
40832cad1ffSPhilippe Mathieu-Daudé }
40932cad1ffSPhilippe Mathieu-Daudé
41032cad1ffSPhilippe Mathieu-Daudé rc = do_open_tray(device, id, force, &local_err);
41132cad1ffSPhilippe Mathieu-Daudé if (rc && rc != -ENOSYS) {
41232cad1ffSPhilippe Mathieu-Daudé error_propagate(errp, local_err);
41332cad1ffSPhilippe Mathieu-Daudé return;
41432cad1ffSPhilippe Mathieu-Daudé }
41532cad1ffSPhilippe Mathieu-Daudé error_free(local_err);
41632cad1ffSPhilippe Mathieu-Daudé
41732cad1ffSPhilippe Mathieu-Daudé blockdev_remove_medium(device, id, errp);
41832cad1ffSPhilippe Mathieu-Daudé }
41932cad1ffSPhilippe Mathieu-Daudé
42032cad1ffSPhilippe Mathieu-Daudé /* throttling disk I/O limits */
qmp_block_set_io_throttle(BlockIOThrottle * arg,Error ** errp)42132cad1ffSPhilippe Mathieu-Daudé void qmp_block_set_io_throttle(BlockIOThrottle *arg, Error **errp)
42232cad1ffSPhilippe Mathieu-Daudé {
42332cad1ffSPhilippe Mathieu-Daudé ThrottleConfig cfg;
42432cad1ffSPhilippe Mathieu-Daudé BlockDriverState *bs;
42532cad1ffSPhilippe Mathieu-Daudé BlockBackend *blk;
42632cad1ffSPhilippe Mathieu-Daudé
42732cad1ffSPhilippe Mathieu-Daudé blk = qmp_get_blk(arg->device, arg->id, errp);
42832cad1ffSPhilippe Mathieu-Daudé if (!blk) {
42932cad1ffSPhilippe Mathieu-Daudé return;
43032cad1ffSPhilippe Mathieu-Daudé }
43132cad1ffSPhilippe Mathieu-Daudé
43232cad1ffSPhilippe Mathieu-Daudé bs = blk_bs(blk);
43332cad1ffSPhilippe Mathieu-Daudé if (!bs) {
43432cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device has no medium");
43532cad1ffSPhilippe Mathieu-Daudé return;
43632cad1ffSPhilippe Mathieu-Daudé }
43732cad1ffSPhilippe Mathieu-Daudé
43832cad1ffSPhilippe Mathieu-Daudé throttle_config_init(&cfg);
43932cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_BPS_TOTAL].avg = arg->bps;
44032cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_BPS_READ].avg = arg->bps_rd;
44132cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_BPS_WRITE].avg = arg->bps_wr;
44232cad1ffSPhilippe Mathieu-Daudé
44332cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_OPS_TOTAL].avg = arg->iops;
44432cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_OPS_READ].avg = arg->iops_rd;
44532cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_OPS_WRITE].avg = arg->iops_wr;
44632cad1ffSPhilippe Mathieu-Daudé
44732cad1ffSPhilippe Mathieu-Daudé if (arg->has_bps_max) {
44832cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_BPS_TOTAL].max = arg->bps_max;
44932cad1ffSPhilippe Mathieu-Daudé }
45032cad1ffSPhilippe Mathieu-Daudé if (arg->has_bps_rd_max) {
45132cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_BPS_READ].max = arg->bps_rd_max;
45232cad1ffSPhilippe Mathieu-Daudé }
45332cad1ffSPhilippe Mathieu-Daudé if (arg->has_bps_wr_max) {
45432cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_BPS_WRITE].max = arg->bps_wr_max;
45532cad1ffSPhilippe Mathieu-Daudé }
45632cad1ffSPhilippe Mathieu-Daudé if (arg->has_iops_max) {
45732cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_OPS_TOTAL].max = arg->iops_max;
45832cad1ffSPhilippe Mathieu-Daudé }
45932cad1ffSPhilippe Mathieu-Daudé if (arg->has_iops_rd_max) {
46032cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_OPS_READ].max = arg->iops_rd_max;
46132cad1ffSPhilippe Mathieu-Daudé }
46232cad1ffSPhilippe Mathieu-Daudé if (arg->has_iops_wr_max) {
46332cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_OPS_WRITE].max = arg->iops_wr_max;
46432cad1ffSPhilippe Mathieu-Daudé }
46532cad1ffSPhilippe Mathieu-Daudé
46632cad1ffSPhilippe Mathieu-Daudé if (arg->has_bps_max_length) {
46732cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_BPS_TOTAL].burst_length = arg->bps_max_length;
46832cad1ffSPhilippe Mathieu-Daudé }
46932cad1ffSPhilippe Mathieu-Daudé if (arg->has_bps_rd_max_length) {
47032cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_BPS_READ].burst_length = arg->bps_rd_max_length;
47132cad1ffSPhilippe Mathieu-Daudé }
47232cad1ffSPhilippe Mathieu-Daudé if (arg->has_bps_wr_max_length) {
47332cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_BPS_WRITE].burst_length = arg->bps_wr_max_length;
47432cad1ffSPhilippe Mathieu-Daudé }
47532cad1ffSPhilippe Mathieu-Daudé if (arg->has_iops_max_length) {
47632cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_OPS_TOTAL].burst_length = arg->iops_max_length;
47732cad1ffSPhilippe Mathieu-Daudé }
47832cad1ffSPhilippe Mathieu-Daudé if (arg->has_iops_rd_max_length) {
47932cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_OPS_READ].burst_length = arg->iops_rd_max_length;
48032cad1ffSPhilippe Mathieu-Daudé }
48132cad1ffSPhilippe Mathieu-Daudé if (arg->has_iops_wr_max_length) {
48232cad1ffSPhilippe Mathieu-Daudé cfg.buckets[THROTTLE_OPS_WRITE].burst_length = arg->iops_wr_max_length;
48332cad1ffSPhilippe Mathieu-Daudé }
48432cad1ffSPhilippe Mathieu-Daudé
48532cad1ffSPhilippe Mathieu-Daudé if (arg->has_iops_size) {
48632cad1ffSPhilippe Mathieu-Daudé cfg.op_size = arg->iops_size;
48732cad1ffSPhilippe Mathieu-Daudé }
48832cad1ffSPhilippe Mathieu-Daudé
48932cad1ffSPhilippe Mathieu-Daudé if (!throttle_is_valid(&cfg, errp)) {
49032cad1ffSPhilippe Mathieu-Daudé return;
49132cad1ffSPhilippe Mathieu-Daudé }
49232cad1ffSPhilippe Mathieu-Daudé
49332cad1ffSPhilippe Mathieu-Daudé if (throttle_enabled(&cfg)) {
49432cad1ffSPhilippe Mathieu-Daudé /* Enable I/O limits if they're not enabled yet, otherwise
49532cad1ffSPhilippe Mathieu-Daudé * just update the throttling group. */
49632cad1ffSPhilippe Mathieu-Daudé if (!blk_get_public(blk)->throttle_group_member.throttle_state) {
49732cad1ffSPhilippe Mathieu-Daudé blk_io_limits_enable(blk, arg->group ?: arg->device ?: arg->id);
49832cad1ffSPhilippe Mathieu-Daudé } else if (arg->group) {
49932cad1ffSPhilippe Mathieu-Daudé blk_io_limits_update_group(blk, arg->group);
50032cad1ffSPhilippe Mathieu-Daudé }
50132cad1ffSPhilippe Mathieu-Daudé /* Set the new throttling configuration */
50232cad1ffSPhilippe Mathieu-Daudé blk_set_io_limits(blk, &cfg);
50332cad1ffSPhilippe Mathieu-Daudé } else if (blk_get_public(blk)->throttle_group_member.throttle_state) {
50432cad1ffSPhilippe Mathieu-Daudé /* If all throttling settings are set to 0, disable I/O limits */
50532cad1ffSPhilippe Mathieu-Daudé blk_io_limits_disable(blk);
50632cad1ffSPhilippe Mathieu-Daudé }
50732cad1ffSPhilippe Mathieu-Daudé }
50832cad1ffSPhilippe Mathieu-Daudé
qmp_block_latency_histogram_set(const char * id,bool has_boundaries,uint64List * boundaries,bool has_boundaries_read,uint64List * boundaries_read,bool has_boundaries_write,uint64List * boundaries_write,bool has_boundaries_append,uint64List * boundaries_append,bool has_boundaries_flush,uint64List * boundaries_flush,Error ** errp)50932cad1ffSPhilippe Mathieu-Daudé void qmp_block_latency_histogram_set(
51032cad1ffSPhilippe Mathieu-Daudé const char *id,
51132cad1ffSPhilippe Mathieu-Daudé bool has_boundaries, uint64List *boundaries,
51232cad1ffSPhilippe Mathieu-Daudé bool has_boundaries_read, uint64List *boundaries_read,
51332cad1ffSPhilippe Mathieu-Daudé bool has_boundaries_write, uint64List *boundaries_write,
51432cad1ffSPhilippe Mathieu-Daudé bool has_boundaries_append, uint64List *boundaries_append,
51532cad1ffSPhilippe Mathieu-Daudé bool has_boundaries_flush, uint64List *boundaries_flush,
51632cad1ffSPhilippe Mathieu-Daudé Error **errp)
51732cad1ffSPhilippe Mathieu-Daudé {
51832cad1ffSPhilippe Mathieu-Daudé BlockBackend *blk = qmp_get_blk(NULL, id, errp);
51932cad1ffSPhilippe Mathieu-Daudé BlockAcctStats *stats;
52032cad1ffSPhilippe Mathieu-Daudé int ret;
52132cad1ffSPhilippe Mathieu-Daudé
52232cad1ffSPhilippe Mathieu-Daudé if (!blk) {
52332cad1ffSPhilippe Mathieu-Daudé return;
52432cad1ffSPhilippe Mathieu-Daudé }
52532cad1ffSPhilippe Mathieu-Daudé
52632cad1ffSPhilippe Mathieu-Daudé stats = blk_get_stats(blk);
52732cad1ffSPhilippe Mathieu-Daudé
52832cad1ffSPhilippe Mathieu-Daudé if (!has_boundaries && !has_boundaries_read && !has_boundaries_write &&
52932cad1ffSPhilippe Mathieu-Daudé !has_boundaries_flush)
53032cad1ffSPhilippe Mathieu-Daudé {
53132cad1ffSPhilippe Mathieu-Daudé block_latency_histograms_clear(stats);
53232cad1ffSPhilippe Mathieu-Daudé return;
53332cad1ffSPhilippe Mathieu-Daudé }
53432cad1ffSPhilippe Mathieu-Daudé
53532cad1ffSPhilippe Mathieu-Daudé if (has_boundaries || has_boundaries_read) {
53632cad1ffSPhilippe Mathieu-Daudé ret = block_latency_histogram_set(
53732cad1ffSPhilippe Mathieu-Daudé stats, BLOCK_ACCT_READ,
53832cad1ffSPhilippe Mathieu-Daudé has_boundaries_read ? boundaries_read : boundaries);
53932cad1ffSPhilippe Mathieu-Daudé if (ret) {
54032cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device '%s' set read boundaries fail", id);
54132cad1ffSPhilippe Mathieu-Daudé return;
54232cad1ffSPhilippe Mathieu-Daudé }
54332cad1ffSPhilippe Mathieu-Daudé }
54432cad1ffSPhilippe Mathieu-Daudé
54532cad1ffSPhilippe Mathieu-Daudé if (has_boundaries || has_boundaries_write) {
54632cad1ffSPhilippe Mathieu-Daudé ret = block_latency_histogram_set(
54732cad1ffSPhilippe Mathieu-Daudé stats, BLOCK_ACCT_WRITE,
54832cad1ffSPhilippe Mathieu-Daudé has_boundaries_write ? boundaries_write : boundaries);
54932cad1ffSPhilippe Mathieu-Daudé if (ret) {
55032cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device '%s' set write boundaries fail", id);
55132cad1ffSPhilippe Mathieu-Daudé return;
55232cad1ffSPhilippe Mathieu-Daudé }
55332cad1ffSPhilippe Mathieu-Daudé }
55432cad1ffSPhilippe Mathieu-Daudé
55532cad1ffSPhilippe Mathieu-Daudé if (has_boundaries || has_boundaries_append) {
55632cad1ffSPhilippe Mathieu-Daudé ret = block_latency_histogram_set(
55732cad1ffSPhilippe Mathieu-Daudé stats, BLOCK_ACCT_ZONE_APPEND,
55832cad1ffSPhilippe Mathieu-Daudé has_boundaries_append ? boundaries_append : boundaries);
55932cad1ffSPhilippe Mathieu-Daudé if (ret) {
56032cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device '%s' set append write boundaries fail", id);
56132cad1ffSPhilippe Mathieu-Daudé return;
56232cad1ffSPhilippe Mathieu-Daudé }
56332cad1ffSPhilippe Mathieu-Daudé }
56432cad1ffSPhilippe Mathieu-Daudé
56532cad1ffSPhilippe Mathieu-Daudé if (has_boundaries || has_boundaries_flush) {
56632cad1ffSPhilippe Mathieu-Daudé ret = block_latency_histogram_set(
56732cad1ffSPhilippe Mathieu-Daudé stats, BLOCK_ACCT_FLUSH,
56832cad1ffSPhilippe Mathieu-Daudé has_boundaries_flush ? boundaries_flush : boundaries);
56932cad1ffSPhilippe Mathieu-Daudé if (ret) {
57032cad1ffSPhilippe Mathieu-Daudé error_setg(errp, "Device '%s' set flush boundaries fail", id);
57132cad1ffSPhilippe Mathieu-Daudé return;
57232cad1ffSPhilippe Mathieu-Daudé }
57332cad1ffSPhilippe Mathieu-Daudé }
57432cad1ffSPhilippe Mathieu-Daudé }
575