From patchwork Thu Oct 23 14:56:14 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 402552 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 8FDD014009A for ; Fri, 24 Oct 2014 01:56:58 +1100 (AEDT) Received: from localhost ([::1]:40527 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XhJou-0000Om-Hp for incoming@patchwork.ozlabs.org; Thu, 23 Oct 2014 10:56:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48487) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XhJoR-0008Af-7S for qemu-devel@nongnu.org; Thu, 23 Oct 2014 10:56:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XhJoJ-0007Un-UO for qemu-devel@nongnu.org; Thu, 23 Oct 2014 10:56:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:18076) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XhJoJ-0007Uh-N2 for qemu-devel@nongnu.org; Thu, 23 Oct 2014 10:56:19 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s9NEuJBo006760 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Thu, 23 Oct 2014 10:56:19 -0400 Received: from localhost (dhcp-192-247.str.redhat.com [10.33.192.247]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s9NEuHnj028635 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Thu, 23 Oct 2014 10:56:18 -0400 From: Max Reitz To: qemu-devel@nongnu.org Date: Thu, 23 Oct 2014 16:56:14 +0200 Message-Id: <1414076175-17034-2-git-send-email-mreitz@redhat.com> In-Reply-To: <1414076175-17034-1-git-send-email-mreitz@redhat.com> References: <1414076175-17034-1-git-send-email-mreitz@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Kevin Wolf , Stefan Hajnoczi , Max Reitz Subject: [Qemu-devel] [PATCH 1/2] 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 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. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- Just by the way, the reason for using bs->exact_filename in bdrv_get_full_backing_filename() instead of just testing whether bs->filename is prefixed by "json:" is that in the future we might have cases where bs->filename contains a JSON filename, but bs->exact_filename is set to a non-JSON filename (because there are some rather vital options, which radically change performance or something like that, so we want them to be included in bs->filename if they were specified; but we can still generate a plain filename which results in the same data read and written, but just in some very different way or something like that). Actually, I might write a follow-up patch which makes bdrv_refresh_filename() always generate an exact_filename if somehow possible, even if unknown options were specified. This would then be very useful for this function, but on the other hand, it would no longer fit the definition of exact_filename (in order to follow that definition, we have to be certain that we don't omit any vital options which really change the data read and written). --- block.c | 19 +++++++++++++++---- block/qapi.c | 7 ++++++- include/block/block.h | 2 +- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/block.c b/block.c index 88f6d9b..6ccc94b 100644 --- a/block.c +++ b/block.c @@ -303,12 +303,17 @@ void path_combine(char *dest, int dest_size, } } -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) { - if (bs->backing_file[0] == '\0' || path_has_protocol(bs->backing_file)) { + if (bs->backing_file[0] == '\0' || path_has_protocol(bs->backing_file) || + path_is_absolute(bs->backing_file)) { pstrcpy(dest, sz, bs->backing_file); + } else if (!bs->exact_filename[0] || + strstart(bs->exact_filename, "json:", NULL)) { + error_setg(errp, "Cannot use relative backing file names for '%s'", + bs->filename); } else { - path_combine(dest, sz, bs->filename, bs->backing_file); + path_combine(dest, sz, bs->exact_filename, bs->backing_file); } } @@ -1197,7 +1202,13 @@ 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 1301144..77baa36 100644 --- a/block/qapi.c +++ b/block/qapi.c @@ -229,7 +229,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 341054d..3abc7df 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -387,7 +387,7 @@ 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); int bdrv_is_snapshot(BlockDriverState *bs); int path_is_absolute(const char *path);