From nobody Wed Nov 12 01:53:56 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1567199120; cv=none; d=zoho.com; s=zohoarc; b=B1Tr88KjzwJC79LT377im+/u2uG3PFoTm06ecsGISwGVqu9t0xmurJBnkr+kO0SVsyDexwUuDkuszC1lo3/2gD40yWS0qJzgQvCyLpv3LZ4qne1hlWFmCdANs5oY5TOc+d6HV6m8xYoXpczGdLWvvRHkru4fwVL/9AaL9svXPtM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1567199120; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=EJWWyna7nIgY/DjIlmBhG8fvkNuBVVS3sPsFgymdn2U=; b=J8AVovD1hhIx1wM6jNb0ed55KkN/NfXy6BuS8/5zAfdPXgENNe4TzvuBlbONq0s8wKHDS9zwkcOzKBCiwb3X4llCrbDz160cOIenXHtVI52QcexLl21x7i20BGYRM8xrN2lQ1lcg/nnDFM2Baqnu5Stp7MckTKIkYzF4KZBtHC8= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1567199120245224.03124301339687; Fri, 30 Aug 2019 14:05:20 -0700 (PDT) Received: from localhost ([::1]:41142 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i3o59-0001Lt-5j for importer@patchew.org; Fri, 30 Aug 2019 17:05:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47597) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i3nwt-0003O5-V9 for qemu-devel@nongnu.org; Fri, 30 Aug 2019 16:56:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i3nws-0001b2-99 for qemu-devel@nongnu.org; Fri, 30 Aug 2019 16:56:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49800) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i3nwo-0001X4-9N; Fri, 30 Aug 2019 16:56:42 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 96ECE79704; Fri, 30 Aug 2019 20:56:41 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.29]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4D8145D9CA; Fri, 30 Aug 2019 20:56:39 +0000 (UTC) From: Maxim Levitsky To: qemu-devel@nongnu.org Date: Fri, 30 Aug 2019 23:56:05 +0300 Message-Id: <20190830205608.18192-8-mlevitsk@redhat.com> In-Reply-To: <20190830205608.18192-1-mlevitsk@redhat.com> References: <20190830205608.18192-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 30 Aug 2019 20:56:41 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 07/10] block: add x-blockdev-amend qmp command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= , qemu-block@nongnu.org, Markus Armbruster , Max Reitz , Maxim Levitsky , John Snow Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Maxim Levitsky --- block/Makefile.objs | 2 +- block/amend.c | 116 ++++++++++++++++++++++++++++++++++++++ include/block/block_int.h | 23 ++++++-- qapi/block-core.json | 26 +++++++++ qapi/job.json | 4 +- 5 files changed, 163 insertions(+), 8 deletions(-) create mode 100644 block/amend.c diff --git a/block/Makefile.objs b/block/Makefile.objs index 35f3bca4d9..10d0308792 100644 --- a/block/Makefile.objs +++ b/block/Makefile.objs @@ -18,7 +18,7 @@ block-obj-y +=3D block-backend.o snapshot.o qapi.o block-obj-$(CONFIG_WIN32) +=3D file-win32.o win32-aio.o block-obj-$(CONFIG_POSIX) +=3D file-posix.o block-obj-$(CONFIG_LINUX_AIO) +=3D linux-aio.o -block-obj-y +=3D null.o mirror.o commit.o io.o create.o +block-obj-y +=3D null.o mirror.o commit.o io.o create.o amend.o block-obj-y +=3D throttle-groups.o block-obj-$(CONFIG_LINUX) +=3D nvme.o =20 diff --git a/block/amend.c b/block/amend.c new file mode 100644 index 0000000000..9bd28e08e7 --- /dev/null +++ b/block/amend.c @@ -0,0 +1,116 @@ +/* + * Block layer code related to image options amend + * + * Copyright (c) 2018 Kevin Wolf + * Copyright (c) 2019 Maxim Levitsky + * + * Heavily based on create.c + * + * Permission is hereby granted, free of charge, to any person obtaining a= copy + * of this software and associated documentation files (the "Software"), t= o deal + * in the Software without restriction, including without limitation the r= ights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or se= ll + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included= in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS= OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OT= HER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING= FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS = IN + * THE SOFTWARE. + */ + +#include "qemu/osdep.h" +#include "block/block_int.h" +#include "qemu/job.h" +#include "qemu/main-loop.h" +#include "qapi/qapi-commands-block-core.h" +#include "qapi/qapi-visit-block-core.h" +#include "qapi/clone-visitor.h" +#include "qapi/error.h" + +typedef struct BlockdevAmendJob { + Job common; + BlockdevCreateOptions *opts; + BlockDriverState *bs; + bool force; +} BlockdevAmendJob; + +static int coroutine_fn blockdev_amend_run(Job *job, Error **errp) +{ + BlockdevAmendJob *s =3D container_of(job, BlockdevAmendJob, common); + int ret; + + job_progress_set_remaining(&s->common, 1); + ret =3D s->bs->drv->bdrv_co_amend(s->bs, s->opts, s->force, errp); + job_progress_update(&s->common, 1); + + qapi_free_BlockdevCreateOptions(s->opts); + + return ret; +} + +static const JobDriver blockdev_amend_job_driver =3D { + .instance_size =3D sizeof(BlockdevAmendJob), + .job_type =3D JOB_TYPE_AMEND, + .run =3D blockdev_amend_run, +}; + +void qmp_x_blockdev_amend(const char *job_id, + const char *node_name, + BlockdevCreateOptions *options, + bool has_force, + bool force, + Error **errp) +{ + BlockdevAmendJob *s; + const char *fmt =3D BlockdevDriver_str(options->driver); + BlockDriver *drv =3D bdrv_find_format(fmt); + BlockDriverState *bs =3D bdrv_find_node(node_name); + + /* + * If the driver is in the schema, we know that it exists. But it may = not + * be whitelisted. + */ + assert(drv); + if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) { + error_setg(errp, "Driver is not whitelisted"); + return; + } + + if (bs->drv !=3D drv) { + error_setg(errp, + "x-blockdev-amend doesn't support changing the block dr= iver"); + return; + + } + + /* Error out if the driver doesn't support .bdrv_co_amend */ + if (!drv->bdrv_co_amend) { + error_setg(errp, "Driver does not support x-blockdev-amend"); + return; + } + + /* + * Create the block job + * TODO Running in the main context. Block drivers need to error out o= r add + * locking when they use a BDS in a different AioContext. + */ + s =3D job_create(job_id, &blockdev_amend_job_driver, NULL, + qemu_get_aio_context(), JOB_DEFAULT | JOB_MANUAL_DISMIS= S, + NULL, NULL, errp); + if (!s) { + return; + } + + s->bs =3D bs, + s->opts =3D QAPI_CLONE(BlockdevCreateOptions, options), + s->force =3D has_force ? force : false; + + job_start(&s->common); +} diff --git a/include/block/block_int.h b/include/block/block_int.h index c6aa05214f..546c84957c 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -133,11 +133,28 @@ struct BlockDriver { int (*bdrv_file_open)(BlockDriverState *bs, QDict *options, int flags, Error **errp); void (*bdrv_close)(BlockDriverState *bs); + + int coroutine_fn (*bdrv_co_create)(BlockdevCreateOptions *opts, Error **errp); int coroutine_fn (*bdrv_co_create_opts)(const char *filename, QemuOpts *opts, Error **errp); + + + int coroutine_fn (*bdrv_co_amend)(BlockDriverState *bs, + BlockdevCreateOptions *opts, + bool force, + Error **errp); + + int (*bdrv_amend_options)(BlockDriverState *bs, + QemuOpts *opts, + BlockDriverAmendStatusCB *status_cb, + void *cb_opaque, + bool force, + Error **errp); + + int (*bdrv_make_empty)(BlockDriverState *bs); =20 /* @@ -399,12 +416,6 @@ struct BlockDriver { BdrvCheckResult *result, BdrvCheckMode fix); =20 - int (*bdrv_amend_options)(BlockDriverState *bs, QemuOpts *opts, - BlockDriverAmendStatusCB *status_cb, - void *cb_opaque, - bool force, - Error **errp); - void (*bdrv_debug_event)(BlockDriverState *bs, BlkdebugEvent event); =20 /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */ diff --git a/qapi/block-core.json b/qapi/block-core.json index e6edd641f1..7900914506 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -4650,6 +4650,32 @@ 'data': { 'job-id': 'str', 'options': 'BlockdevCreateOptions' } } =20 +## +# @x-blockdev-amend: +# +# Starts a job to amend format specific options of an existing open block = device. +# The job is automatically finalized, but a manual job-dismiss is required. +# +# @job-id: Identifier for the newly created job. +# +# @node-name: Name of the block node to work on +# +# @options: Options (same as for image creation) +# +# @force: Allow unsafe operations, format specific +# For luks that allows erase of the last active keyslot +# (permanent loss of data), +# and replacement of an active keyslot +# (possible loss of data if IO error happens) +# +# Since: 4.2 +## +{ 'command': 'x-blockdev-amend', + 'data': { 'job-id': 'str', + 'node-name': 'str', + 'options': 'BlockdevCreateOptions', + '*force': 'bool' } } + ## # @blockdev-open-tray: # diff --git a/qapi/job.json b/qapi/job.json index a121b615fb..342d29a7aa 100644 --- a/qapi/job.json +++ b/qapi/job.json @@ -19,10 +19,12 @@ # # @create: image creation job type, see "blockdev-create" (since 3.0) # +# @amend: image options amend job type, see "x-blockdev-amend" (since 4.2) +# # Since: 1.7 ## { 'enum': 'JobType', - 'data': ['commit', 'stream', 'mirror', 'backup', 'create'] } + 'data': ['commit', 'stream', 'mirror', 'backup', 'create', 'amend'] } =20 ## # @JobStatus: --=20 2.17.2