From nobody Thu Nov 13 13:36:12 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.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; dkim=fail; spf=pass (zohomail.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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 158040576066250.31440099867268; Thu, 30 Jan 2020 09:36:00 -0800 (PST) Received: from localhost ([::1]:36878 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ixDjT-0000EP-HB for importer@patchew.org; Thu, 30 Jan 2020 12:35:59 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:47227) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ixDdn-000873-Fm for qemu-devel@nongnu.org; Thu, 30 Jan 2020 12:30:09 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ixDdl-0000Yj-01 for qemu-devel@nongnu.org; Thu, 30 Jan 2020 12:30:07 -0500 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:45233 helo=us-smtp-delivery-1.mimecast.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ixDdk-0000Wn-Rn for qemu-devel@nongnu.org; Thu, 30 Jan 2020 12:30:04 -0500 Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-184-zk6YZy_SMfG7kJgisCOxag-1; Thu, 30 Jan 2020 12:30:00 -0500 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 mimecast-mx01.redhat.com (Postfix) with ESMTPS id 989EF107ACCD; Thu, 30 Jan 2020 17:29:59 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.78]) by smtp.corp.redhat.com (Postfix) with ESMTP id 651955D9E5; Thu, 30 Jan 2020 17:29:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1580405404; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aisj+mR7VgKL4Znpf1cP/KJ/RiE/Cey1r7bpgUsaqc4=; b=IMA0dwQe0yQPgGDa/IDj1C/jHJT/5YCqedhXtTOW9fpJK8hftVgdXeBQ35gOpLYaDd96dp 8Cf9Acd7Sr3tSrB3IwY9I8Y0zLbc5BttpuLiL/L8/L+kp6drmSGtVbursZJYs2u1WUhqVj bMvXbp/NuKqvVFkTn8u3ax9SIfo1dNA= From: Maxim Levitsky To: qemu-devel@nongnu.org Subject: [PATCH v2 11/14] block/core: add generic infrastructure for x-blockdev-amend qmp command Date: Thu, 30 Jan 2020 19:29:16 +0200 Message-Id: <20200130172919.13424-12-mlevitsk@redhat.com> In-Reply-To: <20200130172919.13424-1-mlevitsk@redhat.com> References: <20200130172919.13424-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-MC-Unique: zk6YZy_SMfG7kJgisCOxag-1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 205.139.110.61 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, John Snow , Markus Armbruster , Max Reitz , Maxim Levitsky Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" blockdev-amend will be used similiar to blockdev-create to allow on the fly changes of the structure of the format based block devi= ces. Current plan is to first support encryption keyslot management for luks based formats (raw and embedded in qcow2) Signed-off-by: Maxim Levitsky --- block/Makefile.objs | 2 +- block/amend.c | 108 ++++++++++++++++++++++++++++++++++++++ include/block/block_int.h | 21 +++++--- qapi/block-core.json | 42 +++++++++++++++ qapi/job.json | 4 +- 5 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 block/amend.c diff --git a/block/Makefile.objs b/block/Makefile.objs index 330529b0b7..eb5ddb7158 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..2db7b1eafc --- /dev/null +++ b/block/amend.c @@ -0,0 +1,108 @@ +/* + * 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; + BlockdevAmendOptions *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_BlockdevAmendOptions(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, + BlockdevAmendOptions *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 */ + s =3D job_create(job_id, &blockdev_amend_job_driver, NULL, + bdrv_get_aio_context(bs), JOB_DEFAULT | JOB_MANUAL_DISM= ISS, + NULL, NULL, errp); + if (!s) { + return; + } + + s->bs =3D bs, + s->opts =3D QAPI_CLONE(BlockdevAmendOptions, 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 6f0abf8544..025d1f298a 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -133,11 +133,26 @@ 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, + BlockdevAmendOptions *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 /* @@ -428,12 +443,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 7ff5e5edaf..601f7dc9a4 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -4743,6 +4743,48 @@ 'data': { 'job-id': 'str', 'options': 'BlockdevCreateOptions' } } =20 +## +# @BlockdevAmendOptions: +# +# Options for amending an image format +# +# @driver block driver that is suitable for the image +# +# Since: 5.0 +## +{ 'union': 'BlockdevAmendOptions', + 'base': { + 'driver': 'BlockdevDriver' }, + 'discriminator': 'driver', + 'data': { + } } + +## +# @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 (driver specific) +# +# @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: 5.0 +## +{ 'command': 'x-blockdev-amend', + 'data': { 'job-id': 'str', + 'node-name': 'str', + 'options': 'BlockdevAmendOptions', + '*force': 'bool' } } + ## # @blockdev-open-tray: # diff --git a/qapi/job.json b/qapi/job.json index a121b615fb..362b634ec1 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 5.0) +# # Since: 1.7 ## { 'enum': 'JobType', - 'data': ['commit', 'stream', 'mirror', 'backup', 'create'] } + 'data': ['commit', 'stream', 'mirror', 'backup', 'create', 'amend'] } =20 ## # @JobStatus: --=20 2.17.2