From patchwork Mon Jan 26 16:03:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 432920 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C6DB9140192 for ; Tue, 27 Jan 2015 03:29:38 +1100 (AEDT) Received: from localhost ([::1]:42711 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YFmXg-0002q6-UP for incoming@patchwork.ozlabs.org; Mon, 26 Jan 2015 11:29:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53040) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YFm97-0006Ua-Nl for qemu-devel@nongnu.org; Mon, 26 Jan 2015 11:04:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YFm96-0005Lj-9m for qemu-devel@nongnu.org; Mon, 26 Jan 2015 11:04:13 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47193) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YFm96-0005LR-33 for qemu-devel@nongnu.org; Mon, 26 Jan 2015 11:04:12 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t0QG4BJs028650 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Mon, 26 Jan 2015 11:04:11 -0500 Received: from localhost ([10.18.17.71]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t0QG4AJl020574 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Mon, 26 Jan 2015 11:04:11 -0500 From: Max Reitz To: qemu-devel@nongnu.org Date: Mon, 26 Jan 2015 11:03:17 -0500 Message-Id: <1422288204-29271-44-git-send-email-mreitz@redhat.com> In-Reply-To: <1422288204-29271-1-git-send-email-mreitz@redhat.com> References: <1422288204-29271-1-git-send-email-mreitz@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Kevin Wolf , Fam Zheng , Jeff Cody , Markus Armbruster , Max Reitz , Stefan Hajnoczi , john@redhat.com Subject: [Qemu-devel] [PATCH 43/50] blockdev: Implement change with basic operations X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Implement 'change' on block devices by calling blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium (a variation of that which does not need a node-name) and blockdev-close-tray. Signed-off-by: Max Reitz --- blockdev.c | 191 +++++++++++++++++++++++-------------------------------------- 1 file changed, 72 insertions(+), 119 deletions(-) diff --git a/blockdev.c b/blockdev.c index 0b204eb..6e440b8 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1828,41 +1828,6 @@ exit: } } - -static void eject_device(BlockBackend *blk, int force, Error **errp) -{ - BlockDriverState *bs = blk_bs(blk); - AioContext *aio_context; - - aio_context = blk_get_aio_context(blk); - aio_context_acquire(aio_context); - - if (bs && bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) { - goto out; - } - if (!blk_dev_has_removable_media(blk)) { - error_setg(errp, "Device '%s' is not removable", - bdrv_get_device_name(bs)); - goto out; - } - - if (blk_dev_is_medium_locked(blk) && !blk_dev_is_tray_open(blk)) { - blk_dev_eject_request(blk, force); - if (!force) { - error_setg(errp, "Device '%s' is locked", - bdrv_get_device_name(bs)); - goto out; - } - } - - if (bs) { - bdrv_close(bs); - } - -out: - aio_context_release(aio_context); -} - void qmp_eject(const char *device, bool has_force, bool force, Error **errp) { Error *local_err = NULL; @@ -1909,90 +1874,6 @@ out: aio_context_release(aio_context); } -/* Assumes AioContext is held */ -static void qmp_bdrv_open_encrypted(BlockDriverState **pbs, - const char *filename, - int bdrv_flags, BlockDriver *drv, - const char *password, Error **errp) -{ - BlockDriverState *bs; - Error *local_err = NULL; - int ret; - - ret = bdrv_open(pbs, filename, NULL, NULL, bdrv_flags, drv, &local_err); - if (ret < 0) { - error_propagate(errp, local_err); - return; - } - bs = *pbs; - - if (bdrv_key_required(bs)) { - if (password) { - if (bdrv_set_key(bs, password) < 0) { - error_set(errp, QERR_INVALID_PASSWORD); - } - } else { - error_set(errp, QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs), - bdrv_get_encrypted_filename(bs)); - } - } else if (password) { - error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs)); - } -} - -void qmp_change_blockdev(const char *device, const char *filename, - const char *format, Error **errp) -{ - BlockBackend *blk; - BlockDriverState *bs; - AioContext *aio_context; - BlockDriver *drv = NULL; - int bdrv_flags; - bool new_bs; - Error *err = NULL; - - blk = blk_by_name(device); - if (!blk) { - error_set(errp, QERR_DEVICE_NOT_FOUND, device); - return; - } - bs = blk_bs(blk); - new_bs = !bs; - - aio_context = blk_get_aio_context(blk); - aio_context_acquire(aio_context); - - if (format) { - drv = bdrv_find_whitelisted_format(format, blk_is_read_only(blk)); - if (!drv) { - error_set(errp, QERR_INVALID_BLOCK_FORMAT, format); - goto out; - } - } - - eject_device(blk, 0, &err); - if (err) { - error_propagate(errp, err); - goto out; - } - - bdrv_flags = blk_is_read_only(blk) ? 0 : BDRV_O_RDWR; - bdrv_flags |= blk_get_root_state(blk)->open_flags & ~BDRV_O_RDWR; - - qmp_bdrv_open_encrypted(&bs, filename, bdrv_flags, drv, NULL, &err); - if (err) { - error_propagate(errp, err); - } else if (new_bs) { - blk_insert_bs(blk, bs); - /* Has been sent automatically by bdrv_open() if blk_bs(blk) was not - * NULL */ - blk_dev_change_media_cb(blk, true); - } - -out: - aio_context_release(aio_context); -} - void qmp_blockdev_open_tray(const char *device, bool has_force, bool force, Error **errp) { @@ -2131,6 +2012,78 @@ void qmp_blockdev_insert_medium(const char *device, const char *node_name, qmp_blockdev_insert_anon_medium(device, bs, errp); } +void qmp_change_blockdev(const char *device, const char *filename, + const char *format, Error **errp) +{ + BlockBackend *blk; + BlockBackendRootState *blk_rs; + BlockDriverState *medium_bs; + BlockDriver *drv = NULL; + int bdrv_flags, ret; + Error *err = NULL; + + blk = blk_by_name(device); + if (!blk) { + error_set(errp, QERR_DEVICE_NOT_FOUND, device); + return; + } + + if (blk_bs(blk)) { + blk_update_root_state(blk); + } + + blk_rs = blk_get_root_state(blk); + bdrv_flags = blk_rs->read_only ? 0 : BDRV_O_RDWR; + bdrv_flags |= blk_rs->open_flags & ~BDRV_O_RDWR; + + if (format) { + drv = bdrv_find_whitelisted_format(format, bdrv_flags & BDRV_O_RDWR); + if (!drv) { + error_set(errp, QERR_INVALID_BLOCK_FORMAT, format); + return; + } + } + + medium_bs = NULL; + ret = bdrv_open(&medium_bs, filename, NULL, NULL, bdrv_flags, drv, errp); + if (ret < 0) { + return; + } + + medium_bs->detect_zeroes = blk_rs->detect_zeroes; + if (blk_rs->io_limits_enabled) { + bdrv_io_limits_enable(medium_bs); + bdrv_set_io_limits(medium_bs, &blk_rs->throttle_config); + } + + if (bdrv_key_required(medium_bs)) { + error_set(errp, QERR_DEVICE_ENCRYPTED, device, + bdrv_get_encrypted_filename(medium_bs)); + bdrv_unref(medium_bs); + return; + } + + qmp_blockdev_open_tray(device, false, false, &err); + if (err) { + error_propagate(errp, err); + return; + } + + qmp_blockdev_remove_medium(device, &err); + if (err) { + error_propagate(errp, err); + return; + } + + qmp_blockdev_insert_anon_medium(device, medium_bs, &err); + if (err) { + error_propagate(errp, err); + return; + } + + qmp_blockdev_close_tray(device, errp); +} + /* throttling disk I/O limits */ void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd, int64_t bps_wr,