From patchwork Tue Oct 1 19:27:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Shinkevich X-Patchwork-Id: 11169529 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7393413B1 for ; Tue, 1 Oct 2019 19:36:28 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 51E9E20B7C for ; Tue, 1 Oct 2019 19:36:28 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 51E9E20B7C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:47136 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFNwg-0002vP-Oh for patchwork-qemu-devel@patchwork.kernel.org; Tue, 01 Oct 2019 15:36:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48313) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFNo8-0004iF-Hk for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iFNo7-0001SC-10 for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:36 -0400 Received: from relay.sw.ru ([185.231.240.75]:45300) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iFNo6-0001Qi-PF; Tue, 01 Oct 2019 15:27:34 -0400 Received: from [172.16.25.136] (helo=dhcp-172-16-25-136.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.2) (envelope-from ) id 1iFNo2-00060a-Vx; Tue, 01 Oct 2019 22:27:31 +0300 From: Andrey Shinkevich To: qemu-devel@nongnu.org, qemu-block@nongnu.org Subject: [PATCH 1/6] qcow2: multiple clusters write compressed Date: Tue, 1 Oct 2019 22:27:15 +0300 Message-Id: <1569958040-697220-2-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 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: kwolf@redhat.com, fam@euphon.net, vsementsov@virtuozzo.com, jsnow@redhat.com, armbru@redhat.com, dgilbert@redhat.com, stefanha@redhat.com, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" QEMU currently supports writing compressed data of size less than or equal to one cluster. This patch allows writing QCOW2 compressed data that exceed one cluster. The implementation is simple, we split buffered data into separate clusters and write them using the existing functionality. For unaligned requests, we use a workaround that writes the data without compression. Suggested-by: Pavel Butsykin Suggested-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Andrey Shinkevich --- block/qcow2.c | 113 +++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 28 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 7961c05..54ccaf6 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -4152,10 +4152,8 @@ fail: return ret; } -/* XXX: put compressed sectors first, then all the cluster aligned - tables to avoid losing bytes in alignment */ static coroutine_fn int -qcow2_co_pwritev_compressed_part(BlockDriverState *bs, +qcow2_co_pwritev_compressed_task(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, size_t qiov_offset) { @@ -4165,36 +4163,14 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs, uint8_t *buf, *out_buf; uint64_t cluster_offset; - if (has_data_file(bs)) { - return -ENOTSUP; - } - - if (bytes == 0) { - /* align end of file to a sector boundary to ease reading with - sector based I/Os */ - int64_t len = bdrv_getlength(bs->file->bs); - if (len < 0) { - return len; - } - return bdrv_co_truncate(bs->file, len, PREALLOC_MODE_OFF, NULL); - } - - if (offset_into_cluster(s, offset)) { - return -EINVAL; - } + assert(bytes <= s->cluster_size); buf = qemu_blockalign(bs, s->cluster_size); - if (bytes != s->cluster_size) { - if (bytes > s->cluster_size || - offset + bytes != bs->total_sectors << BDRV_SECTOR_BITS) - { - qemu_vfree(buf); - return -EINVAL; - } + if (bytes < s->cluster_size) { /* Zero-pad last write if image size is not cluster aligned */ memset(buf + bytes, 0, s->cluster_size - bytes); } - qemu_iovec_to_buf(qiov, qiov_offset, buf, bytes); + qemu_iovec_to_buf(qiov, qiov_offset, buf, s->cluster_size); out_buf = g_malloc(s->cluster_size); @@ -4228,6 +4204,9 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs, BLKDBG_EVENT(s->data_file, BLKDBG_WRITE_COMPRESSED); ret = bdrv_co_pwrite(s->data_file, cluster_offset, out_len, out_buf, 0); + if (ret == -ENOTSUP) { + ret = qcow2_co_pwritev_part(bs, offset, bytes, qiov, qiov_offset, 0); + } if (ret < 0) { goto fail; } @@ -4239,6 +4218,84 @@ fail: return ret; } +static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task) +{ + Qcow2AioTask *t = container_of(task, Qcow2AioTask, task); + + assert(!t->cluster_type); + + return qcow2_co_pwritev_compressed_task(t->bs, t->offset, t->bytes, t->qiov, + t->qiov_offset); +} + +/* + * XXX: put compressed sectors first, then all the cluster aligned + tables to avoid losing bytes in alignment + */ +static coroutine_fn int +qcow2_co_pwritev_compressed_part(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, + QEMUIOVector *qiov, size_t qiov_offset) +{ + BDRVQcow2State *s = bs->opaque; + QCowL2Meta *l2meta = NULL; + AioTaskPool *aio = NULL; + uint64_t curr_off = 0; + int ret; + + if (has_data_file(bs)) { + return -ENOTSUP; + } + + if (bytes == 0) { + /* + * align end of file to a sector boundary to ease reading with + * sector based I/Os + */ + int64_t cluster_offset = bdrv_getlength(bs->file->bs); + if (cluster_offset < 0) { + return cluster_offset; + } + return bdrv_co_truncate(bs->file, cluster_offset, PREALLOC_MODE_OFF, + NULL); + } + + if (offset_into_cluster(s, offset)) { + return -EINVAL; + } + + while (bytes && aio_task_pool_status(aio) == 0) { + uint32_t chunk_size = MIN(bytes, s->cluster_size); + + assert((curr_off & (BDRV_SECTOR_SIZE - 1)) == 0); + assert((chunk_size & (BDRV_SECTOR_SIZE - 1)) == 0); + + if (!aio && chunk_size != bytes) { + aio = aio_task_pool_new(QCOW2_MAX_WORKERS); + } + + ret = qcow2_add_task(bs, aio, qcow2_co_pwritev_compressed_task_entry, + 0, 0, offset + curr_off, chunk_size, + qiov, qiov_offset, l2meta); + if (ret < 0) { + break; + } + qiov_offset += chunk_size; + curr_off += chunk_size; + bytes -= chunk_size; + } + + if (aio) { + aio_task_pool_wait_all(aio); + if (ret == 0) { + ret = aio_task_pool_status(aio); + } + g_free(aio); + } + + return ret; +} + static int coroutine_fn qcow2_co_preadv_compressed(BlockDriverState *bs, uint64_t file_cluster_offset, From patchwork Tue Oct 1 19:27:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Shinkevich X-Patchwork-Id: 11169535 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 39BB413B1 for ; Tue, 1 Oct 2019 19:39:16 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E7E4620700 for ; Tue, 1 Oct 2019 19:39:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E7E4620700 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:47160 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFNzO-0005Px-8K for patchwork-qemu-devel@patchwork.kernel.org; Tue, 01 Oct 2019 15:39:14 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48303) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFNo8-0004hT-Hs for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iFNo6-0001Ru-Px for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:35 -0400 Received: from relay.sw.ru ([185.231.240.75]:45306) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iFNo6-0001Qk-In; Tue, 01 Oct 2019 15:27:34 -0400 Received: from [172.16.25.136] (helo=dhcp-172-16-25-136.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.2) (envelope-from ) id 1iFNo3-00060a-4F; Tue, 01 Oct 2019 22:27:31 +0300 From: Andrey Shinkevich To: qemu-devel@nongnu.org, qemu-block@nongnu.org Subject: [PATCH 2/6] tests/qemu-iotests: add case of writing compressed data to multiple clusters. Date: Tue, 1 Oct 2019 22:27:16 +0300 Message-Id: <1569958040-697220-3-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 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: kwolf@redhat.com, fam@euphon.net, vsementsov@virtuozzo.com, jsnow@redhat.com, armbru@redhat.com, dgilbert@redhat.com, stefanha@redhat.com, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Add the test case to the iotest #214 that checks possibility of writing compressed data to more than one cluster. Signed-off-by: Andrey Shinkevich --- tests/qemu-iotests/214 | 9 +++++++++ tests/qemu-iotests/214.out | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/tests/qemu-iotests/214 b/tests/qemu-iotests/214 index 21ec8a2..5f437e4 100755 --- a/tests/qemu-iotests/214 +++ b/tests/qemu-iotests/214 @@ -89,6 +89,15 @@ _check_test_img -r all $QEMU_IO -c "read -P 0x11 0 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir $QEMU_IO -c "read -P 0x22 4M 4M" "$TEST_IMG" 2>&1 | _filter_qemu_io | _filter_testdir +echo +echo "=== Write compressed data to multiple clusters ===" +echo +# Create an empty image and fill three and half clusters with compressed data. +_make_test_img 2M -o cluster_size=0x10000 +data_size=3*0x10000+0x8000 +$QEMU_IO -c "write -c -P 0x11 0 256k" "$TEST_IMG" \ + 2>&1 | _filter_qemu_io | _filter_testdir + # success, all done echo '*** done' rm -f $seq.full diff --git a/tests/qemu-iotests/214.out b/tests/qemu-iotests/214.out index 0fcd8dc..2b908f6 100644 --- a/tests/qemu-iotests/214.out +++ b/tests/qemu-iotests/214.out @@ -32,4 +32,10 @@ read 4194304/4194304 bytes at offset 0 4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) read 4194304/4194304 bytes at offset 4194304 4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=== Write compressed data to multiple clusters === + +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=2097152 +wrote 262144/262144 bytes at offset 0 +256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) *** done From patchwork Tue Oct 1 19:27:17 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Shinkevich X-Patchwork-Id: 11169539 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5639113B1 for ; Tue, 1 Oct 2019 19:43:29 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 36499205C9 for ; Tue, 1 Oct 2019 19:43:29 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 36499205C9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:47200 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFO3U-0000sW-6z for patchwork-qemu-devel@patchwork.kernel.org; Tue, 01 Oct 2019 15:43:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48312) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFNo8-0004i9-Gp for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iFNo6-0001S6-UT for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:36 -0400 Received: from relay.sw.ru ([185.231.240.75]:45292) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iFNo6-0001Qj-N8; Tue, 01 Oct 2019 15:27:34 -0400 Received: from [172.16.25.136] (helo=dhcp-172-16-25-136.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.2) (envelope-from ) id 1iFNo3-00060a-Ay; Tue, 01 Oct 2019 22:27:31 +0300 From: Andrey Shinkevich To: qemu-devel@nongnu.org, qemu-block@nongnu.org Subject: [PATCH 3/6] block: support compressed write for copy-on-read Date: Tue, 1 Oct 2019 22:27:17 +0300 Message-Id: <1569958040-697220-4-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 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: kwolf@redhat.com, fam@euphon.net, vsementsov@virtuozzo.com, jsnow@redhat.com, armbru@redhat.com, dgilbert@redhat.com, stefanha@redhat.com, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Anton Nefedov Signed-off-by: Denis V. Lunev Signed-off-by: Andrey Shinkevich --- block/io.c | 21 ++++++++++++++++----- block/trace-events | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/block/io.c b/block/io.c index f8c3596..a7cd24f 100644 --- a/block/io.c +++ b/block/io.c @@ -1264,12 +1264,13 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, * allocating cluster in the image file. Note that this value may exceed * BDRV_REQUEST_MAX_BYTES (even when the original read did not), which * is one reason we loop rather than doing it all at once. + * Also, this is crucial for compressed copy-on-read. */ bdrv_round_to_clusters(bs, offset, bytes, &cluster_offset, &cluster_bytes); skip_bytes = offset - cluster_offset; trace_bdrv_co_do_copy_on_readv(bs, offset, bytes, - cluster_offset, cluster_bytes); + cluster_offset, cluster_bytes, flags); while (cluster_bytes) { int64_t pnum; @@ -1328,9 +1329,15 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(BdrvChild *child, /* This does not change the data on the disk, it is not * necessary to flush even in cache=writethrough mode. */ - ret = bdrv_driver_pwritev(bs, cluster_offset, pnum, - &local_qiov, 0, - BDRV_REQ_WRITE_UNCHANGED); + if (flags & BDRV_REQ_WRITE_COMPRESSED) { + ret = bdrv_driver_pwritev_compressed(bs, cluster_offset, + pnum, &local_qiov, + qiov_offset); + } else { + ret = bdrv_driver_pwritev(bs, cluster_offset, pnum, + &local_qiov, 0, + BDRV_REQ_WRITE_UNCHANGED); + } } if (ret < 0) { @@ -1396,7 +1403,11 @@ static int coroutine_fn bdrv_aligned_preadv(BdrvChild *child, * to pass through to drivers. For now, there aren't any * passthrough flags. */ assert(!(flags & ~(BDRV_REQ_NO_SERIALISING | BDRV_REQ_COPY_ON_READ | - BDRV_REQ_PREFETCH))); + BDRV_REQ_PREFETCH | BDRV_REQ_WRITE_COMPRESSED))); + + /* write compressed only makes sense with copy on read */ + assert(!(flags & BDRV_REQ_WRITE_COMPRESSED) || + (flags & BDRV_REQ_COPY_ON_READ)); /* Handle Copy on Read and associated serialisation */ if (flags & BDRV_REQ_COPY_ON_READ) { diff --git a/block/trace-events b/block/trace-events index 3aa27e6..f444548 100644 --- a/block/trace-events +++ b/block/trace-events @@ -14,7 +14,7 @@ blk_root_detach(void *child, void *blk, void *bs) "child %p blk %p bs %p" bdrv_co_preadv(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x" bdrv_co_pwritev(void *bs, int64_t offset, int64_t nbytes, unsigned int flags) "bs %p offset %"PRId64" nbytes %"PRId64" flags 0x%x" bdrv_co_pwrite_zeroes(void *bs, int64_t offset, int count, int flags) "bs %p offset %"PRId64" count %d flags 0x%x" -bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64 +bdrv_co_do_copy_on_readv(void *bs, int64_t offset, unsigned int bytes, int64_t cluster_offset, int64_t cluster_bytes, int flags) "bs %p offset %"PRId64" bytes %u cluster_offset %"PRId64" cluster_bytes %"PRId64" flags 0x%x" bdrv_co_copy_range_from(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x" bdrv_co_copy_range_to(void *src, uint64_t src_offset, void *dst, uint64_t dst_offset, uint64_t bytes, int read_flags, int write_flags) "src %p offset %"PRIu64" dst %p offset %"PRIu64" bytes %"PRIu64" rw flags 0x%x 0x%x" From patchwork Tue Oct 1 19:27:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Shinkevich X-Patchwork-Id: 11169533 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F2A3515AB for ; Tue, 1 Oct 2019 19:37:51 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D284F20B7C for ; Tue, 1 Oct 2019 19:37:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D284F20B7C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:47144 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFNy2-0004LG-0G for patchwork-qemu-devel@patchwork.kernel.org; Tue, 01 Oct 2019 15:37:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48340) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFNo9-0004jS-9h for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iFNo7-0001Sa-7w for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:37 -0400 Received: from relay.sw.ru ([185.231.240.75]:45302) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iFNo6-0001Qg-UZ; Tue, 01 Oct 2019 15:27:35 -0400 Received: from [172.16.25.136] (helo=dhcp-172-16-25-136.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.2) (envelope-from ) id 1iFNo3-00060a-In; Tue, 01 Oct 2019 22:27:31 +0300 From: Andrey Shinkevich To: qemu-devel@nongnu.org, qemu-block@nongnu.org Subject: [PATCH 4/6] qemu-nbd: add compression flag support Date: Tue, 1 Oct 2019 22:27:18 +0300 Message-Id: <1569958040-697220-5-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 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: kwolf@redhat.com, fam@euphon.net, vsementsov@virtuozzo.com, jsnow@redhat.com, armbru@redhat.com, dgilbert@redhat.com, stefanha@redhat.com, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Added possibility to write compressed data by using the blk_write_compressed. This action has the limitations of the format driver. For example we can't write compressed data over other. $ ./qemu-img create -f qcow2 -o size=10G ./image.qcow2 $ sudo ./qemu-nbd -c /dev/nbd0 ./image.qcow2 $ sudo dd if=/dev/sda1 of=/dev/nbd0 bs=10M count=10 10+0 records in 10+0 records out 104857600 bytes (105 MB) copied, 0,0890581 s, 1,2 GB/s $ sudo ./qemu-nbd -d /dev/nbd0 $ du -sh ./image.qcow2 101M ./image.qcow2 $ ./qemu-img create -f qcow2 -o size=10G ./image.qcow2 $ sudo ./qemu-nbd -C -c /dev/nbd0 ./image.qcow2 $ sudo dd if=/dev/sda1 of=/dev/nbd0 bs=10M count=10 10+0 records in 10+0 records out 104857600 bytes (105 MB) copied, 0,076046 s, 1,4 GB/s $ sudo ./qemu-nbd -d /dev/nbd0 $ du -sh ./image.qcow2 5,3M ./image.qcow2 Signed-off-by: Pavel Butsykin Signed-off-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Denis V. Lunev Signed-off-by: Andrey Shinkevich --- blockdev-nbd.c | 2 +- include/block/nbd.h | 7 ++++++- nbd/server.c | 8 +++++++- qemu-nbd.c | 18 ++++++++++++++++-- qemu-nbd.texi | 2 ++ 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 6a8b206..2a01a04 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -191,7 +191,7 @@ void qmp_nbd_server_add(const char *device, bool has_name, const char *name, } exp = nbd_export_new(bs, 0, len, name, NULL, bitmap, !writable, !writable, - NULL, false, on_eject_blk, errp); + 0, NULL, false, on_eject_blk, errp); if (!exp) { goto out; } diff --git a/include/block/nbd.h b/include/block/nbd.h index 316fd70..0032f73 100644 --- a/include/block/nbd.h +++ b/include/block/nbd.h @@ -25,6 +25,10 @@ #include "crypto/tlscreds.h" #include "qapi/error.h" +enum { + NBD_INTERNAL_FLAG_COMPRESS = 1 << 1, /* Use write compressed */ +}; + /* Handshake phase structs - this struct is passed on the wire */ struct NBDOption { @@ -330,7 +334,8 @@ typedef struct NBDClient NBDClient; NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, uint64_t size, const char *name, const char *desc, - const char *bitmap, bool readonly, bool shared, + const char *bitmap, bool readonly, + bool shared, uint32_t iflags, void (*close)(NBDExport *), bool writethrough, BlockBackend *on_eject_blk, Error **errp); void nbd_export_close(NBDExport *exp); diff --git a/nbd/server.c b/nbd/server.c index d8d1e62..96d581d 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -91,6 +91,7 @@ struct NBDExport { uint16_t nbdflags; QTAILQ_HEAD(, NBDClient) clients; QTAILQ_ENTRY(NBDExport) next; + uint32_t iflags; AioContext *ctx; @@ -1471,7 +1472,8 @@ static void nbd_eject_notifier(Notifier *n, void *data) NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, uint64_t size, const char *name, const char *desc, - const char *bitmap, bool readonly, bool shared, + const char *bitmap, bool readonly, + bool shared, uint32_t iflags, void (*close)(NBDExport *), bool writethrough, BlockBackend *on_eject_blk, Error **errp) { @@ -1525,6 +1527,7 @@ NBDExport *nbd_export_new(BlockDriverState *bs, uint64_t dev_offset, exp->nbdflags |= (NBD_FLAG_SEND_TRIM | NBD_FLAG_SEND_WRITE_ZEROES | NBD_FLAG_SEND_FAST_ZERO); } + exp->iflags = iflags; assert(size <= INT64_MAX - dev_offset); exp->size = QEMU_ALIGN_DOWN(size, BDRV_SECTOR_SIZE); @@ -2312,6 +2315,9 @@ static coroutine_fn int nbd_handle_request(NBDClient *client, if (request->flags & NBD_CMD_FLAG_FUA) { flags |= BDRV_REQ_FUA; } + if (exp->iflags & NBD_INTERNAL_FLAG_COMPRESS) { + flags |= BDRV_REQ_WRITE_COMPRESSED; + } ret = blk_pwrite(exp->blk, request->from + exp->dev_offset, data, request->len, flags); return nbd_send_generic_reply(client, request->handle, ret, diff --git a/qemu-nbd.c b/qemu-nbd.c index 9032b6d..3765c4b 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -139,6 +139,7 @@ static void usage(const char *name) " --discard=MODE set discard mode (ignore, unmap)\n" " --detect-zeroes=MODE set detect-zeroes mode (off, on, unmap)\n" " --image-opts treat FILE as a full set of image options\n" +" -C, --compress use data compression (if the target format supports it)\n" "\n" QEMU_HELP_BOTTOM "\n" , name, name, NBD_DEFAULT_PORT, "DEVICE"); @@ -602,6 +603,7 @@ int main(int argc, char **argv) BlockDriverState *bs; uint64_t dev_offset = 0; bool readonly = false; + uint32_t iflags = 0; bool disconnect = false; const char *bindto = NULL; const char *port = NULL; @@ -610,7 +612,7 @@ int main(int argc, char **argv) int64_t fd_size; QemuOpts *sn_opts = NULL; const char *sn_id_or_name = NULL; - const char *sopt = "hVb:o:p:rsnP:c:dvk:e:f:tl:x:T:D:B:L"; + const char *sopt = "hVb:o:p:CrsnP:c:dvk:e:f:tl:x:T:D:B:L"; struct option lopt[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, @@ -619,6 +621,7 @@ int main(int argc, char **argv) { "socket", required_argument, NULL, 'k' }, { "offset", required_argument, NULL, 'o' }, { "read-only", no_argument, NULL, 'r' }, + { "compress", no_argument, NULL, 'C'}, { "partition", required_argument, NULL, 'P' }, { "bitmap", required_argument, NULL, 'B' }, { "connect", required_argument, NULL, 'c' }, @@ -786,6 +789,9 @@ int main(int argc, char **argv) readonly = true; flags &= ~BDRV_O_RDWR; break; + case 'C': + iflags |= NBD_INTERNAL_FLAG_COMPRESS; + break; case 'P': warn_report("The '-P' option is deprecated; use --image-opts with " "a raw device wrapper for subset exports instead"); @@ -1117,6 +1123,14 @@ int main(int argc, char **argv) blk_set_enable_write_cache(blk, !writethrough); + if ((iflags & NBD_INTERNAL_FLAG_COMPRESS) && + !(bs->drv && bs->drv->bdrv_co_pwritev_compressed_part)) + { + error_report("Compression not supported for this file format %s", + argv[optind]); + exit(EXIT_FAILURE); + } + if (sn_opts) { ret = bdrv_snapshot_load_tmp(bs, qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID), @@ -1175,7 +1189,7 @@ int main(int argc, char **argv) export = nbd_export_new(bs, dev_offset, fd_size, export_name, export_description, bitmap, readonly, shared > 1, - nbd_export_closed, writethrough, NULL, + iflags, nbd_export_closed, writethrough, NULL, &error_fatal); if (device) { diff --git a/qemu-nbd.texi b/qemu-nbd.texi index 7f55657..26ea1ec 100644 --- a/qemu-nbd.texi +++ b/qemu-nbd.texi @@ -55,6 +55,8 @@ Force the use of the block driver for format @var{fmt} instead of auto-detecting. @item -r, --read-only Export the disk as read-only. +@item -C, --compress +Use data compression (if the target format supports it) @item -P, --partition=@var{num} Deprecated: Only expose MBR partition @var{num}. Understands physical partitions 1-4 and logical partition 5. New code should instead use From patchwork Tue Oct 1 19:27:19 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Shinkevich X-Patchwork-Id: 11169547 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4317013BD for ; Tue, 1 Oct 2019 19:52:41 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 21B0021855 for ; Tue, 1 Oct 2019 19:52:41 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 21B0021855 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:47548 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFOCO-000197-5O for patchwork-qemu-devel@patchwork.kernel.org; Tue, 01 Oct 2019 15:52:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48335) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFNo9-0004j2-5E for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iFNo7-0001SS-6S for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:36 -0400 Received: from relay.sw.ru ([185.231.240.75]:45312) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iFNo6-0001Qp-UX; Tue, 01 Oct 2019 15:27:35 -0400 Received: from [172.16.25.136] (helo=dhcp-172-16-25-136.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.2) (envelope-from ) id 1iFNo3-00060a-UZ; Tue, 01 Oct 2019 22:27:32 +0300 From: Andrey Shinkevich To: qemu-devel@nongnu.org, qemu-block@nongnu.org Subject: [PATCH 5/6] block-stream: add compress option Date: Tue, 1 Oct 2019 22:27:19 +0300 Message-Id: <1569958040-697220-6-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 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: kwolf@redhat.com, fam@euphon.net, vsementsov@virtuozzo.com, jsnow@redhat.com, armbru@redhat.com, dgilbert@redhat.com, stefanha@redhat.com, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Signed-off-by: Anton Nefedov Signed-off-by: Vladimir Sementsov-Ogievskiy Signed-off-by: Denis V. Lunev Signed-off-by: Andrey Shinkevich --- block/stream.c | 19 +++++++++++++------ blockdev.c | 14 +++++++++++++- hmp-commands.hx | 4 ++-- include/block/block_int.h | 3 ++- monitor/hmp-cmds.c | 5 +++-- qapi/block-core.json | 5 ++++- 6 files changed, 37 insertions(+), 13 deletions(-) diff --git a/block/stream.c b/block/stream.c index 5562ccb..51cc49e 100644 --- a/block/stream.c +++ b/block/stream.c @@ -36,15 +36,21 @@ typedef struct StreamBlockJob { char *backing_file_str; bool bs_read_only; bool chain_frozen; + bool compress; } StreamBlockJob; -static int coroutine_fn stream_populate(BlockBackend *blk, - int64_t offset, uint64_t bytes) +static int coroutine_fn stream_populate(BlockBackend *blk, int64_t offset, + uint64_t bytes, bool compress) { + int flags = BDRV_REQ_COPY_ON_READ | BDRV_REQ_PREFETCH; + + if (compress) { + flags |= BDRV_REQ_WRITE_COMPRESSED; + } + assert(bytes < SIZE_MAX); - return blk_co_preadv(blk, offset, bytes, NULL, - BDRV_REQ_COPY_ON_READ | BDRV_REQ_PREFETCH); + return blk_co_preadv(blk, offset, bytes, NULL, flags); } static void stream_abort(Job *job) @@ -167,7 +173,7 @@ static int coroutine_fn stream_run(Job *job, Error **errp) } trace_stream_one_iteration(s, offset, n, ret); if (copy) { - ret = stream_populate(blk, offset, n); + ret = stream_populate(blk, offset, n, s->compress); } if (ret < 0) { BlockErrorAction action = @@ -217,7 +223,7 @@ static const BlockJobDriver stream_job_driver = { void stream_start(const char *job_id, BlockDriverState *bs, BlockDriverState *base, const char *backing_file_str, - int creation_flags, int64_t speed, + int creation_flags, int64_t speed, bool compress, BlockdevOnError on_error, Error **errp) { StreamBlockJob *s; @@ -267,6 +273,7 @@ void stream_start(const char *job_id, BlockDriverState *bs, s->backing_file_str = g_strdup(backing_file_str); s->bs_read_only = bs_read_only; s->chain_frozen = true; + s->compress = compress; s->on_error = on_error; trace_stream_start(bs, base, s); diff --git a/blockdev.c b/blockdev.c index fbef684..290ee4b 100644 --- a/blockdev.c +++ b/blockdev.c @@ -3238,6 +3238,7 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, bool has_base_node, const char *base_node, bool has_backing_file, const char *backing_file, bool has_speed, int64_t speed, + bool has_compress, bool compress, bool has_on_error, BlockdevOnError on_error, bool has_auto_finalize, bool auto_finalize, bool has_auto_dismiss, bool auto_dismiss, @@ -3254,6 +3255,10 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, on_error = BLOCKDEV_ON_ERROR_REPORT; } + if (!has_compress) { + compress = false; + } + bs = bdrv_lookup_bs(device, device, errp); if (!bs) { return; @@ -3308,6 +3313,12 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, goto out; } + if (compress && bs->drv->bdrv_co_pwritev_compressed_part == NULL) { + error_setg(errp, "Compression is not supported for this drive %s", + bdrv_get_device_name(bs)); + goto out; + } + /* backing_file string overrides base bs filename */ base_name = has_backing_file ? backing_file : base_name; @@ -3319,7 +3330,8 @@ void qmp_block_stream(bool has_job_id, const char *job_id, const char *device, } stream_start(has_job_id ? job_id : NULL, bs, base_bs, base_name, - job_flags, has_speed ? speed : 0, on_error, &local_err); + job_flags, has_speed ? speed : 0, compress, on_error, + &local_err); if (local_err) { error_propagate(errp, local_err); goto out; diff --git a/hmp-commands.hx b/hmp-commands.hx index cfcc044..3a347fd 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -95,8 +95,8 @@ ETEXI { .name = "block_stream", - .args_type = "device:B,speed:o?,base:s?", - .params = "device [speed [base]]", + .args_type = "device:B,speed:o?,base:s?,compress:o?", + .params = "device [speed [base]] [compress]", .help = "copy data from a backing file into a block device", .cmd = hmp_block_stream, }, diff --git a/include/block/block_int.h b/include/block/block_int.h index 0422acd..5e7fce8 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -1065,6 +1065,7 @@ int is_windows_drive(const char *filename); * @creation_flags: Flags that control the behavior of the Job lifetime. * See @BlockJobCreateFlags * @speed: The maximum speed, in bytes per second, or 0 for unlimited. + * @compress: True to compress data. * @on_error: The action to take upon error. * @errp: Error object. * @@ -1077,7 +1078,7 @@ int is_windows_drive(const char *filename); */ void stream_start(const char *job_id, BlockDriverState *bs, BlockDriverState *base, const char *backing_file_str, - int creation_flags, int64_t speed, + int creation_flags, int64_t speed, bool compress, BlockdevOnError on_error, Error **errp); /** diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c index b2551c1..91201fe 100644 --- a/monitor/hmp-cmds.c +++ b/monitor/hmp-cmds.c @@ -2025,11 +2025,12 @@ void hmp_block_stream(Monitor *mon, const QDict *qdict) const char *device = qdict_get_str(qdict, "device"); const char *base = qdict_get_try_str(qdict, "base"); int64_t speed = qdict_get_try_int(qdict, "speed", 0); + bool compress = qdict_get_try_bool(qdict, "compress", false); qmp_block_stream(true, device, device, base != NULL, base, false, NULL, false, NULL, qdict_haskey(qdict, "speed"), speed, true, - BLOCKDEV_ON_ERROR_REPORT, false, false, false, false, - &error); + compress, true, BLOCKDEV_ON_ERROR_REPORT, + false, false, false, false, &error); hmp_handle_error(mon, &error); } diff --git a/qapi/block-core.json b/qapi/block-core.json index e6edd64..f41513f 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -2544,6 +2544,9 @@ # # @speed: the maximum speed, in bytes per second # +# @compress: true to compress data, if the target format supports it. +# (default: false). Since 4.1. +# # @on-error: the action to take on an error (default report). # 'stop' and 'enospc' can only be used if the block device # supports io-status (see BlockInfo). Since 1.3. @@ -2576,7 +2579,7 @@ { 'command': 'block-stream', 'data': { '*job-id': 'str', 'device': 'str', '*base': 'str', '*base-node': 'str', '*backing-file': 'str', '*speed': 'int', - '*on-error': 'BlockdevOnError', + '*compress': 'bool', '*on-error': 'BlockdevOnError', '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } } ## From patchwork Tue Oct 1 19:27:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrey Shinkevich X-Patchwork-Id: 11169541 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7670115AB for ; Tue, 1 Oct 2019 19:48:25 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 55F4F20842 for ; Tue, 1 Oct 2019 19:48:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 55F4F20842 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=virtuozzo.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:47330 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFO8F-0004nj-Pp for patchwork-qemu-devel@patchwork.kernel.org; Tue, 01 Oct 2019 15:48:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48327) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iFNo8-0004il-Rq for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:38 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iFNo7-0001Sk-CF for qemu-devel@nongnu.org; Tue, 01 Oct 2019 15:27:36 -0400 Received: from relay.sw.ru ([185.231.240.75]:45314) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iFNo7-0001RR-2P; Tue, 01 Oct 2019 15:27:35 -0400 Received: from [172.16.25.136] (helo=dhcp-172-16-25-136.sw.ru) by relay.sw.ru with esmtp (Exim 4.92.2) (envelope-from ) id 1iFNo4-00060a-7j; Tue, 01 Oct 2019 22:27:32 +0300 From: Andrey Shinkevich To: qemu-devel@nongnu.org, qemu-block@nongnu.org Subject: [PATCH 6/6] tests/qemu-iotests: add case for block-stream compress Date: Tue, 1 Oct 2019 22:27:20 +0300 Message-Id: <1569958040-697220-7-git-send-email-andrey.shinkevich@virtuozzo.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> References: <1569958040-697220-1-git-send-email-andrey.shinkevich@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 185.231.240.75 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: kwolf@redhat.com, fam@euphon.net, vsementsov@virtuozzo.com, jsnow@redhat.com, armbru@redhat.com, dgilbert@redhat.com, stefanha@redhat.com, andrey.shinkevich@virtuozzo.com, den@openvz.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" Add a test case to the iotest #030 that checks 'compress' option for a block-stream job. Signed-off-by: Andrey Shinkevich --- tests/qemu-iotests/030 | 49 +++++++++++++++++++++++++++++++++++++++++++++- tests/qemu-iotests/030.out | 4 ++-- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030 index f3766f2..13fe5a2 100755 --- a/tests/qemu-iotests/030 +++ b/tests/qemu-iotests/030 @@ -21,7 +21,8 @@ import time import os import iotests -from iotests import qemu_img, qemu_io +from iotests import qemu_img, qemu_io, qemu_img_pipe +import json backing_img = os.path.join(iotests.test_dir, 'backing.img') mid_img = os.path.join(iotests.test_dir, 'mid.img') @@ -956,6 +957,52 @@ class TestSetSpeed(iotests.QMPTestCase): self.cancel_and_wait(resume=True) +class TestCompressed(iotests.QMPTestCase): + + def setUp(self): + qemu_img('create', '-f', iotests.imgfmt, backing_img, '1M') + qemu_img('create', '-f', iotests.imgfmt, '-o', + 'backing_file=%s' % backing_img, mid_img) + qemu_img('create', '-f', iotests.imgfmt, '-o', + 'backing_file=%s' % mid_img, test_img) + qemu_io('-c', 'write -P 0x1 0 512k', backing_img) + self.vm = iotests.VM().add_drive(test_img, "backing.node-name=mid," + + "backing.backing.node-name=base") + self.vm.launch() + + def tearDown(self): + self.vm.shutdown() + os.remove(test_img) + os.remove(mid_img) + os.remove(backing_img) + + def test_stream_compress(self): + self.assert_no_active_block_jobs() + + result = self.vm.qmp('block-stream', device='mid', job_id='stream-mid') + self.assert_qmp(result, 'return', {}) + + self.wait_until_completed(drive='stream-mid') + for event in self.vm.get_qmp_events(wait=True): + if event['event'] == 'BLOCK_JOB_COMPLETED': + self.dictpath(event, 'data/device') + self.assert_qmp_absent(event, 'data/error') + + result = self.vm.qmp('block-stream', device='drive0', base=mid_img, + job_id='stream-top', compress=True) + self.assert_qmp(result, 'return', {}) + + self.wait_until_completed(drive='stream-top') + self.assert_no_active_block_jobs() + self.vm.shutdown() + + top = json.loads(qemu_img_pipe('info', '--output=json', test_img)) + mid = json.loads(qemu_img_pipe('info', '--output=json', mid_img)) + base = json.loads(qemu_img_pipe('info', '--output=json', backing_img)) + + self.assertEqual(mid['actual-size'], base['actual-size']) + self.assertLess(top['actual-size'], mid['actual-size']) + if __name__ == '__main__': iotests.main(supported_fmts=['qcow2', 'qed'], supported_protocols=['file']) diff --git a/tests/qemu-iotests/030.out b/tests/qemu-iotests/030.out index 6d9bee1..af8dac1 100644 --- a/tests/qemu-iotests/030.out +++ b/tests/qemu-iotests/030.out @@ -1,5 +1,5 @@ -........................... +............................ ---------------------------------------------------------------------- -Ran 27 tests +Ran 28 tests OK