From nobody Sun May 19 23:34:09 2024 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=1570807853; cv=none; d=zoho.com; s=zohoarc; b=I/Rb5P+n9SAqI6PmTBDI/a7jpnM9DLX2+Og4RzA9wDHBKS8ZbsAtdjsLw6T90otR/+YGdJw+8gqvMOHghpsTtce09nwrFDWE/uA6DsjBeEZs8VL3BzDzHeqlVoIurkvn9W14WORfglavz/+kKJXrysJZVpfTnoNqBZFxSuhicpk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570807853; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=tl4qBlapXEYIsWM17iUAXjpeek/MfVRrB/c8IJRwGuo=; b=iYqqHvTzqwCvqs/0YrqE8sdhlZ6oit0D1YbArs8I6CYMSlXWeVhhR1GpQ5KldqiWJYAlZTd0KASvVVmI/gNh3mYqKoCUHpeTK7TYrt/9097Bb0WAHftDYjpMTF1g2T/XEasUzG0KZ0tTc2amEHLNntW692TXy8ks8Ruf7WwmICg= 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 1570807853929934.1272593749541; Fri, 11 Oct 2019 08:30:53 -0700 (PDT) Received: from localhost ([::1]:52206 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwsW-0003B7-1I for importer@patchew.org; Fri, 11 Oct 2019 11:30:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57640) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwq9-0001BD-3O for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwq7-0006N0-Tr for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:24 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59382) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwq5-0006Kd-EQ; Fri, 11 Oct 2019 11:28:21 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A964C10B78; Fri, 11 Oct 2019 15:28:20 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1480E4535; Fri, 11 Oct 2019 15:28:19 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 01/16] include: Move endof() up from hw/virtio/virtio.h Date: Fri, 11 Oct 2019 17:27:59 +0200 Message-Id: <20191011152814.14791-2-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 11 Oct 2019 15:28:20 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" endof() is a useful macro, we can make use of it outside of virtio. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- include/hw/virtio/virtio.h | 7 ------- include/qemu/compiler.h | 7 +++++++ hw/block/virtio-blk.c | 4 ++-- hw/net/virtio-net.c | 10 +++++----- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h index 48e8d04ff6..ef083af550 100644 --- a/include/hw/virtio/virtio.h +++ b/include/hw/virtio/virtio.h @@ -37,13 +37,6 @@ static inline hwaddr vring_align(hwaddr addr, return QEMU_ALIGN_UP(addr, align); } =20 -/* - * Calculate the number of bytes up to and including the given 'field' of - * 'container'. - */ -#define virtio_endof(container, field) \ - (offsetof(container, field) + sizeof_field(container, field)) - typedef struct VirtIOFeature { uint64_t flags; size_t end; diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h index 7b93c73340..85c02c16d3 100644 --- a/include/qemu/compiler.h +++ b/include/qemu/compiler.h @@ -60,6 +60,13 @@ =20 #define sizeof_field(type, field) sizeof(((type *)0)->field) =20 +/* + * Calculate the number of bytes up to and including the given 'field' of + * 'container'. + */ +#define endof(container, field) \ + (offsetof(container, field) + sizeof_field(container, field)) + /* Convert from a base type to a parent type, with compile time checking. = */ #ifdef __GNUC__ #define DO_UPCAST(type, field, dev) ( __extension__ ( { \ diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index ed2ddebd2b..ac857edc73 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -42,9 +42,9 @@ */ static VirtIOFeature feature_sizes[] =3D { {.flags =3D 1ULL << VIRTIO_BLK_F_DISCARD, - .end =3D virtio_endof(struct virtio_blk_config, discard_sector_alignm= ent)}, + .end =3D endof(struct virtio_blk_config, discard_sector_alignment)}, {.flags =3D 1ULL << VIRTIO_BLK_F_WRITE_ZEROES, - .end =3D virtio_endof(struct virtio_blk_config, write_zeroes_may_unma= p)}, + .end =3D endof(struct virtio_blk_config, write_zeroes_may_unmap)}, {} }; =20 diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 9f11422337..2c4909c5f9 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -90,15 +90,15 @@ static inline __virtio16 *virtio_net_rsc_ext_num_dupack= s( =20 static VirtIOFeature feature_sizes[] =3D { {.flags =3D 1ULL << VIRTIO_NET_F_MAC, - .end =3D virtio_endof(struct virtio_net_config, mac)}, + .end =3D endof(struct virtio_net_config, mac)}, {.flags =3D 1ULL << VIRTIO_NET_F_STATUS, - .end =3D virtio_endof(struct virtio_net_config, status)}, + .end =3D endof(struct virtio_net_config, status)}, {.flags =3D 1ULL << VIRTIO_NET_F_MQ, - .end =3D virtio_endof(struct virtio_net_config, max_virtqueue_pairs)}, + .end =3D endof(struct virtio_net_config, max_virtqueue_pairs)}, {.flags =3D 1ULL << VIRTIO_NET_F_MTU, - .end =3D virtio_endof(struct virtio_net_config, mtu)}, + .end =3D endof(struct virtio_net_config, mtu)}, {.flags =3D 1ULL << VIRTIO_NET_F_SPEED_DUPLEX, - .end =3D virtio_endof(struct virtio_net_config, duplex)}, + .end =3D endof(struct virtio_net_config, duplex)}, {} }; =20 --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570807862; cv=none; d=zoho.com; s=zohoarc; b=QZNNe797TTFzlLlUeR63gfno9E5WebEfLXIpXsj7jDuxxyLHpy6qV7JJmVuT4er3MIIooVmsqfZRTgnNNGs4GSJPBPvg/YkBol4Xr9I+xRljPA56u6O/QmWuku66KW9QZojMKN6aq6Ga6DxyN8gLcwTt1qA7zbs2LrpOTSqei+8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570807862; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=rdpfZ+Y38TQhd4xmQMeFvA12Qaer2DufYyVhRcXYCq0=; b=CuEfH91T+rDvBZ2hOam/l2rgSvsDG92U396HCwWGZXJgP7PULdobbPaFVGOxVGkJS1XL4ek0qse6JutQVYVdo90XMVo8JHfrrIf7ZpfDTuL4VQWshtfUpWCMTmkpztCrmzpHWhK6JNibz7O3O8As6HXPm8Qu2JoJV8iqAbFEXwE= 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 1570807862365334.2083522260556; Fri, 11 Oct 2019 08:31:02 -0700 (PDT) Received: from localhost ([::1]:52210 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwsc-0003MT-T7 for importer@patchew.org; Fri, 11 Oct 2019 11:30:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57672) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqB-0001GI-IQ for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqA-0006Pv-IM for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:27 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53134) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwq8-0006Mx-FQ; Fri, 11 Oct 2019 11:28:24 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B4D3B3090FDD; Fri, 11 Oct 2019 15:28:23 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2BDD3600C4; Fri, 11 Oct 2019 15:28:22 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 02/16] qcow2: Use endof() Date: Fri, 11 Oct 2019 17:28:00 +0200 Message-Id: <20191011152814.14791-3-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 11 Oct 2019 15:28:23 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2-snapshot.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index d0e7fa9311..752883e5c3 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -92,11 +92,12 @@ int qcow2_read_snapshots(BlockDriverState *bs) } offset +=3D extra_data_size; =20 - if (extra_data_size >=3D 8) { + if (extra_data_size >=3D endof(QCowSnapshotExtraData, + vm_state_size_large)) { sn->vm_state_size =3D be64_to_cpu(extra.vm_state_size_large); } =20 - if (extra_data_size >=3D 16) { + if (extra_data_size >=3D endof(QCowSnapshotExtraData, disk_size)) { sn->disk_size =3D be64_to_cpu(extra.disk_size); } else { sn->disk_size =3D bs->total_sectors * BDRV_SECTOR_SIZE; @@ -251,7 +252,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs) } =20 QEMU_BUILD_BUG_ON(offsetof(QCowHeader, snapshots_offset) !=3D - offsetof(QCowHeader, nb_snapshots) + sizeof(header_data.nb_snapsho= ts)); + endof(QCowHeader, nb_snapshots)); =20 header_data.nb_snapshots =3D cpu_to_be32(s->nb_snapshots); header_data.snapshots_offset =3D cpu_to_be64(snapshots_offset); --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570807895; cv=none; d=zoho.com; s=zohoarc; b=gM6Wk0hFdRz4Gh/VxLYu308AEv5T3SD/8tioqa1x9dmbXXlTBDuil358E0NjzZxgQ7dGa+h/F0Yg0V181wDOQRo4PCzbyCi334FFjovFka5AE1R5qXTpuD8FCNXzPFFpcg2/31klo52kdGK/woi5ytdEvdONA0cPwteCa6zn+NM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570807895; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=kWqBW7qsSmVX7+AcytBZZlBJOpdnZXGpV9l7gjBYw8w=; b=EPWLgC/mQ3RQkW3LVSxBpRivZzDB5QkvmIB6/il/31uWAaXO3/56rJDtxpC3JwVwJCQclDZtyQy6y3fajvmtya6j15XiAVu7jFMhEkANQj0wqz9N7hrzEd7xddS61iALmJvjc8t5SdF7EP97DLLKJgpuHHDymXxgCJ5Y+QgxVgc= 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 1570807895642543.6589229414014; Fri, 11 Oct 2019 08:31:35 -0700 (PDT) Received: from localhost ([::1]:52218 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwtC-0003pO-1E for importer@patchew.org; Fri, 11 Oct 2019 11:31:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57708) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqG-0001P4-O9 for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqF-0006Rx-JE for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:32 -0400 Received: from mx1.redhat.com ([209.132.183.28]:45254) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqB-0006QE-Ka; Fri, 11 Oct 2019 11:28:27 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C64627575F; Fri, 11 Oct 2019 15:28:26 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 38EE660872; Fri, 11 Oct 2019 15:28:26 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 03/16] qcow2: Add Error ** to qcow2_read_snapshots() Date: Fri, 11 Oct 2019 17:28:01 +0200 Message-Id: <20191011152814.14791-4-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Fri, 11 Oct 2019 15:28:26 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2.h | 2 +- block/qcow2-snapshot.c | 7 ++++++- block/qcow2.c | 3 +-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/block/qcow2.h b/block/qcow2.h index f51f478e34..8da1ad11d9 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -708,7 +708,7 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, Error **errp); =20 void qcow2_free_snapshots(BlockDriverState *bs); -int qcow2_read_snapshots(BlockDriverState *bs); +int qcow2_read_snapshots(BlockDriverState *bs, Error **errp); =20 /* qcow2-cache.c functions */ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables, diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 752883e5c3..80d32e4504 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -43,7 +43,7 @@ void qcow2_free_snapshots(BlockDriverState *bs) s->nb_snapshots =3D 0; } =20 -int qcow2_read_snapshots(BlockDriverState *bs) +int qcow2_read_snapshots(BlockDriverState *bs, Error **errp) { BDRVQcow2State *s =3D bs->opaque; QCowSnapshotHeader h; @@ -68,6 +68,7 @@ int qcow2_read_snapshots(BlockDriverState *bs) offset =3D ROUND_UP(offset, 8); ret =3D bdrv_pread(bs->file, offset, &h, sizeof(h)); if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to read snapshot table"); goto fail; } =20 @@ -88,6 +89,7 @@ int qcow2_read_snapshots(BlockDriverState *bs) ret =3D bdrv_pread(bs->file, offset, &extra, MIN(sizeof(extra), extra_data_size)); if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to read snapshot table"); goto fail; } offset +=3D extra_data_size; @@ -107,6 +109,7 @@ int qcow2_read_snapshots(BlockDriverState *bs) sn->id_str =3D g_malloc(id_str_size + 1); ret =3D bdrv_pread(bs->file, offset, sn->id_str, id_str_size); if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to read snapshot table"); goto fail; } offset +=3D id_str_size; @@ -116,6 +119,7 @@ int qcow2_read_snapshots(BlockDriverState *bs) sn->name =3D g_malloc(name_size + 1); ret =3D bdrv_pread(bs->file, offset, sn->name, name_size); if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to read snapshot table"); goto fail; } offset +=3D name_size; @@ -123,6 +127,7 @@ int qcow2_read_snapshots(BlockDriverState *bs) =20 if (offset - s->snapshots_offset > QCOW_MAX_SNAPSHOTS_SIZE) { ret =3D -EFBIG; + error_setg(errp, "Snapshot table is too big"); goto fail; } } diff --git a/block/qcow2.c b/block/qcow2.c index 7961c05783..d0135912d0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1584,9 +1584,8 @@ static int coroutine_fn qcow2_do_open(BlockDriverStat= e *bs, QDict *options, s->snapshots_offset =3D header.snapshots_offset; s->nb_snapshots =3D header.nb_snapshots; =20 - ret =3D qcow2_read_snapshots(bs); + ret =3D qcow2_read_snapshots(bs, errp); if (ret < 0) { - error_setg_errno(errp, -ret, "Could not read snapshots"); goto fail; } =20 --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808139; cv=none; d=zoho.com; s=zohoarc; b=JU83RLIEd4Hf6RShkLZXRTfL6kopv/i6IPLT4WMvWGJIfzElWx9TDuW0JpfGsWduw/P5PeImA5rHkLs+fWQMCvsbNiygy/9vcEzmoUnxjRH07AN29wd0I3nHjT/IZYXOl8W5XAdqsPYrcG2HnInAiXwkbZongloMdP8jDPb3B1c= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808139; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Vd4uO5pItnslJVdsn/vUXH9GsCdFsW7d5g66+MVW+6E=; b=VpFu2op+M7R411R3Gr0+U4Xu5Z+i3XRu0I1txV1wEoPPgpxlUDeoYagJII2yG2Pqlc48TbzSluuvoEbmp+AIsXg9NpGrV9fy8uAObhoSrfONbbuSFUSxGMb4htp+iCdKAWSVYk0iFLOx8H4YTEGm/F7rzede9s4d3PFYI3bU4bc= 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 1570808139073523.6420977324016; Fri, 11 Oct 2019 08:35:39 -0700 (PDT) Received: from localhost ([::1]:52270 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwx6-0007sE-Un for importer@patchew.org; Fri, 11 Oct 2019 11:35:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57737) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqJ-0001RS-HF for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqI-0006UM-1r for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:35 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38058) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqE-0006RO-CW; Fri, 11 Oct 2019 11:28:30 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9F7AD300CB26; Fri, 11 Oct 2019 15:28:29 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E50E310013D9; Fri, 11 Oct 2019 15:28:28 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 04/16] qcow2: Keep unknown extra snapshot data Date: Fri, 11 Oct 2019 17:28:02 +0200 Message-Id: <20191011152814.14791-5-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 11 Oct 2019 15:28:29 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The qcow2 specification says to ignore unknown extra data fields in snapshot table entries. Currently, we discard it whenever we update the image, which is a bit different from "ignore". This patch makes the qcow2 driver keep all unknown extra data fields when updating an image's snapshot table. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2.h | 5 ++++ block/qcow2-snapshot.c | 61 +++++++++++++++++++++++++++++++++++------- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/block/qcow2.h b/block/qcow2.h index 8da1ad11d9..61e5d4ba94 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -61,6 +61,9 @@ * space for snapshot names and IDs */ #define QCOW_MAX_SNAPSHOTS_SIZE (1024 * QCOW_MAX_SNAPSHOTS) =20 +/* Maximum amount of extra data per snapshot table entry to accept */ +#define QCOW_MAX_SNAPSHOT_EXTRA_DATA 1024 + /* Bitmap header extension constraints */ #define QCOW2_MAX_BITMAPS 65535 #define QCOW2_MAX_BITMAP_DIRECTORY_SIZE (1024 * QCOW2_MAX_BITMAPS) @@ -181,6 +184,8 @@ typedef struct QCowSnapshot { uint32_t date_sec; uint32_t date_nsec; uint64_t vm_clock_nsec; + uint32_t extra_data_size; + void *unknown_extra_data; /* Extra data past QCowSnapshotExtraData */ } QCowSnapshot; =20 struct Qcow2Cache; diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 80d32e4504..120cb7fa09 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -37,6 +37,7 @@ void qcow2_free_snapshots(BlockDriverState *bs) for(i =3D 0; i < s->nb_snapshots; i++) { g_free(s->snapshots[i].name); g_free(s->snapshots[i].id_str); + g_free(s->snapshots[i].unknown_extra_data); } g_free(s->snapshots); s->snapshots =3D NULL; @@ -51,7 +52,6 @@ int qcow2_read_snapshots(BlockDriverState *bs, Error **er= rp) QCowSnapshot *sn; int i, id_str_size, name_size; int64_t offset; - uint32_t extra_data_size; int ret; =20 if (!s->nb_snapshots) { @@ -80,31 +80,53 @@ int qcow2_read_snapshots(BlockDriverState *bs, Error **= errp) sn->date_sec =3D be32_to_cpu(h.date_sec); sn->date_nsec =3D be32_to_cpu(h.date_nsec); sn->vm_clock_nsec =3D be64_to_cpu(h.vm_clock_nsec); - extra_data_size =3D be32_to_cpu(h.extra_data_size); + sn->extra_data_size =3D be32_to_cpu(h.extra_data_size); =20 id_str_size =3D be16_to_cpu(h.id_str_size); name_size =3D be16_to_cpu(h.name_size); =20 - /* Read extra data */ + if (sn->extra_data_size > QCOW_MAX_SNAPSHOT_EXTRA_DATA) { + ret =3D -EFBIG; + error_setg(errp, "Too much extra metadata in snapshot table " + "entry %i", i); + goto fail; + } + + /* Read known extra data */ ret =3D bdrv_pread(bs->file, offset, &extra, - MIN(sizeof(extra), extra_data_size)); + MIN(sizeof(extra), sn->extra_data_size)); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to read snapshot table"); goto fail; } - offset +=3D extra_data_size; + offset +=3D MIN(sizeof(extra), sn->extra_data_size); =20 - if (extra_data_size >=3D endof(QCowSnapshotExtraData, - vm_state_size_large)) { + if (sn->extra_data_size >=3D endof(QCowSnapshotExtraData, + vm_state_size_large)) { sn->vm_state_size =3D be64_to_cpu(extra.vm_state_size_large); } =20 - if (extra_data_size >=3D endof(QCowSnapshotExtraData, disk_size)) { + if (sn->extra_data_size >=3D endof(QCowSnapshotExtraData, disk_siz= e)) { sn->disk_size =3D be64_to_cpu(extra.disk_size); } else { sn->disk_size =3D bs->total_sectors * BDRV_SECTOR_SIZE; } =20 + if (sn->extra_data_size > sizeof(extra)) { + /* Store unknown extra data */ + size_t unknown_extra_data_size =3D + sn->extra_data_size - sizeof(extra); + + sn->unknown_extra_data =3D g_malloc(unknown_extra_data_size); + ret =3D bdrv_pread(bs->file, offset, sn->unknown_extra_data, + unknown_extra_data_size); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to read snapshot tabl= e"); + goto fail; + } + offset +=3D unknown_extra_data_size; + } + /* Read snapshot ID */ sn->id_str =3D g_malloc(id_str_size + 1); ret =3D bdrv_pread(bs->file, offset, sn->id_str, id_str_size); @@ -162,7 +184,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs) sn =3D s->snapshots + i; offset =3D ROUND_UP(offset, 8); offset +=3D sizeof(h); - offset +=3D sizeof(extra); + offset +=3D MAX(sizeof(extra), sn->extra_data_size); offset +=3D strlen(sn->id_str); offset +=3D strlen(sn->name); =20 @@ -209,7 +231,8 @@ static int qcow2_write_snapshots(BlockDriverState *bs) h.date_sec =3D cpu_to_be32(sn->date_sec); h.date_nsec =3D cpu_to_be32(sn->date_nsec); h.vm_clock_nsec =3D cpu_to_be64(sn->vm_clock_nsec); - h.extra_data_size =3D cpu_to_be32(sizeof(extra)); + h.extra_data_size =3D cpu_to_be32(MAX(sizeof(extra), + sn->extra_data_size)); =20 memset(&extra, 0, sizeof(extra)); extra.vm_state_size_large =3D cpu_to_be64(sn->vm_state_size); @@ -234,6 +257,22 @@ static int qcow2_write_snapshots(BlockDriverState *bs) } offset +=3D sizeof(extra); =20 + if (sn->extra_data_size > sizeof(extra)) { + size_t unknown_extra_data_size =3D + sn->extra_data_size - sizeof(extra); + + /* qcow2_read_snapshots() ensures no unbounded allocation */ + assert(unknown_extra_data_size <=3D BDRV_REQUEST_MAX_BYTES); + assert(sn->unknown_extra_data); + + ret =3D bdrv_pwrite(bs->file, offset, sn->unknown_extra_data, + unknown_extra_data_size); + if (ret < 0) { + goto fail; + } + offset +=3D unknown_extra_data_size; + } + ret =3D bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size); if (ret < 0) { goto fail; @@ -376,6 +415,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSna= pshotInfo *sn_info) sn->date_sec =3D sn_info->date_sec; sn->date_nsec =3D sn_info->date_nsec; sn->vm_clock_nsec =3D sn_info->vm_clock_nsec; + sn->extra_data_size =3D sizeof(QCowSnapshotExtraData); =20 /* Allocate the L1 table of the snapshot and copy the current one ther= e. */ l1_table_offset =3D qcow2_alloc_clusters(bs, s->l1_size * sizeof(uint6= 4_t)); @@ -647,6 +687,7 @@ int qcow2_snapshot_delete(BlockDriverState *bs, * The snapshot is now unused, clean up. If we fail after this point, = we * won't recover but just leak clusters. */ + g_free(sn.unknown_extra_data); g_free(sn.id_str); g_free(sn.name); =20 --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808089; cv=none; d=zoho.com; s=zohoarc; b=RNI3OcZusKzn6NYTGbnUL3tDjd0H4hVt52R+LbI4ghqUPGgAX9HzF/xHgyjzDxHDJgX7My6BOXieI2H1dc134ApCl9tGxVJU6O4SeMotWWQsgeQDJiVQAP6VM1pQ5pDnY1qoO47Qb/LX5gNMQurID7n1OcPWUaJsUB9jcbpCejo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808089; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=vKNWtrawwrvcPC483txmrgkOQmjJJDK3XXfz5Etm53I=; b=Qn//TKCADs/0K3/s5+YJMNiVXQlAqLrPRRheqWvchd0IgSqfdaZ1+M6iktY3Dw4KyfG7jv1WDKoZnKKXmRcO6QulnjCQp+pLVTprPvfr/W4EnrAVHHC1eZo/hQz9bn8TupgR7wKN25xhCthin19bT+BlFpOF90o3o6s/e/dZRjY= 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 1570808089281590.8173322393228; Fri, 11 Oct 2019 08:34:49 -0700 (PDT) Received: from localhost ([::1]:52264 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwwJ-00079c-Fp for importer@patchew.org; Fri, 11 Oct 2019 11:34:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57755) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqN-0001TB-LZ for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:41 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqL-0006XI-J5 for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51184) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqH-0006Sb-Go; Fri, 11 Oct 2019 11:28:33 -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 A0EE73001783; Fri, 11 Oct 2019 15:28:32 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 11D7F5DA2C; Fri, 11 Oct 2019 15:28:31 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 05/16] qcow2: Make qcow2_write_snapshots() public Date: Fri, 11 Oct 2019 17:28:03 +0200 Message-Id: <20191011152814.14791-6-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 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.44]); Fri, 11 Oct 2019 15:28:32 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Updating the snapshot list will be useful when upgrading a v2 image to v3, so we will need to call this function in qcow2.c. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2.h | 1 + block/qcow2-snapshot.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/block/qcow2.h b/block/qcow2.h index 61e5d4ba94..02d629a3d8 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -714,6 +714,7 @@ int qcow2_snapshot_load_tmp(BlockDriverState *bs, =20 void qcow2_free_snapshots(BlockDriverState *bs); int qcow2_read_snapshots(BlockDriverState *bs, Error **errp); +int qcow2_write_snapshots(BlockDriverState *bs); =20 /* qcow2-cache.c functions */ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables, diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 120cb7fa09..e3bf4c9776 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -164,7 +164,7 @@ fail: } =20 /* add at the end of the file a new list of snapshots */ -static int qcow2_write_snapshots(BlockDriverState *bs) +int qcow2_write_snapshots(BlockDriverState *bs) { BDRVQcow2State *s =3D bs->opaque; QCowSnapshot *sn; --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808290; cv=none; d=zoho.com; s=zohoarc; b=Y88rUF76zpR/dkkPae8gTF8XsM0zO/9GvImRH1pJyxGATQexPbTR72qgJb8pD/3Q+cHfXouoEg1CcJCCO/bCjPtnIJ+F0qQEZMcpuLtMtCX1YiuC3kdRm05hBAjzjcnmavkkmrR7Ul3mNBLnHb9RpnBkI8HlY5IKJHehGdk7eUE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808290; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=mz0jR2V6cnSu94VAk5eTr/ce5XPdzCEMVdktfJZ8BgM=; b=SxBT7wghioHJ2pYlPcNERFmCvWngfXXhQ57YFrkx9UiahKbGcamoyPdQRLygKTilGTRlf+PrNzZq18DgbAYaOdhQCnZR5eZv/sNugXlq66lIybhPTtBXwLPzF5814w90FtbmFiBjcQ0ZkoDmf2SB5DHdzdyF6S2PKvTOTBEY4Yw= 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 157080829078462.69918778409317; Fri, 11 Oct 2019 08:38:10 -0700 (PDT) Received: from localhost ([::1]:52302 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwzZ-0003VI-G2 for importer@patchew.org; Fri, 11 Oct 2019 11:38:09 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57801) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqS-0001Wf-S3 for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqR-0006aA-Kw for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:44 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58338) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqL-0006Wg-GW; Fri, 11 Oct 2019 11:28:37 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 936F199C42; Fri, 11 Oct 2019 15:28:35 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 30EF719C58; Fri, 11 Oct 2019 15:28:34 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 06/16] qcow2: Put qcow2_upgrade() into its own function Date: Fri, 11 Oct 2019 17:28:04 +0200 Message-Id: <20191011152814.14791-7-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 11 Oct 2019 15:28:35 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This does not make sense right now, but it will make sense once we need to do more than to just update s->qcow_version. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2.c | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index d0135912d0..d43064dca2 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -4897,12 +4897,46 @@ static int qcow2_downgrade(BlockDriverState *bs, in= t target_version, return 0; } =20 +/* + * Upgrades an image's version. While newer versions encompass all + * features of older versions, some things may have to be presented + * differently. + */ +static int qcow2_upgrade(BlockDriverState *bs, int target_version, + BlockDriverAmendStatusCB *status_cb, void *cb_opa= que, + Error **errp) +{ + BDRVQcow2State *s =3D bs->opaque; + int current_version =3D s->qcow_version; + int ret; + + /* This is qcow2_upgrade(), not qcow2_downgrade() */ + assert(target_version > current_version); + + /* There are no other versions (yet) that you can upgrade to */ + assert(target_version =3D=3D 3); + + status_cb(bs, 0, 1, cb_opaque); + + s->qcow_version =3D target_version; + ret =3D qcow2_update_header(bs); + if (ret < 0) { + s->qcow_version =3D current_version; + error_setg_errno(errp, -ret, "Failed to update the image header"); + return ret; + } + status_cb(bs, 1, 1, cb_opaque); + + return 0; +} + typedef enum Qcow2AmendOperation { /* This is the value Qcow2AmendHelperCBInfo::last_operation will be * statically initialized to so that the helper CB can discern the fir= st * invocation from an operation change */ QCOW2_NO_OPERATION =3D 0, =20 + QCOW2_UPGRADING, QCOW2_CHANGING_REFCOUNT_ORDER, QCOW2_DOWNGRADING, } Qcow2AmendOperation; @@ -5085,17 +5119,16 @@ static int qcow2_amend_options(BlockDriverState *bs= , QemuOpts *opts, helper_cb_info =3D (Qcow2AmendHelperCBInfo){ .original_status_cb =3D status_cb, .original_cb_opaque =3D cb_opaque, - .total_operations =3D (new_version < old_version) + .total_operations =3D (new_version !=3D old_version) + (s->refcount_bits !=3D refcount_bits) }; =20 /* Upgrade first (some features may require compat=3D1.1) */ if (new_version > old_version) { - s->qcow_version =3D new_version; - ret =3D qcow2_update_header(bs); + helper_cb_info.current_operation =3D QCOW2_UPGRADING; + ret =3D qcow2_upgrade(bs, new_version, &qcow2_amend_helper_cb, + &helper_cb_info, errp); if (ret < 0) { - s->qcow_version =3D old_version; - error_setg_errno(errp, -ret, "Failed to update the image heade= r"); return ret; } } --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808091; cv=none; d=zoho.com; s=zohoarc; b=j/5B2O9I6WhZ0WVsRRIIkPFEhF9kr9jF0U1qWnZjOPENQQ52V7Afc0VXqYcC5hzUuUGjMad48wRXG/4uEXiDO1PayKAPCVQTLFyCCJs4phQbIudrl6Kpdfb447+1WvTXnM4PqdrQHGyzgckFlPvMI+rUan2Pi7gsHpr+h8H6tzc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808091; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=BzXZJ6TgZGnk1jwxt8/OduaLSfB1C1V/iBDP7rtFHa0=; b=B67xFwXChpif4g8Do2Cl8k5fteeTUqO6BYUKY7TKUDTaQLI6r5hxskYinPD84aTjmO3G1X44RH/LGWbRhcs7hLLOdTxxgl18R16b2ocgEjrvhDN32MWFVHSX8OdVQw7qSp3RiqQaqMY153W/hHP/V2p6uR+0iyGJszzXiPRriU4= 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 157080809146835.4118115953371; Fri, 11 Oct 2019 08:34:51 -0700 (PDT) Received: from localhost ([::1]:52266 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwwL-0007Cu-L9 for importer@patchew.org; Fri, 11 Oct 2019 11:34:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57805) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqT-0001Wz-0m for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqR-0006Zz-Ka for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:44 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38154) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqN-0006Xm-JB; Fri, 11 Oct 2019 11:28:39 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8CA3C302C080; Fri, 11 Oct 2019 15:28:38 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 029DA60872; Fri, 11 Oct 2019 15:28:37 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 07/16] qcow2: Write v3-compliant snapshot list on upgrade Date: Fri, 11 Oct 2019 17:28:05 +0200 Message-Id: <20191011152814.14791-8-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.46]); Fri, 11 Oct 2019 15:28:38 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" qcow2 v3 requires every snapshot table entry to have two extra data fields: The 64-bit VM state size, and the virtual disk size. Both are optional for v2 images, so they may not be present. qcow2_upgrade() therefore should update the snapshot table to ensure all entries have these extra data fields. Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=3D1727347 Reported-by: Eric Blake Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index d43064dca2..a2e46ce589 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -4907,7 +4907,9 @@ static int qcow2_upgrade(BlockDriverState *bs, int ta= rget_version, Error **errp) { BDRVQcow2State *s =3D bs->opaque; + bool need_snapshot_update; int current_version =3D s->qcow_version; + int i; int ret; =20 /* This is qcow2_upgrade(), not qcow2_downgrade() */ @@ -4916,7 +4918,33 @@ static int qcow2_upgrade(BlockDriverState *bs, int t= arget_version, /* There are no other versions (yet) that you can upgrade to */ assert(target_version =3D=3D 3); =20 - status_cb(bs, 0, 1, cb_opaque); + status_cb(bs, 0, 2, cb_opaque); + + /* + * In v2, snapshots do not need to have extra data. v3 requires + * the 64-bit VM state size and the virtual disk size to be + * present. + * qcow2_write_snapshots() will always write the list in the + * v3-compliant format. + */ + need_snapshot_update =3D false; + for (i =3D 0; i < s->nb_snapshots; i++) { + if (s->snapshots[i].extra_data_size < + sizeof_field(QCowSnapshotExtraData, vm_state_size_large) + + sizeof_field(QCowSnapshotExtraData, disk_size)) + { + need_snapshot_update =3D true; + break; + } + } + if (need_snapshot_update) { + ret =3D qcow2_write_snapshots(bs); + if (ret < 0) { + error_setg_errno(errp, -ret, "Failed to update the snapshot ta= ble"); + return ret; + } + } + status_cb(bs, 1, 2, cb_opaque); =20 s->qcow_version =3D target_version; ret =3D qcow2_update_header(bs); @@ -4925,7 +4953,7 @@ static int qcow2_upgrade(BlockDriverState *bs, int ta= rget_version, error_setg_errno(errp, -ret, "Failed to update the image header"); return ret; } - status_cb(bs, 1, 1, cb_opaque); + status_cb(bs, 2, 2, cb_opaque); =20 return 0; } --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808270; cv=none; d=zoho.com; s=zohoarc; b=nJ2epgvvMG5C/ID/BROOWzHaWI5S0U1UoZocSEyJKTWNXbMKmC9clzlxrEApAVhBzafGSd0pPVN78dCYRzPZTQzUHTBGd/0+38S2xglFuNr3vadetEzwb4ONkYrywaR2XgcqAuj8NfUVCfAnBz4sLnj/rGLsec0rDM5hIyj9FYs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808270; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=t8XjP35u7ULqi+yYnS5N7zEl7A5C+J0HKDlmU0hiCiw=; b=aNa8nb9J8nT3rOxfPLtaMUvNAWntt0RycZXBQWZNvkrxzXItL4q/q07FrS0R4EWm/H6GexGokD/c+qnDNeL8U3JNWAQSwL+skC4SJaoFE11p+JAh5zBkKE+Xir5NHYGTjoR2PxiEy6zMeKxr5QA7tLJrOX50+AbTY4wB3Nr0z/U= 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 1570808270941408.1246110947137; Fri, 11 Oct 2019 08:37:50 -0700 (PDT) Received: from localhost ([::1]:52300 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwzF-0002sX-C9 for importer@patchew.org; Fri, 11 Oct 2019 11:37:49 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57846) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqW-0001cs-Aq for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqU-0006bn-R4 for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39432) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqR-0006ZC-Iy; Fri, 11 Oct 2019 11:28:43 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 538BB7E423; Fri, 11 Oct 2019 15:28:41 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B41A14535; Fri, 11 Oct 2019 15:28:40 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 08/16] qcow2: Separate qcow2_check_read_snapshot_table() Date: Fri, 11 Oct 2019 17:28:06 +0200 Message-Id: <20191011152814.14791-9-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 11 Oct 2019 15:28:41 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Reading the snapshot table can fail. That is a problem when we want to repair the image. Therefore, stop reading the snapshot table in qcow2_do_open() in check mode. Instead, add a new function qcow2_check_read_snapshot_table() that reads the snapshot table at a later point. In the future, we want to handle errors here and fix them. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2.h | 4 +++ block/qcow2-snapshot.c | 58 ++++++++++++++++++++++++++++++++ block/qcow2.c | 76 ++++++++++++++++++++++++++++++++---------- 3 files changed, 120 insertions(+), 18 deletions(-) diff --git a/block/qcow2.h b/block/qcow2.h index 02d629a3d8..6c2a38c98d 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -716,6 +716,10 @@ void qcow2_free_snapshots(BlockDriverState *bs); int qcow2_read_snapshots(BlockDriverState *bs, Error **errp); int qcow2_write_snapshots(BlockDriverState *bs); =20 +int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs, + BdrvCheckResult *result, + BdrvCheckMode fix); + /* qcow2-cache.c functions */ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables, unsigned table_size); diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index e3bf4c9776..d667bfd935 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -322,6 +322,64 @@ fail: return ret; } =20 +int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs, + BdrvCheckResult *result, + BdrvCheckMode fix) +{ + BDRVQcow2State *s =3D bs->opaque; + Error *local_err =3D NULL; + int ret; + struct { + uint32_t nb_snapshots; + uint64_t snapshots_offset; + } QEMU_PACKED snapshot_table_pointer; + + /* qcow2_do_open() discards this information in check mode */ + ret =3D bdrv_pread(bs->file, offsetof(QCowHeader, nb_snapshots), + &snapshot_table_pointer, sizeof(snapshot_table_pointe= r)); + if (ret < 0) { + result->check_errors++; + fprintf(stderr, "ERROR failed to read the snapshot table pointer f= rom " + "the image header: %s\n", strerror(-ret)); + return ret; + } + + s->snapshots_offset =3D be64_to_cpu(snapshot_table_pointer.snapshots_o= ffset); + s->nb_snapshots =3D be32_to_cpu(snapshot_table_pointer.nb_snapshots); + + ret =3D qcow2_validate_table(bs, s->snapshots_offset, s->nb_snapshots, + sizeof(QCowSnapshotHeader), + sizeof(QCowSnapshotHeader) * QCOW_MAX_SNAPS= HOTS, + "snapshot table", &local_err); + if (ret < 0) { + result->check_errors++; + error_reportf_err(local_err, "ERROR "); + + /* We did not read the snapshot table, so invalidate this informat= ion */ + s->snapshots_offset =3D 0; + s->nb_snapshots =3D 0; + + return ret; + } + + qemu_co_mutex_unlock(&s->lock); + ret =3D qcow2_read_snapshots(bs, &local_err); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + result->check_errors++; + error_reportf_err(local_err, + "ERROR failed to read the snapshot table: "); + + /* We did not read the snapshot table, so invalidate this informat= ion */ + s->snapshots_offset =3D 0; + s->nb_snapshots =3D 0; + + return ret; + } + + return 0; +} + static void find_new_snapshot_id(BlockDriverState *bs, char *id_str, int id_str_size) { diff --git a/block/qcow2.c b/block/qcow2.c index a2e46ce589..7f47444ab7 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -570,11 +570,40 @@ int qcow2_mark_consistent(BlockDriverState *bs) return 0; } =20 +static void qcow2_add_check_result(BdrvCheckResult *out, + const BdrvCheckResult *src, + bool set_allocation_info) +{ + out->corruptions +=3D src->corruptions; + out->leaks +=3D src->leaks; + out->check_errors +=3D src->check_errors; + out->corruptions_fixed +=3D src->corruptions_fixed; + out->leaks_fixed +=3D src->leaks_fixed; + + if (set_allocation_info) { + out->image_end_offset =3D src->image_end_offset; + out->bfi =3D src->bfi; + } +} + static int coroutine_fn qcow2_co_check_locked(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix) { - int ret =3D qcow2_check_refcounts(bs, result, fix); + BdrvCheckResult snapshot_res =3D {}; + BdrvCheckResult refcount_res =3D {}; + int ret; + + memset(result, 0, sizeof(*result)); + + ret =3D qcow2_check_read_snapshot_table(bs, &snapshot_res, fix); + qcow2_add_check_result(result, &snapshot_res, false); + if (ret < 0) { + return ret; + } + + ret =3D qcow2_check_refcounts(bs, &refcount_res, fix); + qcow2_add_check_result(result, &refcount_res, true); if (ret < 0) { return ret; } @@ -1410,17 +1439,22 @@ static int coroutine_fn qcow2_do_open(BlockDriverSt= ate *bs, QDict *options, goto fail; } =20 - /* The total size in bytes of the snapshot table is checked in - * qcow2_read_snapshots() because the size of each snapshot is - * variable and we don't know it yet. - * Here we only check the offset and number of snapshots. */ - ret =3D qcow2_validate_table(bs, header.snapshots_offset, - header.nb_snapshots, - sizeof(QCowSnapshotHeader), - sizeof(QCowSnapshotHeader) * QCOW_MAX_SNAPS= HOTS, - "Snapshot table", errp); - if (ret < 0) { - goto fail; + if (!(flags & BDRV_O_CHECK)) { + /* + * The total size in bytes of the snapshot table is checked in + * qcow2_read_snapshots() because the size of each snapshot is + * variable and we don't know it yet. + * Here we only check the offset and number of snapshots. + */ + ret =3D qcow2_validate_table(bs, header.snapshots_offset, + header.nb_snapshots, + sizeof(QCowSnapshotHeader), + sizeof(QCowSnapshotHeader) * + QCOW_MAX_SNAPSHOTS, + "Snapshot table", errp); + if (ret < 0) { + goto fail; + } } =20 /* read the level 1 table */ @@ -1580,13 +1614,19 @@ static int coroutine_fn qcow2_do_open(BlockDriverSt= ate *bs, QDict *options, s->image_backing_file =3D g_strdup(bs->auto_backing_file); } =20 - /* Internal snapshots */ - s->snapshots_offset =3D header.snapshots_offset; - s->nb_snapshots =3D header.nb_snapshots; + /* + * Internal snapshots; skip reading them in check mode, because + * we do not need them then, and we do not want to abort because + * of a broken table. + */ + if (!(flags & BDRV_O_CHECK)) { + s->snapshots_offset =3D header.snapshots_offset; + s->nb_snapshots =3D header.nb_snapshots; =20 - ret =3D qcow2_read_snapshots(bs, errp); - if (ret < 0) { - goto fail; + ret =3D qcow2_read_snapshots(bs, errp); + if (ret < 0) { + goto fail; + } } =20 /* Clear unknown autoclear feature bits */ --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808442; cv=none; d=zoho.com; s=zohoarc; b=W9RbT9Pr7F7FqmGyCMWDdrzEql25Pog6B8NfOSC/ZAlIozlO/Yd1Qps4FH10bYPbZVxIcu+oCrKc6jCGqWhLfAE0RFlMWjx59fYwwMxracYYApBlD2lUGdWOGKi6c50Ohi/yvtOQq67+j5XhBmFOU79WgidLyc7J29n/ycyjRvU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808442; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=AzZTmfgIrg2IlPyA45FBab1ZYygJXIS9ijT4kh/VQtY=; b=UcoSU0IWRmk2U8nbrnqI5gLrhauDAUgLV60aYc2fHOfmIRd8RSlcVuU1SG06VfwqqnGu6sWZh5/hLUPvXpUhmSCpJOvbj+YG1BXEQUN29EF7D0n4IZ0Gk4h4GgPuGuQVGhyTO7CX7/K7TcPvD3bcqtLwoTxK37luANyaoaGAwQQ= 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 1570808442860673.5254781246226; Fri, 11 Oct 2019 08:40:42 -0700 (PDT) Received: from localhost ([::1]:52338 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIx21-0006yT-Bo for importer@patchew.org; Fri, 11 Oct 2019 11:40:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57853) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqW-0001dg-QU for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqV-0006cA-JM for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:48 -0400 Received: from mx1.redhat.com ([209.132.183.28]:34174) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqT-0006ae-2l; Fri, 11 Oct 2019 11:28:45 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 55FC910DCCA4; Fri, 11 Oct 2019 15:28:44 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 91C365C1B2; Fri, 11 Oct 2019 15:28:43 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 09/16] qcow2: Add qcow2_check_fix_snapshot_table() Date: Fri, 11 Oct 2019 17:28:07 +0200 Message-Id: <20191011152814.14791-10-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.64]); Fri, 11 Oct 2019 15:28:44 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" qcow2_check_read_snapshot_table() can perform consistency checks, but it cannot fix everything. Specifically, it cannot allocate new clusters, because that should wait until the refcount structures are known to be consistent (i.e., after qcow2_check_refcounts()). Thus, it cannot call qcow2_write_snapshots(). Do that in qcow2_check_fix_snapshot_table(), which is called after qcow2_check_refcounts(). Currently, there is nothing that would set result->corruptions, so this is a no-op. A follow-up patch will change that. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2.h | 3 +++ block/qcow2-snapshot.c | 25 +++++++++++++++++++++++++ block/qcow2.c | 9 ++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/block/qcow2.h b/block/qcow2.h index 6c2a38c98d..b6125899b8 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -719,6 +719,9 @@ int qcow2_write_snapshots(BlockDriverState *bs); int coroutine_fn qcow2_check_read_snapshot_table(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix); +int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs, + BdrvCheckResult *result, + BdrvCheckMode fix); =20 /* qcow2-cache.c functions */ Qcow2Cache *qcow2_cache_create(BlockDriverState *bs, int num_tables, diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index d667bfd935..b526a8f819 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -380,6 +380,31 @@ int coroutine_fn qcow2_check_read_snapshot_table(Block= DriverState *bs, return 0; } =20 +int coroutine_fn qcow2_check_fix_snapshot_table(BlockDriverState *bs, + BdrvCheckResult *result, + BdrvCheckMode fix) +{ + BDRVQcow2State *s =3D bs->opaque; + int ret; + + if (result->corruptions && (fix & BDRV_FIX_ERRORS)) { + qemu_co_mutex_unlock(&s->lock); + ret =3D qcow2_write_snapshots(bs); + qemu_co_mutex_lock(&s->lock); + if (ret < 0) { + result->check_errors++; + fprintf(stderr, "ERROR failed to update snapshot table: %s\n", + strerror(-ret)); + return ret; + } + + result->corruptions_fixed +=3D result->corruptions; + result->corruptions =3D 0; + } + + return 0; +} + static void find_new_snapshot_id(BlockDriverState *bs, char *id_str, int id_str_size) { diff --git a/block/qcow2.c b/block/qcow2.c index 7f47444ab7..c8b3726dff 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -597,13 +597,20 @@ static int coroutine_fn qcow2_co_check_locked(BlockDr= iverState *bs, memset(result, 0, sizeof(*result)); =20 ret =3D qcow2_check_read_snapshot_table(bs, &snapshot_res, fix); - qcow2_add_check_result(result, &snapshot_res, false); if (ret < 0) { + qcow2_add_check_result(result, &snapshot_res, false); return ret; } =20 ret =3D qcow2_check_refcounts(bs, &refcount_res, fix); qcow2_add_check_result(result, &refcount_res, true); + if (ret < 0) { + qcow2_add_check_result(result, &snapshot_res, false); + return ret; + } + + ret =3D qcow2_check_fix_snapshot_table(bs, &snapshot_res, fix); + qcow2_add_check_result(result, &snapshot_res, false); if (ret < 0) { return ret; } --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808262; cv=none; d=zoho.com; s=zohoarc; b=Ivb43vL8nt43lqWd6HIoCi08+sEruf85T7MdKQGIOL2Gj5PPwEZ2AHXgSbNofYJoqvKyYm8Wk5n127mr+11LzzQK+j+t1CRljl+7ya0Dxkm9AgF5xBQo8PDb7U3nQWY4Z/833dDR5ifXGK6tguPZgD1BEDO6lgTVSjLcEe8/Vew= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808262; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=crynb91AxCXcV0n6HPvCdyO3qG2pc4snrxQCwiWuECw=; b=XHGQppI5rxkkH4PBLslAVZeVoTT9oD1n11/TvbLMPzy0QAqldyq33keVsESfa7GjUzJzt8tFGSaQ6ZBUgZ1+41BCAIRXX29vtmtBSvL7bPz3S0a/JWX04HTMx1k+xNs2Y3HdqDMNK01dMP/aiqRXw9Ii31FgDAjUVtRQzpKlck4= 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 1570808262686416.79731677103075; Fri, 11 Oct 2019 08:37:42 -0700 (PDT) Received: from localhost ([::1]:52296 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwz7-0002fb-47 for importer@patchew.org; Fri, 11 Oct 2019 11:37:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57891) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqZ-0001iX-IZ for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqY-0006dS-5J for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:51 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59658) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqV-0006bi-64; Fri, 11 Oct 2019 11:28:47 -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 6EFC02BF02; Fri, 11 Oct 2019 15:28:46 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 0C2E45D9CA; Fri, 11 Oct 2019 15:28:45 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 10/16] qcow2: Fix broken snapshot table entries Date: Fri, 11 Oct 2019 17:28:08 +0200 Message-Id: <20191011152814.14791-11-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 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.39]); Fri, 11 Oct 2019 15:28:46 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The only case where we currently reject snapshot table entries is when they have too much extra data. Fix them with qemu-img check -r all by counting it as a corruption, reducing their extra_data_size, and then letting qcow2_check_fix_snapshot_table() do the rest. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2-snapshot.c | 67 +++++++++++++++++++++++++++++++++++------- 1 file changed, 56 insertions(+), 11 deletions(-) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index b526a8f819..53dc1635ec 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -44,7 +44,23 @@ void qcow2_free_snapshots(BlockDriverState *bs) s->nb_snapshots =3D 0; } =20 -int qcow2_read_snapshots(BlockDriverState *bs, Error **errp) +/* + * If @repair is true, try to repair a broken snapshot table instead + * of just returning an error: + * + * - If there were snapshots with too much extra metadata, increment + * *extra_data_dropped for each. + * This requires the caller to eventually rewrite the whole snapshot + * table, which requires cluster allocation. Therefore, this should + * be done only after qcow2_check_refcounts() made sure the refcount + * structures are valid. + * (In the meantime, the image is still valid because + * qcow2_check_refcounts() does not do anything with snapshots' + * extra data.) + */ +static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair, + int *extra_data_dropped, + Error **errp) { BDRVQcow2State *s =3D bs->opaque; QCowSnapshotHeader h; @@ -64,6 +80,8 @@ int qcow2_read_snapshots(BlockDriverState *bs, Error **er= rp) s->snapshots =3D g_new0(QCowSnapshot, s->nb_snapshots); =20 for(i =3D 0; i < s->nb_snapshots; i++) { + bool truncate_unknown_extra_data =3D false; + /* Read statically sized part of the snapshot header */ offset =3D ROUND_UP(offset, 8); ret =3D bdrv_pread(bs->file, offset, &h, sizeof(h)); @@ -86,10 +104,21 @@ int qcow2_read_snapshots(BlockDriverState *bs, Error *= *errp) name_size =3D be16_to_cpu(h.name_size); =20 if (sn->extra_data_size > QCOW_MAX_SNAPSHOT_EXTRA_DATA) { - ret =3D -EFBIG; - error_setg(errp, "Too much extra metadata in snapshot table " - "entry %i", i); - goto fail; + if (!repair) { + ret =3D -EFBIG; + error_setg(errp, "Too much extra metadata in snapshot tabl= e " + "entry %i", i); + error_append_hint(errp, "You can force-remove this extra " + "metadata with qemu-img check -r all\n"); + goto fail; + } + + fprintf(stderr, "Discarding too much extra metadata in snapsho= t " + "table entry %i (%" PRIu32 " > %u)\n", + i, sn->extra_data_size, QCOW_MAX_SNAPSHOT_EXTRA_DATA); + + (*extra_data_dropped)++; + truncate_unknown_extra_data =3D true; } =20 /* Read known extra data */ @@ -113,18 +142,26 @@ int qcow2_read_snapshots(BlockDriverState *bs, Error = **errp) } =20 if (sn->extra_data_size > sizeof(extra)) { - /* Store unknown extra data */ - size_t unknown_extra_data_size =3D - sn->extra_data_size - sizeof(extra); + uint64_t extra_data_end; + size_t unknown_extra_data_size; + + extra_data_end =3D offset + sn->extra_data_size - sizeof(extra= ); =20 + if (truncate_unknown_extra_data) { + sn->extra_data_size =3D QCOW_MAX_SNAPSHOT_EXTRA_DATA; + } + + /* Store unknown extra data */ + unknown_extra_data_size =3D sn->extra_data_size - sizeof(extra= ); sn->unknown_extra_data =3D g_malloc(unknown_extra_data_size); ret =3D bdrv_pread(bs->file, offset, sn->unknown_extra_data, unknown_extra_data_size); if (ret < 0) { - error_setg_errno(errp, -ret, "Failed to read snapshot tabl= e"); + error_setg_errno(errp, -ret, + "Failed to read snapshot table"); goto fail; } - offset +=3D unknown_extra_data_size; + offset =3D extra_data_end; } =20 /* Read snapshot ID */ @@ -163,6 +200,11 @@ fail: return ret; } =20 +int qcow2_read_snapshots(BlockDriverState *bs, Error **errp) +{ + return qcow2_do_read_snapshots(bs, false, NULL, errp); +} + /* add at the end of the file a new list of snapshots */ int qcow2_write_snapshots(BlockDriverState *bs) { @@ -328,6 +370,7 @@ int coroutine_fn qcow2_check_read_snapshot_table(BlockD= riverState *bs, { BDRVQcow2State *s =3D bs->opaque; Error *local_err =3D NULL; + int extra_data_dropped =3D 0; int ret; struct { uint32_t nb_snapshots; @@ -363,7 +406,8 @@ int coroutine_fn qcow2_check_read_snapshot_table(BlockD= riverState *bs, } =20 qemu_co_mutex_unlock(&s->lock); - ret =3D qcow2_read_snapshots(bs, &local_err); + ret =3D qcow2_do_read_snapshots(bs, fix & BDRV_FIX_ERRORS, + &extra_data_dropped, &local_err); qemu_co_mutex_lock(&s->lock); if (ret < 0) { result->check_errors++; @@ -376,6 +420,7 @@ int coroutine_fn qcow2_check_read_snapshot_table(BlockD= riverState *bs, =20 return ret; } + result->corruptions +=3D extra_data_dropped; =20 return 0; } --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808414; cv=none; d=zoho.com; s=zohoarc; b=HDS7JYK4HPMhJ7cJoyBlT9K7t3nxMz2/jJBTk03Hq7b2u8Duqbwd3AyRqr4E/21EfI+ovPLwK1bSluDioVxJkdw1ITu1aTJoxJwbLnHcaA13EzOLANBRqbIK518TVDV6H5dMmQjyAHtrCDyeBqrcx/bY3VozCns8wfO0DcjsWe0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808414; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=8GY0UYALgORgrIsYVkFZ2gJAx/X11FEG9MYTIfqkoCA=; b=BNqAOYzdy+hxJ3UNkCZvU9DhE9634t8LY7XZlyTcv1af3V/V72NTBmYvYFNkthcB6keyTqQihPSvEMmXG5QrGn34WwZLpptneQNEjB4gUzAjKODvVuyT+wKyGMKaml+06ciUEemNdcybhrnc4ntyPtlZCgwk06L0c0pJoCPb94g= 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 1570808414501956.0374283283422; Fri, 11 Oct 2019 08:40:14 -0700 (PDT) Received: from localhost ([::1]:52324 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIx1W-000670-Uz for importer@patchew.org; Fri, 11 Oct 2019 11:40:10 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57910) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqb-0001mC-DE for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqa-0006eO-28 for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:53 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58420) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqX-0006ct-LI; Fri, 11 Oct 2019 11:28:49 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DEE6576FF; Fri, 11 Oct 2019 15:28:48 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 56A236031D; Fri, 11 Oct 2019 15:28:48 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 11/16] qcow2: Keep track of the snapshot table length Date: Fri, 11 Oct 2019 17:28:09 +0200 Message-Id: <20191011152814.14791-12-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 11 Oct 2019 15:28:48 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" When repairing the snapshot table, we truncate entries that have too much extra data. This frees up space that we do not have to count towards the snapshot table size. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2-snapshot.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 53dc1635ec..582eb3386a 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -68,6 +68,7 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, = bool repair, QCowSnapshot *sn; int i, id_str_size, name_size; int64_t offset; + uint64_t table_length =3D 0; int ret; =20 if (!s->nb_snapshots) { @@ -82,6 +83,8 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, = bool repair, for(i =3D 0; i < s->nb_snapshots; i++) { bool truncate_unknown_extra_data =3D false; =20 + table_length =3D ROUND_UP(table_length, 8); + /* Read statically sized part of the snapshot header */ offset =3D ROUND_UP(offset, 8); ret =3D bdrv_pread(bs->file, offset, &h, sizeof(h)); @@ -184,7 +187,16 @@ static int qcow2_do_read_snapshots(BlockDriverState *b= s, bool repair, offset +=3D name_size; sn->name[name_size] =3D '\0'; =20 - if (offset - s->snapshots_offset > QCOW_MAX_SNAPSHOTS_SIZE) { + /* Note that the extra data may have been truncated */ + table_length +=3D sizeof(h) + sn->extra_data_size + id_str_size + + name_size; + if (!repair) { + assert(table_length =3D=3D offset - s->snapshots_offset); + } + + if (table_length > QCOW_MAX_SNAPSHOTS_SIZE || + offset - s->snapshots_offset > INT_MAX) + { ret =3D -EFBIG; error_setg(errp, "Snapshot table is too big"); goto fail; --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808128; cv=none; d=zoho.com; s=zohoarc; b=U7OgL9KzUvrvpIpMYywpI+IYO42DDVpHCvnC6gbKNDZwUhuKRLQhsECUDDAE2EzRI9WYXqS0EHcirfLVUqPItVaTbuv5g61wGc+6iq3NyNQIw4N5U28P51PMUGcNIh3hLP63ndeWYPXHju98jB100pgIq0YeTOZNsEzVFyXXPbc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808128; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=y2lEeI7TEj29X12MQf140m0jERLxAc5pE2jh8zenTmQ=; b=S9T5NaDsLjiBws66S6PN7Lt7E2jg1wLFHOvMcDYv90IRWqQWrnVTuYkeAQiLjZag1UjntYGMVcFcqEcUbgFAMWt5XqeyvcPlwWKf5evpwWR2Blj5xkZT8oCnKRr+AEfoZvcVdV0rZX3NYh9IQ4IfZvCF79rk2hEZVMEkymzWpNk= 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 1570808128069363.0997092620729; Fri, 11 Oct 2019 08:35:28 -0700 (PDT) Received: from localhost ([::1]:52268 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwws-0007Xl-RE for importer@patchew.org; Fri, 11 Oct 2019 11:35:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57957) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqf-0001tp-A8 for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqd-0006gT-LR for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:57 -0400 Received: from mx1.redhat.com ([209.132.183.28]:53312) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqa-0006eK-FP; Fri, 11 Oct 2019 11:28:52 -0400 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B13BE3097032; Fri, 11 Oct 2019 15:28:51 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 23B0F600CC; Fri, 11 Oct 2019 15:28:50 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 12/16] qcow2: Fix overly long snapshot tables Date: Fri, 11 Oct 2019 17:28:10 +0200 Message-Id: <20191011152814.14791-13-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.43]); Fri, 11 Oct 2019 15:28:51 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" We currently refuse to open qcow2 images with overly long snapshot tables. This patch makes qemu-img check -r all drop all offending entries past what we deem acceptable. The user cannot choose which snapshots are removed. This is fine because we have chosen the maximum snapshot table size to be so large (64 MB) that it cannot be reasonably reached. If the snapshot table exceeds this size, the image has probably been corrupted in some way; in this case, it is most important to just make the image usable such that the user can copy off at least the active layer. (Also note that the snapshots will be removed only with "-r all", so a plain "check" or "check -r leaks" will not delete any data.) Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2-snapshot.c | 88 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 78 insertions(+), 10 deletions(-) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 582eb3386a..366d9f574c 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -29,15 +29,24 @@ #include "qemu/error-report.h" #include "qemu/cutils.h" =20 +static void qcow2_free_single_snapshot(BlockDriverState *bs, int i) +{ + BDRVQcow2State *s =3D bs->opaque; + + assert(i >=3D 0 && i < s->nb_snapshots); + g_free(s->snapshots[i].name); + g_free(s->snapshots[i].id_str); + g_free(s->snapshots[i].unknown_extra_data); + memset(&s->snapshots[i], 0, sizeof(s->snapshots[i])); +} + void qcow2_free_snapshots(BlockDriverState *bs) { BDRVQcow2State *s =3D bs->opaque; int i; =20 for(i =3D 0; i < s->nb_snapshots; i++) { - g_free(s->snapshots[i].name); - g_free(s->snapshots[i].id_str); - g_free(s->snapshots[i].unknown_extra_data); + qcow2_free_single_snapshot(bs, i); } g_free(s->snapshots); s->snapshots =3D NULL; @@ -48,6 +57,14 @@ void qcow2_free_snapshots(BlockDriverState *bs) * If @repair is true, try to repair a broken snapshot table instead * of just returning an error: * + * - If the snapshot table was too long, set *nb_clusters_reduced to + * the number of snapshots removed off the end. + * The caller will update the on-disk nb_snapshots accordingly; + * this leaks clusters, but is safe. + * (The on-disk information must be updated before + * qcow2_check_refcounts(), because that function relies on + * s->nb_snapshots to reflect the on-disk value.) + * * - If there were snapshots with too much extra metadata, increment * *extra_data_dropped for each. * This requires the caller to eventually rewrite the whole snapshot @@ -59,6 +76,7 @@ void qcow2_free_snapshots(BlockDriverState *bs) * extra data.) */ static int qcow2_do_read_snapshots(BlockDriverState *bs, bool repair, + int *nb_clusters_reduced, int *extra_data_dropped, Error **errp) { @@ -67,7 +85,7 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs, = bool repair, QCowSnapshotExtraData extra; QCowSnapshot *sn; int i, id_str_size, name_size; - int64_t offset; + int64_t offset, pre_sn_offset; uint64_t table_length =3D 0; int ret; =20 @@ -83,6 +101,7 @@ static int qcow2_do_read_snapshots(BlockDriverState *bs,= bool repair, for(i =3D 0; i < s->nb_snapshots; i++) { bool truncate_unknown_extra_data =3D false; =20 + pre_sn_offset =3D offset; table_length =3D ROUND_UP(table_length, 8); =20 /* Read statically sized part of the snapshot header */ @@ -197,9 +216,31 @@ static int qcow2_do_read_snapshots(BlockDriverState *b= s, bool repair, if (table_length > QCOW_MAX_SNAPSHOTS_SIZE || offset - s->snapshots_offset > INT_MAX) { - ret =3D -EFBIG; - error_setg(errp, "Snapshot table is too big"); - goto fail; + if (!repair) { + ret =3D -EFBIG; + error_setg(errp, "Snapshot table is too big"); + error_append_hint(errp, "You can force-remove all %u " + "overhanging snapshots with qemu-img che= ck " + "-r all\n", s->nb_snapshots - i); + goto fail; + } + + fprintf(stderr, "Discarding %u overhanging snapshots (snapshot= " + "table is too big)\n", s->nb_snapshots - i); + + *nb_clusters_reduced +=3D (s->nb_snapshots - i); + + /* Discard current snapshot also */ + qcow2_free_single_snapshot(bs, i); + + /* + * This leaks all the rest of the snapshot table and the + * snapshots' clusters, but we run in check -r all mode, + * so qcow2_check_refcounts() will take care of it. + */ + s->nb_snapshots =3D i; + offset =3D pre_sn_offset; + break; } } =20 @@ -214,7 +255,7 @@ fail: =20 int qcow2_read_snapshots(BlockDriverState *bs, Error **errp) { - return qcow2_do_read_snapshots(bs, false, NULL, errp); + return qcow2_do_read_snapshots(bs, false, NULL, NULL, errp); } =20 /* add at the end of the file a new list of snapshots */ @@ -382,6 +423,7 @@ int coroutine_fn qcow2_check_read_snapshot_table(BlockD= riverState *bs, { BDRVQcow2State *s =3D bs->opaque; Error *local_err =3D NULL; + int nb_clusters_reduced =3D 0; int extra_data_dropped =3D 0; int ret; struct { @@ -419,7 +461,8 @@ int coroutine_fn qcow2_check_read_snapshot_table(BlockD= riverState *bs, =20 qemu_co_mutex_unlock(&s->lock); ret =3D qcow2_do_read_snapshots(bs, fix & BDRV_FIX_ERRORS, - &extra_data_dropped, &local_err); + &nb_clusters_reduced, &extra_data_droppe= d, + &local_err); qemu_co_mutex_lock(&s->lock); if (ret < 0) { result->check_errors++; @@ -432,7 +475,32 @@ int coroutine_fn qcow2_check_read_snapshot_table(Block= DriverState *bs, =20 return ret; } - result->corruptions +=3D extra_data_dropped; + result->corruptions +=3D nb_clusters_reduced + extra_data_dropped; + + if (nb_clusters_reduced) { + /* + * Update image header now, because: + * (1) qcow2_check_refcounts() relies on s->nb_snapshots to be + * the same as what the image header says, + * (2) this leaks clusters, but qcow2_check_refcounts() will + * fix that. + */ + assert(fix & BDRV_FIX_ERRORS); + + snapshot_table_pointer.nb_snapshots =3D cpu_to_be32(s->nb_snapshot= s); + ret =3D bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, nb_snapsho= ts), + &snapshot_table_pointer.nb_snapshots, + sizeof(snapshot_table_pointer.nb_snapshots)= ); + if (ret < 0) { + result->check_errors++; + fprintf(stderr, "ERROR failed to update the snapshot count in = the " + "image header: %s\n", strerror(-ret)); + return ret; + } + + result->corruptions_fixed +=3D nb_clusters_reduced; + result->corruptions -=3D nb_clusters_reduced; + } =20 return 0; } --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808268; cv=none; d=zoho.com; s=zohoarc; b=KKKMyGZQC1XAfCYI5m+h+7JvoycECnJotCwDg2srRLNM8cHuOkziIQBP3VYokMsOW6JPbFZdqELyYQ93rJEpr+Q5mTzAcO2POLT71aoTkAnXE4BSyKZwHSLYdMBY0Z3bXBKRVZY9/QKBX5hmqoELYUZ4QFeyLGV+6ybk0Pl2mDg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808268; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=iZpAr5c9r6mQ1RYt8JFFF6fHIYtCETHDS9lTRJz13GY=; b=RXfPcMCTE1kPRrBvXtGlgd35RYFYmpS4nh6EZmE3rWazUktX3ZF4lfmFlO8P3YWq+vDrbxG1AkOfRdqJMscSNnkexR6z0CCQITpnv3xRooIdTowor8644Ce+CpVjZgfVoHlVzxq25myJmmoKgx1Q9qm/Yjb+mEs4TYMYTdYB5v0= 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 157080826866927.63500502096292; Fri, 11 Oct 2019 08:37:48 -0700 (PDT) Received: from localhost ([::1]:52298 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwzD-0002qX-43 for importer@patchew.org; Fri, 11 Oct 2019 11:37:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57969) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqg-0001vm-A3 for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqf-0006hM-3r for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:28:58 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58454) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqc-0006fc-NN; Fri, 11 Oct 2019 11:28:54 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id F1CD199C42; Fri, 11 Oct 2019 15:28:53 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 883C6453B; Fri, 11 Oct 2019 15:28:53 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 13/16] qcow2: Repair snapshot table with too many entries Date: Fri, 11 Oct 2019 17:28:11 +0200 Message-Id: <20191011152814.14791-14-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Fri, 11 Oct 2019 15:28:54 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" The user cannot choose which snapshots are removed. This is fine because we have chosen the maximum snapshot table size to be so large (65536 entries) that it cannot be reasonably reached. If the snapshot table exceeds this size, the image has probably been corrupted in some way; in this case, it is most important to just make the image usable such that the user can copy off at least the active layer. (Also note that the snapshots will be removed only with "-r all", so a plain "check" or "check -r leaks" will not delete any data.) Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2-snapshot.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 366d9f574c..dac8a778e4 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -444,6 +444,14 @@ int coroutine_fn qcow2_check_read_snapshot_table(Block= DriverState *bs, s->snapshots_offset =3D be64_to_cpu(snapshot_table_pointer.snapshots_o= ffset); s->nb_snapshots =3D be32_to_cpu(snapshot_table_pointer.nb_snapshots); =20 + if (s->nb_snapshots > QCOW_MAX_SNAPSHOTS && (fix & BDRV_FIX_ERRORS)) { + fprintf(stderr, "Discarding %u overhanging snapshots\n", + s->nb_snapshots - QCOW_MAX_SNAPSHOTS); + + nb_clusters_reduced +=3D s->nb_snapshots - QCOW_MAX_SNAPSHOTS; + s->nb_snapshots =3D QCOW_MAX_SNAPSHOTS; + } + ret =3D qcow2_validate_table(bs, s->snapshots_offset, s->nb_snapshots, sizeof(QCowSnapshotHeader), sizeof(QCowSnapshotHeader) * QCOW_MAX_SNAPS= HOTS, @@ -452,6 +460,12 @@ int coroutine_fn qcow2_check_read_snapshot_table(Block= DriverState *bs, result->check_errors++; error_reportf_err(local_err, "ERROR "); =20 + if (s->nb_snapshots > QCOW_MAX_SNAPSHOTS) { + fprintf(stderr, "You can force-remove all %u overhanging snaps= hots " + "with qemu-img check -r all\n", + s->nb_snapshots - QCOW_MAX_SNAPSHOTS); + } + /* We did not read the snapshot table, so invalidate this informat= ion */ s->snapshots_offset =3D 0; s->nb_snapshots =3D 0; --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808427; cv=none; d=zoho.com; s=zohoarc; b=JdmyFc+ofnyvblNk8Z8lL94dsplQttSy+xvDJL2q510c6k+LSN7vByVv8sFiJoHBA+SNwh+BTIk6RjHhOlX4n715xOenAqNF9O8BsTtS61OCqK7eq9yaEsTox/oX8lDzRxjRqpDyEnrzIykv+C5QqhZywEhWER89TCF2xUzpINQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808427; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=z77RBQL2XYxMS3AdxqbzS9TYFtCR/x+W9dQqKaW4VIs=; b=Mu0KAy1VAnKxXeXCEYOefgj6qnF0Ii9dQSD8J4xDdgjM8rir995wXKos3OpzClx1wetQFjqm0JQQ+4IklaOfkmz/3WXVcD77PXD0VhiOdCyYy3kfWA3A6trZUGowEhywwxXyBSVa944+4CySoyPY7r2zdaRVUgQVxE77Bqf1be8= 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 1570808427869784.7849054312106; Fri, 11 Oct 2019 08:40:27 -0700 (PDT) Received: from localhost ([::1]:52328 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIx1j-0006Pw-Dn for importer@patchew.org; Fri, 11 Oct 2019 11:40:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:57999) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqi-000235-Vd for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:29:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqh-0006jp-U5 for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:29:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56634) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqf-0006hI-KN; Fri, 11 Oct 2019 11:28:57 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D4CF3C059B80; Fri, 11 Oct 2019 15:28:56 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 5CFFC5D6C8; Fri, 11 Oct 2019 15:28:56 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 14/16] qcow2: Fix v3 snapshot table entry compliancy Date: Fri, 11 Oct 2019 17:28:12 +0200 Message-Id: <20191011152814.14791-15-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 11 Oct 2019 15:28:56 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" qcow2 v3 images require every snapshot table entry to have at least 16 bytes of extra data. If they do not, let qemu-img check -r all fix it. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- block/qcow2-snapshot.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index dac8a778e4..5ab64da1ec 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -516,6 +516,24 @@ int coroutine_fn qcow2_check_read_snapshot_table(Block= DriverState *bs, result->corruptions -=3D nb_clusters_reduced; } =20 + /* + * All of v3 images' snapshot table entries need to have at least + * 16 bytes of extra data. + */ + if (s->qcow_version >=3D 3) { + int i; + for (i =3D 0; i < s->nb_snapshots; i++) { + if (s->snapshots[i].extra_data_size < + sizeof_field(QCowSnapshotExtraData, vm_state_size_large) + + sizeof_field(QCowSnapshotExtraData, disk_size)) + { + result->corruptions++; + fprintf(stderr, "%s snapshot table entry %i is incomplete\= n", + fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i); + } + } + } + return 0; } =20 --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808587; cv=none; d=zoho.com; s=zohoarc; b=QrI4evuA83M1c5P7rEpKtc8NuduTjSDTwIBiESLJ+f+Xf/DY+cVfqP72LOogRljrvgeZqmsVnBNdr5vybwgsvJxCqmMR5Lxg1/UYC7b6Muol0CTtfnEjcVwtGjP9MSNFTAZaRGhTQfnWF6xGcLrUgEdD7uKqjjeDEReLm8EyKCY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808587; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=hmyvOy5tzwV0/Jx+MNFQhB0sEqdLfmxH1M0XowEG6mk=; b=UaIwpscvYl2YVFhqMxwTQpoSU3q/cJDcynSfEjwTiktMVu8a8bj2uIejQUxh4xDIAfvdnKX71OiMWJxTvIYf3kRN1EqcZeCHIw/i50RG993ExvOQr1lQqHdiJ+hd0g1vkUXFXHNB21lME6a7qzDPqHCT2tJXjA92PVnbVpnSl2Q= 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 1570808587560613.2585344455741; Fri, 11 Oct 2019 08:43:07 -0700 (PDT) Received: from localhost ([::1]:52376 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIx4I-0001pl-LQ for importer@patchew.org; Fri, 11 Oct 2019 11:43:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58024) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwql-00027x-Fi for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:29:05 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqk-0006lf-Fr for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:29:03 -0400 Received: from mx1.redhat.com ([209.132.183.28]:24413) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqi-0006jU-Dz; Fri, 11 Oct 2019 11:29:00 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A6791A26695; Fri, 11 Oct 2019 15:28:59 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4D2035C1B2; Fri, 11 Oct 2019 15:28:59 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 15/16] iotests: Add peek_file* functions Date: Fri, 11 Oct 2019 17:28:13 +0200 Message-Id: <20191011152814.14791-16-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.68]); Fri, 11 Oct 2019 15:28:59 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- tests/qemu-iotests/common.rc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 12b4751848..fa7bae2422 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -53,6 +53,26 @@ poke_file() printf "$3" | dd "of=3D$1" bs=3D1 "seek=3D$2" conv=3Dnotrunc &>/dev/nu= ll } =20 +# peek_file_le 'test.img' 512 2 =3D> 65534 +peek_file_le() +{ + # Wrap in echo $() to strip spaces + echo $(od -j"$2" -N"$3" --endian=3Dlittle -An -vtu"$3" "$1") +} + +# peek_file_be 'test.img' 512 2 =3D> 65279 +peek_file_be() +{ + # Wrap in echo $() to strip spaces + echo $(od -j"$2" -N"$3" --endian=3Dbig -An -vtu"$3" "$1") +} + +# peek_file_raw 'test.img' 512 2 =3D> '\xff\xfe' +peek_file_raw() +{ + dd if=3D"$1" bs=3D1 skip=3D"$2" count=3D"$3" status=3Dnone +} + =20 if ! . ./common.config then --=20 2.21.0 From nobody Sun May 19 23:34:09 2024 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=1570808699; cv=none; d=zoho.com; s=zohoarc; b=oCu/NbxQsExgPpKLrE1//zXNms6wojBgmXzwk6Xn0Td1hgi8Dd6U4CpyfTwDBrztfUXBNYhfhR94p7XnfImnWlugueE92c4FtOyBjbGQKduV8iU0pxAirNG40H5IRipK47mIDdtg/8oKRcrPrUKBPpIz+QC6bTiqB1lo1TrLk1o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1570808699; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=g000HfDs/3pKC9la1rLSSHfwYcofJeyGjZUErFlH8b0=; b=maFreCT9tQuBdTGCZ9fmlCNJYWxUk/O42IUzYGh7j/NXi3VTf3cP/RTOpDI7brPSEh+V21U93+NK234K29YhyY6s4m9cqxI6/NJs4232uYMxsnWTeEy3yu5F/sb/HFrlMAE7FD+E7jG7T49YHPqfruoWAFLKUC3k3+3YBBzM7P0= 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 1570808699949926.5801888927039; Fri, 11 Oct 2019 08:44:59 -0700 (PDT) Received: from localhost ([::1]:52416 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIx6A-0004CT-Rt for importer@patchew.org; Fri, 11 Oct 2019 11:44:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:58080) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iIwqy-0002Y0-6c for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:29:19 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iIwqu-0006oU-C5 for qemu-devel@nongnu.org; Fri, 11 Oct 2019 11:29:16 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42340) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iIwqm-0006lr-MZ; Fri, 11 Oct 2019 11:29:04 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EA4347E424; Fri, 11 Oct 2019 15:29:02 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DDBB45C1B2; Fri, 11 Oct 2019 15:29:01 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Subject: [PATCH v3 16/16] iotests: Test qcow2's snapshot table handling Date: Fri, 11 Oct 2019 17:28:14 +0200 Message-Id: <20191011152814.14791-17-mreitz@redhat.com> In-Reply-To: <20191011152814.14791-1-mreitz@redhat.com> References: <20191011152814.14791-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Fri, 11 Oct 2019 15:29:02 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Add a test how our qcow2 driver handles extra data in snapshot table entries, and how it repairs overly long snapshot tables. Signed-off-by: Max Reitz Reviewed-by: Eric Blake --- tests/qemu-iotests/261 | 523 +++++++++++++++++++++++++++++++++++++ tests/qemu-iotests/261.out | 346 ++++++++++++++++++++++++ tests/qemu-iotests/group | 1 + 3 files changed, 870 insertions(+) create mode 100755 tests/qemu-iotests/261 create mode 100644 tests/qemu-iotests/261.out diff --git a/tests/qemu-iotests/261 b/tests/qemu-iotests/261 new file mode 100755 index 0000000000..fb96bcfbe2 --- /dev/null +++ b/tests/qemu-iotests/261 @@ -0,0 +1,523 @@ +#!/usr/bin/env bash +# +# Test case for qcow2's handling of extra data in snapshot table entries +# (and more generally, how certain cases of broken snapshot tables are +# handled) +# +# Copyright (C) 2019 Red Hat, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# creator +owner=3Dmreitz@redhat.com + +seq=3D$(basename $0) +echo "QA output created by $seq" + +status=3D1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img + rm -f "$TEST_IMG".v{2,3}.orig + rm -f "$TEST_DIR"/sn{0,1,2}{,-pre,-extra,-post} +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +. ./common.rc +. ./common.filter + +# This tests qocw2-specific low-level functionality +_supported_fmt qcow2 +_supported_proto file +_supported_os Linux +# (1) We create a v2 image that supports nothing but refcount_bits=3D16 +# (2) We do some refcount management on our own which expects +# refcount_bits=3D16 +_unsupported_imgopts 'refcount_bits=3D\([^1]\|.\([^6]\|$\)\)' + +# Parameters: +# $1: image filename +# $2: snapshot table entry offset in the image +snapshot_table_entry_size() +{ + id_len=3D$(peek_file_be "$1" $(($2 + 12)) 2) + name_len=3D$(peek_file_be "$1" $(($2 + 14)) 2) + extra_len=3D$(peek_file_be "$1" $(($2 + 36)) 4) + + full_len=3D$((40 + extra_len + id_len + name_len)) + echo $(((full_len + 7) / 8 * 8)) +} + +# Parameter: +# $1: image filename +print_snapshot_table() +{ + nb_entries=3D$(peek_file_be "$1" 60 4) + offset=3D$(peek_file_be "$1" 64 8) + + echo "Snapshots in $1:" | _filter_testdir | _filter_imgfmt + + for ((i =3D 0; i < nb_entries; i++)); do + id_len=3D$(peek_file_be "$1" $((offset + 12)) 2) + name_len=3D$(peek_file_be "$1" $((offset + 14)) 2) + extra_len=3D$(peek_file_be "$1" $((offset + 36)) 4) + + extra_ofs=3D$((offset + 40)) + id_ofs=3D$((extra_ofs + extra_len)) + name_ofs=3D$((id_ofs + id_len)) + + echo " [$i]" + echo " ID: $(peek_file_raw "$1" $id_ofs $id_len)" + echo " Name: $(peek_file_raw "$1" $name_ofs $name_len)" + echo " Extra data size: $extra_len" + if [ $extra_len -ge 8 ]; then + echo " VM state size: $(peek_file_be "$1" $extra_ofs 8)" + fi + if [ $extra_len -ge 16 ]; then + echo " Disk size: $(peek_file_be "$1" $((extra_ofs + 8)) 8)" + fi + if [ $extra_len -gt 16 ]; then + echo ' Unknown extra data:' \ + "$(peek_file_raw "$1" $((extra_ofs + 16)) $((extra_len - 1= 6)) \ + | tr -d '\0')" + fi + + offset=3D$((offset + $(snapshot_table_entry_size "$1" $offset))) + done +} + +# Mark clusters as allocated; works only in refblock 0 (i.e. before +# cluster #32768). +# Parameters: +# $1: Start offset of what to allocate +# $2: End offset (exclusive) +refblock0_allocate() +{ + reftable_ofs=3D$(peek_file_be "$TEST_IMG" 48 8) + refblock_ofs=3D$(peek_file_be "$TEST_IMG" $reftable_ofs 8) + + cluster=3D$(($1 / 65536)) + ecluster=3D$((($2 + 65535) / 65536)) + + while [ $cluster -lt $ecluster ]; do + if [ $cluster -ge 32768 ]; then + echo "*** Abort: Cluster $cluster exceeds refblock 0 ***" + exit 1 + fi + poke_file "$TEST_IMG" $((refblock_ofs + cluster * 2)) '\x00\x01' + cluster=3D$((cluster + 1)) + done +} + + +echo +echo '=3D=3D=3D Create v2 template =3D=3D=3D' +echo + +# Create v2 image with a snapshot table with three entries: +# [0]: No extra data (valid with v2, not valid with v3) +# [1]: Has extra data unknown to qemu +# [2]: Has the 64-bit VM state size, but not the disk size (again, +# valid with v2, not valid with v3) + +TEST_IMG=3D"$TEST_IMG.v2.orig" IMGOPTS=3D'compat=3D0.10' _make_test_img 64M +$QEMU_IMG snapshot -c sn0 "$TEST_IMG.v2.orig" +$QEMU_IMG snapshot -c sn1 "$TEST_IMG.v2.orig" +$QEMU_IMG snapshot -c sn2 "$TEST_IMG.v2.orig" + +# Copy out all existing snapshot table entries +sn_table_ofs=3D$(peek_file_be "$TEST_IMG.v2.orig" 64 8) + +# ofs: Snapshot table entry offset +# eds: Extra data size +# ids: Name + ID size +# len: Total entry length +sn0_ofs=3D$sn_table_ofs +sn0_eds=3D$(peek_file_be "$TEST_IMG.v2.orig" $((sn0_ofs + 36)) 4) +sn0_ids=3D$(($(peek_file_be "$TEST_IMG.v2.orig" $((sn0_ofs + 12)) 2) + + $(peek_file_be "$TEST_IMG.v2.orig" $((sn0_ofs + 14)) 2))) +sn0_len=3D$(snapshot_table_entry_size "$TEST_IMG.v2.orig" $sn0_ofs) +sn1_ofs=3D$((sn0_ofs + sn0_len)) +sn1_eds=3D$(peek_file_be "$TEST_IMG.v2.orig" $((sn1_ofs + 36)) 4) +sn1_ids=3D$(($(peek_file_be "$TEST_IMG.v2.orig" $((sn1_ofs + 12)) 2) + + $(peek_file_be "$TEST_IMG.v2.orig" $((sn1_ofs + 14)) 2))) +sn1_len=3D$(snapshot_table_entry_size "$TEST_IMG.v2.orig" $sn1_ofs) +sn2_ofs=3D$((sn1_ofs + sn1_len)) +sn2_eds=3D$(peek_file_be "$TEST_IMG.v2.orig" $((sn2_ofs + 36)) 4) +sn2_ids=3D$(($(peek_file_be "$TEST_IMG.v2.orig" $((sn2_ofs + 12)) 2) + + $(peek_file_be "$TEST_IMG.v2.orig" $((sn2_ofs + 14)) 2))) +sn2_len=3D$(snapshot_table_entry_size "$TEST_IMG.v2.orig" $sn2_ofs) + +# Data before extra data +dd if=3D"$TEST_IMG.v2.orig" of=3D"$TEST_DIR/sn0-pre" bs=3D1 skip=3D$sn0_of= s count=3D40 \ + &> /dev/null +dd if=3D"$TEST_IMG.v2.orig" of=3D"$TEST_DIR/sn1-pre" bs=3D1 skip=3D$sn1_of= s count=3D40 \ + &> /dev/null +dd if=3D"$TEST_IMG.v2.orig" of=3D"$TEST_DIR/sn2-pre" bs=3D1 skip=3D$sn2_of= s count=3D40 \ + &> /dev/null + +# Extra data +dd if=3D"$TEST_IMG.v2.orig" of=3D"$TEST_DIR/sn0-extra" bs=3D1 \ + skip=3D$((sn0_ofs + 40)) count=3D$sn0_eds &> /dev/null +dd if=3D"$TEST_IMG.v2.orig" of=3D"$TEST_DIR/sn1-extra" bs=3D1 \ + skip=3D$((sn1_ofs + 40)) count=3D$sn1_eds &> /dev/null +dd if=3D"$TEST_IMG.v2.orig" of=3D"$TEST_DIR/sn2-extra" bs=3D1 \ + skip=3D$((sn2_ofs + 40)) count=3D$sn2_eds &> /dev/null + +# Data after extra data +dd if=3D"$TEST_IMG.v2.orig" of=3D"$TEST_DIR/sn0-post" bs=3D1 \ + skip=3D$((sn0_ofs + 40 + sn0_eds)) count=3D$sn0_ids \ + &> /dev/null +dd if=3D"$TEST_IMG.v2.orig" of=3D"$TEST_DIR/sn1-post" bs=3D1 \ + skip=3D$((sn1_ofs + 40 + sn1_eds)) count=3D$sn1_ids \ + &> /dev/null +dd if=3D"$TEST_IMG.v2.orig" of=3D"$TEST_DIR/sn2-post" bs=3D1 \ + skip=3D$((sn2_ofs + 40 + sn2_eds)) count=3D$sn2_ids \ + &> /dev/null + +# Amend them, one by one +# Set sn0's extra data size to 0 +poke_file "$TEST_DIR/sn0-pre" 36 '\x00\x00\x00\x00' +truncate -s 0 "$TEST_DIR/sn0-extra" +# Grow sn0-post to pad +truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn0-pre") - 40)) \ + "$TEST_DIR/sn0-post" + +# Set sn1's extra data size to 42 +poke_file "$TEST_DIR/sn1-pre" 36 '\x00\x00\x00\x2a' +truncate -s 42 "$TEST_DIR/sn1-extra" +poke_file "$TEST_DIR/sn1-extra" 16 'very important data' +# Grow sn1-post to pad +truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn1-pre") - 82)) \ + "$TEST_DIR/sn1-post" + +# Set sn2's extra data size to 8 +poke_file "$TEST_DIR/sn2-pre" 36 '\x00\x00\x00\x08' +truncate -s 8 "$TEST_DIR/sn2-extra" +# Grow sn2-post to pad +truncate -s $(($(snapshot_table_entry_size "$TEST_DIR/sn2-pre") - 48)) \ + "$TEST_DIR/sn2-post" + +# Construct snapshot table +cat "$TEST_DIR"/sn0-{pre,extra,post} \ + "$TEST_DIR"/sn1-{pre,extra,post} \ + "$TEST_DIR"/sn2-{pre,extra,post} \ + | dd of=3D"$TEST_IMG.v2.orig" bs=3D1 seek=3D$sn_table_ofs conv=3Dnotru= nc \ + &> /dev/null + +# Done! +TEST_IMG=3D"$TEST_IMG.v2.orig" _check_test_img +print_snapshot_table "$TEST_IMG.v2.orig" + +echo +echo '=3D=3D=3D Upgrade to v3 =3D=3D=3D' +echo + +cp "$TEST_IMG.v2.orig" "$TEST_IMG.v3.orig" +$QEMU_IMG amend -o compat=3D1.1 "$TEST_IMG.v3.orig" +TEST_IMG=3D"$TEST_IMG.v3.orig" _check_test_img +print_snapshot_table "$TEST_IMG.v3.orig" + +echo +echo '=3D=3D=3D Repair botched v3 =3D=3D=3D' +echo + +# Force the v2 file to be v3. v3 requires each snapshot table entry +# to have at least 16 bytes of extra data, so it will not comply to +# the qcow2 v3 specification; but we can fix that. +cp "$TEST_IMG.v2.orig" "$TEST_IMG" + +# Set version +poke_file "$TEST_IMG" 4 '\x00\x00\x00\x03' +# Increase header length (necessary for v3) +poke_file "$TEST_IMG" 100 '\x00\x00\x00\x68' +# Set refcount order (necessary for v3) +poke_file "$TEST_IMG" 96 '\x00\x00\x00\x04' + +_check_test_img -r all +print_snapshot_table "$TEST_IMG" + + +# From now on, just test the qcow2 version we are supposed to test. +# (v3 by default, v2 by choice through $IMGOPTS.) +# That works because we always write all known extra data when +# updating the snapshot table, independent of the version. + +if echo "$IMGOPTS" | grep -q 'compat=3D\(0\.10\|v2\)' 2> /dev/null; then + subver=3Dv2 +else + subver=3Dv3 +fi + +echo +echo '=3D=3D=3D Add new snapshot =3D=3D=3D' +echo + +cp "$TEST_IMG.$subver.orig" "$TEST_IMG" +$QEMU_IMG snapshot -c sn3 "$TEST_IMG" +_check_test_img +print_snapshot_table "$TEST_IMG" + +echo +echo '=3D=3D=3D Remove different snapshots =3D=3D=3D' + +for sn in sn0 sn1 sn2; do + echo + echo "--- $sn ---" + + cp "$TEST_IMG.$subver.orig" "$TEST_IMG" + $QEMU_IMG snapshot -d $sn "$TEST_IMG" + _check_test_img + print_snapshot_table "$TEST_IMG" +done + +echo +echo '=3D=3D=3D Reject too much unknown extra data =3D=3D=3D' +echo + +cp "$TEST_IMG.$subver.orig" "$TEST_IMG" +$QEMU_IMG snapshot -c sn3 "$TEST_IMG" + +sn_table_ofs=3D$(peek_file_be "$TEST_IMG" 64 8) +sn0_ofs=3D$sn_table_ofs +sn1_ofs=3D$((sn0_ofs + $(snapshot_table_entry_size "$TEST_IMG" $sn0_ofs))) +sn2_ofs=3D$((sn1_ofs + $(snapshot_table_entry_size "$TEST_IMG" $sn1_ofs))) +sn3_ofs=3D$((sn2_ofs + $(snapshot_table_entry_size "$TEST_IMG" $sn2_ofs))) + +# 64 kB of extra data should be rejected +# (Note that this also induces a refcount error, because it spills +# over to the next cluster. That's a good way to test that we can +# handle simultaneous snapshot table and refcount errors.) +poke_file "$TEST_IMG" $((sn3_ofs + 36)) '\x00\x01\x00\x00' + +# Print error +_img_info +echo +_check_test_img +echo + +# Should be repairable +_check_test_img -r all + +echo +echo '=3D=3D=3D Snapshot table too big =3D=3D=3D' +echo + +sn_table_ofs=3D$(peek_file_be "$TEST_IMG.v3.orig" 64 8) + +# Fill a snapshot with 1 kB of extra data, a 65535-char ID, and a +# 65535-char name, and repeat it as many times as necessary to fill +# 64 MB (the maximum supported by qemu) + +touch "$TEST_DIR/sn0" + +# Full size (fixed + extra + ID + name + padding) +sn_size=3D$((40 + 1024 + 65535 + 65535 + 2)) + +# We only need the fixed part, though. +truncate -s 40 "$TEST_DIR/sn0" + +# 65535-char ID string +poke_file "$TEST_DIR/sn0" 12 '\xff\xff' +# 65535-char name +poke_file "$TEST_DIR/sn0" 14 '\xff\xff' +# 1 kB of extra data +poke_file "$TEST_DIR/sn0" 36 '\x00\x00\x04\x00' + +# Create test image +_make_test_img 64M + +# Hook up snapshot table somewhere safe (at 1 MB) +poke_file "$TEST_IMG" 64 '\x00\x00\x00\x00\x00\x10\x00\x00' + +offset=3D1048576 +size_written=3D0 +sn_count=3D0 +while [ $size_written -le $((64 * 1048576)) ]; do + dd if=3D"$TEST_DIR/sn0" of=3D"$TEST_IMG" bs=3D1 seek=3D$offset conv=3D= notrunc \ + &> /dev/null + offset=3D$((offset + sn_size)) + size_written=3D$((size_written + sn_size)) + sn_count=3D$((sn_count + 1)) +done +truncate -s "$offset" "$TEST_IMG" + +# Give the last snapshot (the one to be removed) an L1 table so we can +# see how that is handled when repairing the image +# (Put it two clusters before 1 MB, and one L2 table one cluster +# before 1 MB) +poke_file "$TEST_IMG" $((offset - sn_size + 0)) \ + '\x00\x00\x00\x00\x00\x0e\x00\x00' +poke_file "$TEST_IMG" $((offset - sn_size + 8)) \ + '\x00\x00\x00\x01' + +# Hook up the L2 table +poke_file "$TEST_IMG" $((1048576 - 2 * 65536)) \ + '\x80\x00\x00\x00\x00\x0f\x00\x00' + +# Make sure all of the clusters we just hooked up are allocated: +# - The snapshot table +# - The last snapshot's L1 and L2 table +refblock0_allocate $((1048576 - 2 * 65536)) $offset + +poke_file "$TEST_IMG" 60 \ + "$(printf '%08x' $sn_count | sed -e 's/\(..\)/\\x\1/g')" + +# Print error +_img_info +echo +_check_test_img +echo + +# Should be repairable +_check_test_img -r all + +echo +echo "$((sn_count - 1)) snapshots should remain:" +echo " qemu-img info reports $(_img_info | grep -c '^ \{34\}') snapshots" +echo " Image header reports $(peek_file_be "$TEST_IMG" 60 4) snapshots" + +echo +echo '=3D=3D=3D Snapshot table too big with one entry with too much extra = data =3D=3D=3D' +echo + +# For this test, we reuse the image from the previous case, which has +# a snapshot table that is right at the limit. +# Our layout looks like this: +# - (a number of snapshot table entries) +# - One snapshot with $extra_data_size extra data +# - One normal snapshot that breaks the 64 MB boundary +# - One normal snapshot beyond the 64 MB boundary +# +# $extra_data_size is calculated so that simply by virtue of it +# decreasing to 1 kB, the penultimate snapshot will fit into 64 MB +# limit again. The final snapshot will always be beyond the limit, so +# that we can see that the repair algorithm does still determine the +# limit to be somewhere, even when truncating one snapshot's extra +# data. + +# The last case has removed the last snapshot, so calculate +# $old_offset to get the current image's real length +old_offset=3D$((offset - sn_size)) + +# The layout from the previous test had one snapshot beyond the 64 MB +# limit; we want the same (after the oversized extra data has been +# truncated to 1 kB), so we drop the last three snapshots and +# construct them from scratch. +offset=3D$((offset - 3 * sn_size)) +sn_count=3D$((sn_count - 3)) + +# Assuming we had already written one of the three snapshots +# (necessary so we can calculate $extra_data_size next). +size_written=3D$((size_written - 2 * sn_size)) + +# Increase the extra data size so we go past the limit +# (The -1024 comes from the 1 kB of extra data we already have) +extra_data_size=3D$((64 * 1048576 + 8 - sn_size - (size_written - 1024))) + +poke_file "$TEST_IMG" $((offset + 36)) \ + "$(printf '%08x' $extra_data_size | sed -e 's/\(..\)/\\x\1/g')" + +offset=3D$((offset + sn_size - 1024 + extra_data_size)) +size_written=3D$((size_written - 1024 + extra_data_size)) +sn_count=3D$((sn_count + 1)) + +# Write the two normal snapshots +for ((i =3D 0; i < 2; i++)); do + dd if=3D"$TEST_DIR/sn0" of=3D"$TEST_IMG" bs=3D1 seek=3D$offset conv=3D= notrunc \ + &> /dev/null + offset=3D$((offset + sn_size)) + size_written=3D$((size_written + sn_size)) + sn_count=3D$((sn_count + 1)) + + if [ $i =3D 0 ]; then + # Check that the penultimate snapshot is beyond the 64 MB limit + echo "Snapshot table size should equal $((64 * 1048576 + 8)):" \ + $size_written + echo + fi +done + +truncate -s $offset "$TEST_IMG" +refblock0_allocate $old_offset $offset + +poke_file "$TEST_IMG" 60 \ + "$(printf '%08x' $sn_count | sed -e 's/\(..\)/\\x\1/g')" + +# Print error +_img_info +echo +_check_test_img +echo + +# Just truncating the extra data should be sufficient to shorten the +# snapshot table so only one snapshot exceeds the extra size +_check_test_img -r all + +echo +echo '=3D=3D=3D Too many snapshots =3D=3D=3D' +echo + +# Create a v2 image, for speeds' sake: All-zero snapshot table entries +# are only valid in v2. +IMGOPTS=3D'compat=3D0.10' _make_test_img 64M + +# Hook up snapshot table somewhere safe (at 1 MB) +poke_file "$TEST_IMG" 64 '\x00\x00\x00\x00\x00\x10\x00\x00' +# "Create" more than 65536 snapshots (twice that many here) +poke_file "$TEST_IMG" 60 '\x00\x02\x00\x00' + +# 40-byte all-zero snapshot table entries are valid snapshots, but +# only in v2 (v3 needs 16 bytes of extra data, so we would have to +# write 131072x '\x10'). +truncate -s $((1048576 + 40 * 131072)) "$TEST_IMG" + +# But let us give one of the snapshots to be removed an L1 table so +# we can see how that is handled when repairing the image. +# (Put it two clusters before 1 MB, and one L2 table one cluster +# before 1 MB) +poke_file "$TEST_IMG" $((1048576 + 40 * 65536 + 0)) \ + '\x00\x00\x00\x00\x00\x0e\x00\x00' +poke_file "$TEST_IMG" $((1048576 + 40 * 65536 + 8)) \ + '\x00\x00\x00\x01' + +# Hook up the L2 table +poke_file "$TEST_IMG" $((1048576 - 2 * 65536)) \ + '\x80\x00\x00\x00\x00\x0f\x00\x00' + +# Make sure all of the clusters we just hooked up are allocated: +# - The snapshot table +# - The last snapshot's L1 and L2 table +refblock0_allocate $((1048576 - 2 * 65536)) $((1048576 + 40 * 131072)) + +# Print error +_img_info +echo +_check_test_img +echo + +# Should be repairable +_check_test_img -r all + +echo +echo '65536 snapshots should remain:' +echo " qemu-img info reports $(_img_info | grep -c '^ \{34\}') snapshots" +echo " Image header reports $(peek_file_be "$TEST_IMG" 60 4) snapshots" + +# success, all done +echo "*** done" +status=3D0 diff --git a/tests/qemu-iotests/261.out b/tests/qemu-iotests/261.out new file mode 100644 index 0000000000..2600354566 --- /dev/null +++ b/tests/qemu-iotests/261.out @@ -0,0 +1,346 @@ +QA output created by 261 + +=3D=3D=3D Create v2 template =3D=3D=3D + +Formatting 'TEST_DIR/t.IMGFMT.v2.orig', fmt=3DIMGFMT size=3D67108864 +No errors were found on the image. +Snapshots in TEST_DIR/t.IMGFMT.v2.orig: + [0] + ID: 1 + Name: sn0 + Extra data size: 0 + [1] + ID: 2 + Name: sn1 + Extra data size: 42 + VM state size: 0 + Disk size: 67108864 + Unknown extra data: very important data + [2] + ID: 3 + Name: sn2 + Extra data size: 8 + VM state size: 0 + +=3D=3D=3D Upgrade to v3 =3D=3D=3D + +No errors were found on the image. +Snapshots in TEST_DIR/t.IMGFMT.v3.orig: + [0] + ID: 1 + Name: sn0 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + [1] + ID: 2 + Name: sn1 + Extra data size: 42 + VM state size: 0 + Disk size: 67108864 + Unknown extra data: very important data + [2] + ID: 3 + Name: sn2 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + +=3D=3D=3D Repair botched v3 =3D=3D=3D + +Repairing snapshot table entry 0 is incomplete +Repairing snapshot table entry 2 is incomplete +The following inconsistencies were found and repaired: + + 0 leaked clusters + 2 corruptions + +Double checking the fixed image now... +No errors were found on the image. +Snapshots in TEST_DIR/t.IMGFMT: + [0] + ID: 1 + Name: sn0 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + [1] + ID: 2 + Name: sn1 + Extra data size: 42 + VM state size: 0 + Disk size: 67108864 + Unknown extra data: very important data + [2] + ID: 3 + Name: sn2 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + +=3D=3D=3D Add new snapshot =3D=3D=3D + +No errors were found on the image. +Snapshots in TEST_DIR/t.IMGFMT: + [0] + ID: 1 + Name: sn0 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + [1] + ID: 2 + Name: sn1 + Extra data size: 42 + VM state size: 0 + Disk size: 67108864 + Unknown extra data: very important data + [2] + ID: 3 + Name: sn2 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + [3] + ID: 4 + Name: sn3 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + +=3D=3D=3D Remove different snapshots =3D=3D=3D + +--- sn0 --- +No errors were found on the image. +Snapshots in TEST_DIR/t.IMGFMT: + [0] + ID: 2 + Name: sn1 + Extra data size: 42 + VM state size: 0 + Disk size: 67108864 + Unknown extra data: very important data + [1] + ID: 3 + Name: sn2 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + +--- sn1 --- +No errors were found on the image. +Snapshots in TEST_DIR/t.IMGFMT: + [0] + ID: 1 + Name: sn0 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + [1] + ID: 3 + Name: sn2 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + +--- sn2 --- +No errors were found on the image. +Snapshots in TEST_DIR/t.IMGFMT: + [0] + ID: 1 + Name: sn0 + Extra data size: 16 + VM state size: 0 + Disk size: 67108864 + [1] + ID: 2 + Name: sn1 + Extra data size: 42 + VM state size: 0 + Disk size: 67108864 + Unknown extra data: very important data + +=3D=3D=3D Reject too much unknown extra data =3D=3D=3D + +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Too much extra metadata in s= napshot table entry 3 +You can force-remove this extra metadata with qemu-img check -r all + +qemu-img: ERROR failed to read the snapshot table: Too much extra metadata= in snapshot table entry 3 +You can force-remove this extra metadata with qemu-img check -r all +qemu-img: Check failed: File too large + +Discarding too much extra metadata in snapshot table entry 3 (65536 > 1024) +ERROR cluster 10 refcount=3D0 reference=3D1 +Rebuilding refcount structure +Repairing cluster 1 refcount=3D1 reference=3D0 +Repairing cluster 2 refcount=3D1 reference=3D0 +The following inconsistencies were found and repaired: + + 0 leaked clusters + 2 corruptions + +Double checking the fixed image now... +No errors were found on the image. + +=3D=3D=3D Snapshot table too big =3D=3D=3D + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Snapshot table is too big +You can force-remove all 1 overhanging snapshots with qemu-img check -r all + +qemu-img: ERROR failed to read the snapshot table: Snapshot table is too b= ig +You can force-remove all 1 overhanging snapshots with qemu-img check -r all +qemu-img: Check failed: File too large + +Discarding 1 overhanging snapshots (snapshot table is too big) +Leaked cluster 14 refcount=3D1 reference=3D0 +Leaked cluster 15 refcount=3D1 reference=3D0 +Leaked cluster 1039 refcount=3D1 reference=3D0 +Leaked cluster 1040 refcount=3D1 reference=3D0 +Repairing cluster 14 refcount=3D1 reference=3D0 +Repairing cluster 15 refcount=3D1 reference=3D0 +Repairing cluster 1039 refcount=3D1 reference=3D0 +Repairing cluster 1040 refcount=3D1 reference=3D0 +The following inconsistencies were found and repaired: + + 4 leaked clusters + 1 corruptions + +Double checking the fixed image now... +No errors were found on the image. + +507 snapshots should remain: + qemu-img info reports 507 snapshots + Image header reports 507 snapshots + +=3D=3D=3D Snapshot table too big with one entry with too much extra data = =3D=3D=3D + +Snapshot table size should equal 67108872: 67108872 + +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Too much extra metadata in s= napshot table entry 505 +You can force-remove this extra metadata with qemu-img check -r all + +qemu-img: ERROR failed to read the snapshot table: Too much extra metadata= in snapshot table entry 505 +You can force-remove this extra metadata with qemu-img check -r all +qemu-img: Check failed: File too large + +Discarding too much extra metadata in snapshot table entry 505 (116944 > 1= 024) +Discarding 1 overhanging snapshots (snapshot table is too big) +Leaked cluster 1041 refcount=3D1 reference=3D0 +Leaked cluster 1042 refcount=3D1 reference=3D0 +Repairing cluster 1041 refcount=3D1 reference=3D0 +Repairing cluster 1042 refcount=3D1 reference=3D0 +The following inconsistencies were found and repaired: + + 2 leaked clusters + 2 corruptions + +Double checking the fixed image now... +No errors were found on the image. + +=3D=3D=3D Too many snapshots =3D=3D=3D + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 +qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Snapshot table too large + +qemu-img: ERROR snapshot table too large +You can force-remove all 65536 overhanging snapshots with qemu-img check -= r all +qemu-img: Check failed: File too large + +Discarding 65536 overhanging snapshots +Leaked cluster 14 refcount=3D1 reference=3D0 +Leaked cluster 15 refcount=3D1 reference=3D0 +Leaked cluster 56 refcount=3D1 reference=3D0 +Leaked cluster 57 refcount=3D1 reference=3D0 +Leaked cluster 58 refcount=3D1 reference=3D0 +Leaked cluster 59 refcount=3D1 reference=3D0 +Leaked cluster 60 refcount=3D1 reference=3D0 +Leaked cluster 61 refcount=3D1 reference=3D0 +Leaked cluster 62 refcount=3D1 reference=3D0 +Leaked cluster 63 refcount=3D1 reference=3D0 +Leaked cluster 64 refcount=3D1 reference=3D0 +Leaked cluster 65 refcount=3D1 reference=3D0 +Leaked cluster 66 refcount=3D1 reference=3D0 +Leaked cluster 67 refcount=3D1 reference=3D0 +Leaked cluster 68 refcount=3D1 reference=3D0 +Leaked cluster 69 refcount=3D1 reference=3D0 +Leaked cluster 70 refcount=3D1 reference=3D0 +Leaked cluster 71 refcount=3D1 reference=3D0 +Leaked cluster 72 refcount=3D1 reference=3D0 +Leaked cluster 73 refcount=3D1 reference=3D0 +Leaked cluster 74 refcount=3D1 reference=3D0 +Leaked cluster 75 refcount=3D1 reference=3D0 +Leaked cluster 76 refcount=3D1 reference=3D0 +Leaked cluster 77 refcount=3D1 reference=3D0 +Leaked cluster 78 refcount=3D1 reference=3D0 +Leaked cluster 79 refcount=3D1 reference=3D0 +Leaked cluster 80 refcount=3D1 reference=3D0 +Leaked cluster 81 refcount=3D1 reference=3D0 +Leaked cluster 82 refcount=3D1 reference=3D0 +Leaked cluster 83 refcount=3D1 reference=3D0 +Leaked cluster 84 refcount=3D1 reference=3D0 +Leaked cluster 85 refcount=3D1 reference=3D0 +Leaked cluster 86 refcount=3D1 reference=3D0 +Leaked cluster 87 refcount=3D1 reference=3D0 +Leaked cluster 88 refcount=3D1 reference=3D0 +Leaked cluster 89 refcount=3D1 reference=3D0 +Leaked cluster 90 refcount=3D1 reference=3D0 +Leaked cluster 91 refcount=3D1 reference=3D0 +Leaked cluster 92 refcount=3D1 reference=3D0 +Leaked cluster 93 refcount=3D1 reference=3D0 +Leaked cluster 94 refcount=3D1 reference=3D0 +Leaked cluster 95 refcount=3D1 reference=3D0 +Repairing cluster 14 refcount=3D1 reference=3D0 +Repairing cluster 15 refcount=3D1 reference=3D0 +Repairing cluster 56 refcount=3D1 reference=3D0 +Repairing cluster 57 refcount=3D1 reference=3D0 +Repairing cluster 58 refcount=3D1 reference=3D0 +Repairing cluster 59 refcount=3D1 reference=3D0 +Repairing cluster 60 refcount=3D1 reference=3D0 +Repairing cluster 61 refcount=3D1 reference=3D0 +Repairing cluster 62 refcount=3D1 reference=3D0 +Repairing cluster 63 refcount=3D1 reference=3D0 +Repairing cluster 64 refcount=3D1 reference=3D0 +Repairing cluster 65 refcount=3D1 reference=3D0 +Repairing cluster 66 refcount=3D1 reference=3D0 +Repairing cluster 67 refcount=3D1 reference=3D0 +Repairing cluster 68 refcount=3D1 reference=3D0 +Repairing cluster 69 refcount=3D1 reference=3D0 +Repairing cluster 70 refcount=3D1 reference=3D0 +Repairing cluster 71 refcount=3D1 reference=3D0 +Repairing cluster 72 refcount=3D1 reference=3D0 +Repairing cluster 73 refcount=3D1 reference=3D0 +Repairing cluster 74 refcount=3D1 reference=3D0 +Repairing cluster 75 refcount=3D1 reference=3D0 +Repairing cluster 76 refcount=3D1 reference=3D0 +Repairing cluster 77 refcount=3D1 reference=3D0 +Repairing cluster 78 refcount=3D1 reference=3D0 +Repairing cluster 79 refcount=3D1 reference=3D0 +Repairing cluster 80 refcount=3D1 reference=3D0 +Repairing cluster 81 refcount=3D1 reference=3D0 +Repairing cluster 82 refcount=3D1 reference=3D0 +Repairing cluster 83 refcount=3D1 reference=3D0 +Repairing cluster 84 refcount=3D1 reference=3D0 +Repairing cluster 85 refcount=3D1 reference=3D0 +Repairing cluster 86 refcount=3D1 reference=3D0 +Repairing cluster 87 refcount=3D1 reference=3D0 +Repairing cluster 88 refcount=3D1 reference=3D0 +Repairing cluster 89 refcount=3D1 reference=3D0 +Repairing cluster 90 refcount=3D1 reference=3D0 +Repairing cluster 91 refcount=3D1 reference=3D0 +Repairing cluster 92 refcount=3D1 reference=3D0 +Repairing cluster 93 refcount=3D1 reference=3D0 +Repairing cluster 94 refcount=3D1 reference=3D0 +Repairing cluster 95 refcount=3D1 reference=3D0 +The following inconsistencies were found and repaired: + + 42 leaked clusters + 65536 corruptions + +Double checking the fixed image now... +No errors were found on the image. + +65536 snapshots should remain: + qemu-img info reports 65536 snapshots + Image header reports 65536 snapshots +*** done diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index 5805a79d9e..5191dfcdf2 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -273,6 +273,7 @@ 256 rw quick 257 rw 258 rw quick +261 rw 262 rw quick migration 263 rw quick 265 rw auto quick --=20 2.21.0