From patchwork Mon Jan 12 16:39:58 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Hajnoczi X-Patchwork-Id: 427872 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 331591401DC for ; Tue, 13 Jan 2015 04:40:59 +1100 (AEDT) Received: from localhost ([::1]:35732 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YAiz3-0007iK-5W for incoming@patchwork.ozlabs.org; Mon, 12 Jan 2015 12:40:57 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49669) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YAivU-0002Bg-U8 for qemu-devel@nongnu.org; Mon, 12 Jan 2015 12:37:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YAivO-0005fN-7y for qemu-devel@nongnu.org; Mon, 12 Jan 2015 12:37:16 -0500 Received: from mx1.redhat.com ([209.132.183.28]:37911) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YAivO-0005ex-1F for qemu-devel@nongnu.org; Mon, 12 Jan 2015 12:37:10 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t0CGeqnZ010551 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 12 Jan 2015 11:40:52 -0500 Received: from localhost (ovpn-112-78.ams2.redhat.com [10.36.112.78]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t0CGep4B031987; Mon, 12 Jan 2015 11:40:51 -0500 From: Stefan Hajnoczi To: Date: Mon, 12 Jan 2015 16:39:58 +0000 Message-Id: <1421080834-14724-9-git-send-email-stefanha@redhat.com> In-Reply-To: <1421080834-14724-1-git-send-email-stefanha@redhat.com> References: <1421080834-14724-1-git-send-email-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Kevin Wolf , Peter Maydell , Max Reitz Subject: [Qemu-devel] [PULL v2 08/44] block: JSON filenames and relative backing files 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 From: Max Reitz When using a relative backing file name, qemu needs to know the directory of the top image file. For JSON filenames, such a directory cannot be easily determined (e.g. how do you determine the directory of a qcow2 BDS directly on top of a quorum BDS?). Therefore, do not allow relative filenames for the backing file of BDSs only having a JSON filename. Furthermore, BDS::exact_filename should be used whenever possible. If BDS::filename is not equal to BDS::exact_filename, the former will always be a JSON object. Signed-off-by: Max Reitz Signed-off-by: Kevin Wolf --- block.c | 28 ++++++++++++++++++++++------ block/qapi.c | 7 ++++++- include/block/block.h | 5 +++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/block.c b/block.c index 86f2faa..cf0867c 100644 --- a/block.c +++ b/block.c @@ -305,19 +305,28 @@ void path_combine(char *dest, int dest_size, void bdrv_get_full_backing_filename_from_filename(const char *backed, const char *backing, - char *dest, size_t sz) + char *dest, size_t sz, + Error **errp) { - if (backing[0] == '\0' || path_has_protocol(backing)) { + if (backing[0] == '\0' || path_has_protocol(backing) || + path_is_absolute(backing)) + { pstrcpy(dest, sz, backing); + } else if (backed[0] == '\0' || strstart(backed, "json:", NULL)) { + error_setg(errp, "Cannot use relative backing file names for '%s'", + backed); } else { path_combine(dest, sz, backed, backing); } } -void bdrv_get_full_backing_filename(BlockDriverState *bs, char *dest, size_t sz) +void bdrv_get_full_backing_filename(BlockDriverState *bs, char *dest, size_t sz, + Error **errp) { - bdrv_get_full_backing_filename_from_filename(bs->filename, bs->backing_file, - dest, sz); + char *backed = bs->exact_filename[0] ? bs->exact_filename : bs->filename; + + bdrv_get_full_backing_filename_from_filename(backed, bs->backing_file, + dest, sz, errp); } void bdrv_register(BlockDriver *bdrv) @@ -1225,7 +1234,14 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) QDECREF(options); goto free_exit; } else { - bdrv_get_full_backing_filename(bs, backing_filename, PATH_MAX); + bdrv_get_full_backing_filename(bs, backing_filename, PATH_MAX, + &local_err); + if (local_err) { + ret = -EINVAL; + error_propagate(errp, local_err); + QDECREF(options); + goto free_exit; + } } if (!bs->drv || !bs->drv->supports_backing) { diff --git a/block/qapi.c b/block/qapi.c index fa68ba7..a6fd6f7 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -214,7 +214,12 @@ void bdrv_query_image_info(BlockDriverState *bs, info->backing_filename = g_strdup(backing_filename); info->has_backing_filename = true; bdrv_get_full_backing_filename(bs, backing_filename2, - sizeof(backing_filename2)); + sizeof(backing_filename2), &err); + if (err) { + error_propagate(errp, err); + qapi_free_ImageInfo(info); + return; + } if (strcmp(backing_filename, backing_filename2) != 0) { info->full_backing_filename = diff --git a/include/block/block.h b/include/block/block.h index eac9bb0..9efaa80 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -396,10 +396,11 @@ const char *bdrv_get_encrypted_filename(BlockDriverState *bs); void bdrv_get_backing_filename(BlockDriverState *bs, char *filename, int filename_size); void bdrv_get_full_backing_filename(BlockDriverState *bs, - char *dest, size_t sz); + char *dest, size_t sz, Error **errp); void bdrv_get_full_backing_filename_from_filename(const char *backed, const char *backing, - char *dest, size_t sz); + char *dest, size_t sz, + Error **errp); int bdrv_is_snapshot(BlockDriverState *bs); int path_has_protocol(const char *path);