From nobody Sat Sep 26 23:03:40 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=openvz.org ARC-Seal: i=1; a=rsa-sha256; t=1787763500; cv=none; d=zohomail.com; s=zohoarc; b=n4WSuPkad+oJiAVIwc0r5XWCqRsWk7EC9w2ITAMGl1JT8Q2x+8MO2ntlMmAJpW9oSEuWeZGEwZQKROOl5b9xiIySkhxLbBA9p79PIG3aJousmorsLYHWhWc773wnyqXMdba6eWJNfmzxdCbWQaSeHjjfCwWzHAqTCxDz6W5RnTo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787763500; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=IuftN2fEp9SnVagrlzn2dqlH7W1Bg2kkfW1a6i9OQzo=; b=dUY1RNBiJ3ieU2JHS62/GEi0f5KbGwuKNcI7IyYSSrcKR3ttD0ERlyTOqFTEvsOKc/cQMT5QHoOm1RqTfiN9QL3J03vEDCzJuDFcY6j55fVb9s4DZeBShpHvcou4H4qSZ4H+TRjqzzW+VxJzNXu+DJwg2tTC9uo0P6IoEPQs9XI= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787763499826163.71601262207923; Wed, 26 Aug 2026 09:58:19 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wzGwo-0006Ua-6P; Wed, 26 Aug 2026 12:57:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wzGwm-0006Sn-42 for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:57:56 -0400 Received: from mail-ej1-x634.google.com ([2a00:1450:4864:20::634]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wzGwk-00034K-5Y for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:57:55 -0400 Received: by mail-ej1-x634.google.com with SMTP id a640c23a62f3a-c25366c9b42so6491966b.2 for ; Wed, 26 Aug 2026 09:57:53 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:8a5:68e8:91b1:8a17]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c250a88ac46sm650557766b.29.2026.08.26.09.57.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 09:57:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1787763472; x=1788368272; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=IuftN2fEp9SnVagrlzn2dqlH7W1Bg2kkfW1a6i9OQzo=; b=H72UZRDu5nCzFTl4xqhyETAmOVt46q27N82nyrhEdb45HTaOnP7tKVOvQMbnZ/cPk+ GIYJpSMXJfbSqsFqKaU+9/2JFHqEOLB7DUVjQut0aeXrAqpdlfmmOKvVMtghwZXsXsmF Pzoed8Lzr7MUHuRigKNLP+5YyWCb7xNVg4IcJ8KGlbMUKqZh3a3a4mvvJXcuNSS5B7n6 h695kuhjkj/vzJAMsUNksI2XzroVSAJxJDWGgo5zmkO6DbmLX4J7rU4GYcTt0JAm9q6p gIoVjQfkPuHdnLcKcSbUOqN9EM7on5/iVo6pZC27IVdNdz8pQzXCuPNO4OeOiZ1jMUll 9stg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787763472; x=1788368272; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=IuftN2fEp9SnVagrlzn2dqlH7W1Bg2kkfW1a6i9OQzo=; b=eP1HqmFQjHxYH7phqy3CUjGLZpnmp0IeB0iecVIZC/FQROYFM5SC5qPkpZyuxomcNg 8l7sHIXMmhWNFTRrAhuSD2rAxSbow2fVQwT+JOZqcpiybjCBFQs/nvmpCtZTdiDa8r+s OxUWad6AIe5cIRsQCAMXqQ7eSsT5sXi2tIgQ7CkfsV4glflonBB6cGqSAq8Tdjv9HBEw u5f75yZTHfRB+qwCm5FNZ0TAX2X4IKBOhSEVDLaN5TMsvA/72iUXgqNjbcR0LMgXXc4g rv3FuaMQ1gkZn5dD+13OLnUiPFTSDzyd/f4YSwswFaYtEkVJvXsxwgSsv66hZsJtEbhZ V+VA== X-Gm-Message-State: AFuF++krcU1yzV3oZtmXhsdkXm+/WGGnwBxq+3/gaY9vn831knSi51g9 fy5CEZP3BcloUibu+p37wz5ObblNGkX44Z2SfbLyNzCmrHedLMnIRovaxkNa9N9eMzHja9D1iT1 48+/i X-Gm-Gg: AR+sD10S5Mief1f8jXth7ksqNEwnHrWHu0YE7SL8r+LoF2j2DvLXZzv63IH2JFShNUV b1JFQo1Tu0hO5laX8NDeopPZn7fIgOzsotAKD7P9UB+sZPccwh+z4RiuOwHxq5/a83I3g3FkTov SrmKwp19J+gYaVBhyjpHuj+HiEtB/B4WpkGHXKe0iNWU93osVK7ZAXs5O1qoUbrYQ9Y6EoJBRqV pJSce5J5bFQxeE9E+AuKugD9OZYnOgHHPm+z9dpK6s+85enosN7KJcqzbda3mJalQzgBKZZyhzQ NBDPBV2DFdoQYufrJ/n6JxxsSNH+Axfh0qyuAcbwPLnBFExSrqRVPrL8hRT7yoKd+14Qv1VpsJQ 5ViUd4iDsazpuxz57P8YFB8khC/6RXQ7e3doeoXEnHfCmBmOZmKu0lvr2fN8t7SjdLNoK7Te9C1 1fSFDDPmt+O5N6QfIuxqb5Ej3/wvns51xP3C5hv6hGEhpD0IVUBoMmytNlZXkJCaINF+Y= X-Received: by 2002:a17:907:1c87:b0:c21:180c:d82d with SMTP id a640c23a62f3a-c250c3bfa5dmr1021714366b.20.1787763471800; Wed, 26 Aug 2026 09:57:51 -0700 (PDT) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, "Denis V. Lunev" , Eric Blake , Vladimir Sementsov-Ogievskiy Subject: [PATCH 1/5] iotests: add coverage for NBD transmission commands Date: Wed, 26 Aug 2026 18:57:43 +0200 Message-ID: <20260826165747.3768674-2-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826165747.3768674-1-den@openvz.org> References: <20260826165747.3768674-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::634; envelope-from=den@openvz.org; helo=mail-ej1-x634.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @openvz.org) X-ZM-MESSAGEID: 1787763501225158500 Content-Type: text/plain; charset="utf-8" From: Denis V. Lunev NBD_CMD_CACHE has no coverage anywhere in the tree. Nothing ever sends it: our own NBD client does not implement the command, and neither qemu-io nor 'qemu-nbd --list' can issue one, so the only clients reaching this server path are external ones. Add a test driven by libnbd, gated the way nbd-multiconn already is, and start it with the case the command exists for. The export is a qcow2 image over a fully written backing file, so a prefetch has visible work to do. Signed-off-by: Denis V. Lunev CC: Eric Blake CC: Vladimir Sementsov-Ogievskiy Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/tests/nbd-commands | 136 ++++++++++++++++++++++ tests/qemu-iotests/tests/nbd-commands.out | 5 + 2 files changed, 141 insertions(+) create mode 100755 tests/qemu-iotests/tests/nbd-commands create mode 100644 tests/qemu-iotests/tests/nbd-commands.out diff --git a/tests/qemu-iotests/tests/nbd-commands b/tests/qemu-iotests/tes= ts/nbd-commands new file mode 100755 index 0000000000..73baeb236f --- /dev/null +++ b/tests/qemu-iotests/tests/nbd-commands @@ -0,0 +1,136 @@ +#!/usr/bin/env python3 +# group: rw auto quick +# +# Test NBD transmission commands against a qemu NBD export +# +# Copyright (C) 2026 Virtuozzo International GmbH +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import os +from contextlib import contextmanager +from types import ModuleType + +import iotests +from iotests import qemu_img_create, qemu_img_map, qemu_io + + +base =3D os.path.join(iotests.test_dir, 'base') +top =3D os.path.join(iotests.test_dir, 'top') +# Larger than the maximum payload size an export can advertise +size =3D 64 * 1024 * 1024 +pattern =3D 0xa5 +nbd_sock =3D os.path.join(iotests.sock_dir, 'nbd_sock') +nbd_uri =3D 'nbd+unix:///exp?socket=3D' + nbd_sock +nbd: ModuleType + +DEPTH_LOCAL =3D 1 +DEPTH_BACKING =3D 2 + + +class TestNbdCommands(iotests.QMPTestCase): + def setUp(self): + qemu_img_create('-f', iotests.imgfmt, base, str(size)) + qemu_io('-c', f'write -P {pattern} 0 {size}', base) + qemu_img_create('-f', iotests.imgfmt, '-b', base, + '-F', iotests.imgfmt, top, str(size)) + + self.vm =3D iotests.VM() + self.vm.launch() + self.vm.cmd('blockdev-add', { + 'driver': iotests.imgfmt, + 'node-name': 'n', + 'file': {'driver': 'file', 'filename': top}, + 'backing': { + 'driver': iotests.imgfmt, + 'node-name': 'base', + 'file': {'driver': 'file', 'filename': base}, + }, + }) + self.vm.cmd('nbd-server-start', { + 'addr': {'type': 'unix', 'data': {'path': nbd_sock}} + }) + self.vm.cmd('block-export-add', { + 'type': 'nbd', + 'id': 'exp', + 'node-name': 'n', + 'name': 'exp', + 'writable': True, + 'allocation-depth': True, + }) + + def tearDown(self): + self.vm.shutdown() + for f in (top, base, nbd_sock): + try: + os.remove(f) + except OSError: + pass + + @contextmanager + def open_nbd(self, structured=3DTrue, extended=3DTrue): + h =3D nbd.NBD() + h.set_request_structured_replies(structured) + h.set_request_extended_headers(extended) + h.add_meta_context('base:allocation') + h.add_meta_context('qemu:allocation-depth') + # Let the server, not libnbd, reject the out of range requests bel= ow + h.set_strict_mode(h.get_strict_mode() & + ~(nbd.STRICT_BOUNDS | nbd.STRICT_PAYLOAD)) + try: + h.connect_uri(nbd_uri) + self.assertEqual(h.get_structured_replies_negotiated(), struct= ured) + self.assertEqual(h.get_extended_headers_negotiated(), extended) + yield h + finally: + h.shutdown() + + def allocation_depth(self, h): + extents =3D [] + + def cb(meta, offset, entries, err): + if meta =3D=3D 'qemu:allocation-depth': + extents.extend(zip(entries[0::2], entries[1::2])) + + h.block_status(size, 0, cb) + return extents + + def top_extents(self): + """Which parts of the top image are local, once qemu has let go.""" + self.vm.shutdown() + return [(e['start'], e['length'], e['depth']) + for e in qemu_img_map(top)] + + def test_cache_copies_on_read(self): + with self.open_nbd() as h: + maximum =3D h.get_block_size(nbd.SIZE_MAXIMUM) + self.assertLess(maximum, size) + self.assertEqual(self.allocation_depth(h), + [(size, DEPTH_BACKING)]) + + h.cache(maximum, 0) + + self.assertEqual(self.top_extents(), + [(0, maximum, 0), (maximum, size - maximum, 1)]) + qemu_io('-c', f'read -P {pattern} 0 {size}', top) + + def test_cache_past_end_of_export(self): + with self.open_nbd() as h: + self.assertRaises(nbd.Error, h.cache, size + 1, 0) + + def test_read_bound_by_max_payload(self): + with self.open_nbd() as h: + maximum =3D h.get_block_size(nbd.SIZE_MAXIMUM) + self.assertRaises(nbd.Error, h.pread, maximum + 65536, 0) + + +if __name__ =3D=3D '__main__': + try: + # Easier to use libnbd than to try and set up parallel + # 'qemu-nbd --list' or 'qemu-io' processes, but not all systems + # have libnbd installed. + import nbd # type: ignore + + iotests.main(supported_fmts=3D['qcow2']) + except ImportError: + iotests.notrun('Python bindings to libnbd are not installed') diff --git a/tests/qemu-iotests/tests/nbd-commands.out b/tests/qemu-iotests= /tests/nbd-commands.out new file mode 100644 index 0000000000..8d7e996700 --- /dev/null +++ b/tests/qemu-iotests/tests/nbd-commands.out @@ -0,0 +1,5 @@ +... +---------------------------------------------------------------------- +Ran 3 tests + +OK --=20 2.53.0 From nobody Sat Sep 26 23:03:40 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=openvz.org ARC-Seal: i=1; a=rsa-sha256; t=1787763541; cv=none; d=zohomail.com; s=zohoarc; b=AYWsuXPARtP3hmqN/yvT46rpPqblf+46Hgd0jWL7zGiUQamHs0H9oyDQqy6Hx0q65vVIZvYvus9E53XOPWHPNfXJITWSnhW1PYjbHZdOl8+bIzNvUSm1fYQ25aEIL7sRdp0JDKTRxbL78OwNXVZE30qFMRBx+68vtUNxo+Auzwc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787763541; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=AgMaBiRcFOPbEemdJbEgsISRcRJz2Jh2uGEXsfazQ8Q=; b=JV/T7H3oMCJu17pui3xwES9x20N1z8ju+cSdxvmWpRQTq6p2MqLNTarRe2naFISYSPcEWmWccHCUAxvEjGrAb18m3ldI0bnLYV1MS6ftOHo1t7QwxUj/VGT51eBupFy2zhJlKrl+4N6U1g3EL1ZpFW7JRUMFlftm0nzl61AfpVE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787763541230143.93412978157824; Wed, 26 Aug 2026 09:59:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wzGwp-0006Vb-6a; Wed, 26 Aug 2026 12:57:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wzGwm-0006TY-PT for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:57:56 -0400 Received: from mail-ed1-x530.google.com ([2a00:1450:4864:20::530]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wzGwk-00034U-LJ for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:57:56 -0400 Received: by mail-ed1-x530.google.com with SMTP id 4fb4d7f45d1cf-6a5e866bca0so1483978a12.0 for ; Wed, 26 Aug 2026 09:57:54 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:8a5:68e8:91b1:8a17]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c250a88ac46sm650557766b.29.2026.08.26.09.57.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 09:57:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1787763473; x=1788368273; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=AgMaBiRcFOPbEemdJbEgsISRcRJz2Jh2uGEXsfazQ8Q=; b=NNQ5PyQyxIfnytJL26w0RgLC2gDBmFvIIFpIZAMQlL6H2+w0PggA8EZNtUJxeZ3WQQ lqMFCdZCD/Y4mtCU9jUzX0Tm0D0RyXy/ZHFbFU+Hf0MKQGU6fF11acLN9A8LE22Jdoa4 PLmSY5tW8jERWvsc4GWqbjwBGJh2GQAhbYOmB7hRd87t6H5v2r1AzUTEu5mqtC7WuVgh 3zFtamfJAX8+zxm7JoKHG+eZBIM0jODUDJoLARsa/McQX1hr03IhnOgEJQN0cJ44RRny 8Z3hPgRjr7H2Y0y7Lg2uIi2l79o6edLuyRvuVXSFTkfhKw2FO1fFDlmJDgsfSbyQeJ8X EsCA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787763473; x=1788368273; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=AgMaBiRcFOPbEemdJbEgsISRcRJz2Jh2uGEXsfazQ8Q=; b=dOE0vMWBFGcwQ4f6lbulXbpTLy1XWlP3ohtszSzjUo7RCYXV0YS39AhO8UiD93Pyqw ju6/yt6CJoEbClFyfGeJTKapuC5bKXNRE0a2wrRMW8rc/pD20pdmYUBjlb0G6jHr2Oou jHQ0+osnLlaS8EHYd9foLuXJ0aWezJzckBsl6QMF2rOnecBoaAwR3WKMdI1V4PWncUYT UK16bJagA7349elgqx5uEMWc3qSdZXe1fHGSeTA2SzzE7luIpt5wpdzaPpE3Q57WNDcd ShKdH3ZuYwLFcUimdNOIzOOahtNx8Qmkh79GPs/zkuWzTMENHv3PYmaXcclfhjq5r0uX kqkg== X-Gm-Message-State: AFuF++kEAuexLZqaECp7x90zgbBgvLjBvYafi67AJ+MhQXYCt9pmKEpE zu+7ZWFGFJl+ZGVLQTC10Liz7W/b0nrj/qVzMWAyIVmv2r0nA+PSaDXVs/aZGXji5FVzzM5BXrW XHflz X-Gm-Gg: AR+sD11/mUcUP+OMM1jchiOVu5j8soqrhdtLdlnhZVEyewCAaJuznUO2e0qgAOtICUX BAXilZ3PnRC2dy6CAOol/7zDfJGJaGWJgylTKZj+O5hBcXO02mfo4l1Uin6SIEE+ED2rMtltS7j 0+cgJuzkR+HkNDlA1/T7t64tgTzPBIwVQ89ZFkua+kpFBy3ruHBR0ZJ7yAV1Le9ctu+1nrjs8Qa tLxYYu2K7/KtZsy7RlECb0+pIYLo1+XN2M1STUP8OKO2IqzzNHJMBMwqc5xDznrrK7jTxrxg2Ib Fq0NgzCz2ACWkBHjXUGSycI+DLId/zUx8TTur6XmR+5Si5SWBF+FXe8R07rI+lZBy16pUYofK6l EdOlxbfoQVtwfulfabTg79CSxF41I11y8+D7eCkG64V22gg68XZisBC1YnLiriYGOgMo8NIyj6w cM/M9Lc2sd0fYpviu12L4UwWo1maUfsryMgfnEgVL44MoZW+4xRPeQG1iT X-Received: by 2002:a17:907:7203:b0:c20:fda7:1856 with SMTP id a640c23a62f3a-c250bb76be9mr946057766b.8.1787763472935; Wed, 26 Aug 2026 09:57:52 -0700 (PDT) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, "Denis V. Lunev" , Eric Blake , Vladimir Sementsov-Ogievskiy Subject: [PATCH 2/5] nbd/server: accept NBD_CMD_CACHE above the maximum payload size Date: Wed, 26 Aug 2026 18:57:44 +0200 Message-ID: <20260826165747.3768674-3-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826165747.3768674-1-den@openvz.org> References: <20260826165747.3768674-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::530; envelope-from=den@openvz.org; helo=mail-ed1-x530.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @openvz.org) X-ZM-MESSAGEID: 1787763543711158500 Content-Type: text/plain; charset="utf-8" From: Denis V. Lunev NBD_CMD_CACHE carries no payload in either direction. The request is a header only, nbd_do_cmd_cache() passes a NULL qiov to blk_co_preadv(), and the reply is a bare status. Still the server rejects any effect length above NBD_MAX_BUFFER_SIZE with EINVAL, which forces a client to split a large prefetch into 32 MiB pieces. The specification does not ask for this. The constraint was renamed from "maximum block size" to "maximum payload size" precisely to separate payload length from effect length, and it says: For commands that do not require a payload in either direction (such as NBD_CMD_TRIM or NBD_CMD_WRITE_ZEROES), the client MAY request an effect length larger than the maximum payload size; the server SHOULD NOT disconnect, but MAY reply with an NBD_EOVERFLOW or NBD_EINVAL error if the oversize request would require too many server resources when compared to the same command with an effect length limited to the maximum payload size (such as an implementation of NBD_CMD_WRITE_ZEROES that utilizes a scratch buffer). We already follow that for NBD_CMD_TRIM and NBD_CMD_WRITE_ZEROES, which carry no length check at all, and our client assumes a server supporting extended headers takes unlimited zero and trim lengths. Handle NBD_CMD_CACHE in the same way. Signed-off-by: Denis V. Lunev CC: Eric Blake CC: Vladimir Sementsov-Ogievskiy Reviewed-by: Vladimir Sementsov-Ogievskiy --- nbd/server.c | 4 +--- tests/qemu-iotests/tests/nbd-commands | 5 ++--- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index 78ec984409..e6c47f8c2e 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -2718,7 +2718,6 @@ static int coroutine_fn nbd_co_receive_request(NBDReq= uestData *req, break; =20 case NBD_CMD_CACHE: - check_length =3D true; break; =20 case NBD_CMD_WRITE_ZEROES: @@ -2752,7 +2751,7 @@ static int coroutine_fn nbd_co_receive_request(NBDReq= uestData *req, req->complete =3D true; } if (check_length && request->len > NBD_MAX_BUFFER_SIZE) { - /* READ, WRITE, CACHE */ + /* READ, WRITE */ error_setg(errp, "len (%" PRIu64 ") is larger than max len (%u)", request->len, NBD_MAX_BUFFER_SIZE); return -EINVAL; @@ -2908,7 +2907,6 @@ static coroutine_fn int nbd_do_cmd_cache(NBDClient *c= lient, NBDRequest *request, NBDExport *exp =3D client->exp; =20 assert(request->type =3D=3D NBD_CMD_CACHE); - assert(request->len <=3D NBD_MAX_BUFFER_SIZE); =20 ret =3D blk_co_preadv(exp->common.blk, request->from, request->len, NULL, BDRV_REQ_COPY_ON_READ | BDRV_REQ_PREFETCH); diff --git a/tests/qemu-iotests/tests/nbd-commands b/tests/qemu-iotests/tes= ts/nbd-commands index 73baeb236f..d2715b59a1 100755 --- a/tests/qemu-iotests/tests/nbd-commands +++ b/tests/qemu-iotests/tests/nbd-commands @@ -108,10 +108,9 @@ class TestNbdCommands(iotests.QMPTestCase): self.assertEqual(self.allocation_depth(h), [(size, DEPTH_BACKING)]) =20 - h.cache(maximum, 0) + h.cache(size, 0) =20 - self.assertEqual(self.top_extents(), - [(0, maximum, 0), (maximum, size - maximum, 1)]) + self.assertEqual(self.top_extents(), [(0, size, 0)]) qemu_io('-c', f'read -P {pattern} 0 {size}', top) =20 def test_cache_past_end_of_export(self): --=20 2.53.0 From nobody Sat Sep 26 23:03:40 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=openvz.org ARC-Seal: i=1; a=rsa-sha256; t=1787763527; cv=none; d=zohomail.com; s=zohoarc; b=KkbzjSW6WRY8q/3VIW1/Kg7Lq+rbcwsMNVbWhr3t6rHhL1IRDxWgkeKG8xXZXZnsbvdw5LhWiu9CE7ywReTKuZJGeQyvE/8nc4UdaAvORIMPKoKvMF402PVcmoixKl83j5vtO05le9muOT6lFJIDqSdf8SEmcQaVx4l/NfD9XHI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787763527; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=63p1kaAssd8j2xjruwrsiB3eUjoODKFeBod8GoDopGA=; b=JvWsj3MLfDKESlirpPLKfGEaboKR7UpBXDgtrYacQUv04+uW8XLIkQGAQqGuPFmrbowP2i5I1y/IkkNcWGCKlbdR1ngE9rTXbubQyk1qTu6JDD9jaFe2RlBsE0xVTcqiF+yMmpCZMyQE/8L8dDQnVUKHBLX4B7Qfq8brPnQ3jVM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787763527059761.466924783688; Wed, 26 Aug 2026 09:58:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wzGwo-0006Ur-JG; Wed, 26 Aug 2026 12:57:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wzGwn-0006Ts-Ch for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:57:57 -0400 Received: from mail-ej1-x62a.google.com ([2a00:1450:4864:20::62a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wzGwl-000351-IV for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:57:57 -0400 Received: by mail-ej1-x62a.google.com with SMTP id a640c23a62f3a-c25099bb1fbso159293466b.3 for ; Wed, 26 Aug 2026 09:57:55 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:8a5:68e8:91b1:8a17]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c250a88ac46sm650557766b.29.2026.08.26.09.57.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 09:57:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1787763474; x=1788368274; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=63p1kaAssd8j2xjruwrsiB3eUjoODKFeBod8GoDopGA=; b=Ce8Ssu0xpfM9x++LtHJF0Cn/wkB1moW6j4UeXg18OZplyoA/WoCRW+8BS32IX2ZB06 RmUHkYDHyVUIjOfzKpq8D+slRNwQ9fhTDvvWRGdPRnF9pP3jHBZdBkUxe3P4GInwQDxY nBg2scKmJVrIUlCg4NI7Gq+u+vNgjSwnzFko5l4XhN+UG67wVB6hEtX/tqDT0Op0B08k MSzMr88zB0JyJ2PfRptVH0my89VK4a0n6VltFh5L6tqg9zMOem6BRqPLgSJvJ4nk2j4N HBD4UhP7+ITMJOGiKp4wEIwmkSPV648brGWP8dpXSj3XOrIw3p3eY7vYe/nI+ntlsN43 NeDA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787763474; x=1788368274; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=63p1kaAssd8j2xjruwrsiB3eUjoODKFeBod8GoDopGA=; b=pwQdfGCyquA6BKiepJ1dfVy99Jx4/z5lJsDPVQYjrwKtRIv3kMrYIgyAsAe+wU6eMl ePSoY5HjGNKMybX+AgvH50hz65Wl0UQD+xlldcwr2Epd64KjA/IQdx0nzH3a52cUVmvm A58mIYm8ZZ/sBjnz3jMJEyHFvhEEE/QEZ+I+WwtTQhoVOW6AewoTrsFsPqFl8czghOzD KUx9lXBk2Wq6pqKG+7b1HLnNrVGZzDZ7UG5xWkbDJzRhuLT5KzIWGU+USNAN6ck2kcXR mNkwdSjJP6j+pZYMp03XEuWKEqfY6+NIOI3ixGoGnAT3v1cREwyGN4tzkQay8B/0JdId Ysog== X-Gm-Message-State: AFuF++njtC0Xutc0wTz4jeFxZNCk8nO5ylHYejXdzmUZ+O/F6WWkqE0E x7AmbvJ4ZfYxNHw0vGfrt0mS3F4LJD41whtYa4ne9ez8Vawrn7r1NXH/SrKoWUY1R9Xx9OBD1Gi yPHvF X-Gm-Gg: AR+sD13D795TKBX/MoAXfErVVZnA2bIzm9rKpfOnqiQj/ubvb8+xmB4h2XawnHUmYId GRvNpdDuys8pr4cgUumMAuDrTXyrPR3RmynG/Bt5KooO7qDwBguzehZfb4v5H6O1MeBlFB+9e0u lBdJTLOrNW/tGUnfDegN+8kFK2Cf8yp9OqZzZHs8oZqNvAL0vSD4Ruvjc2OkTxtmzvgeUmLuEuf RWACaYlHWGQ3tuexGTKhwaSJLUqYkB9LSJcB/hviLWTHysIjwv/bvMAR0JtIiwLdl9UzffCpAYP +L1j963Rf1ktczGX8WN6u4q7Q5vncQgg5R4TYYFzHpHiHXwi3j+r5bTf5cju0p6Kp/T75QSSBPy b7IYjN8kwogAD+UeYUPa1/V+sx3W9W0+FnZZxKZBmjTmfhwHnIdg10HHrKkc9TbiOEu8r3PE1sE 2s+jJNAsdTPXl8E22Qw64edGdhk1oRG+R6NvUmOXAqVUwzlINOgaKwOxbA X-Received: by 2002:a17:907:ea8e:b0:c24:d914:6d64 with SMTP id a640c23a62f3a-c250c32cb23mr1054856066b.23.1787763474169; Wed, 26 Aug 2026 09:57:54 -0700 (PDT) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, "Denis V. Lunev" , Eric Blake , Vladimir Sementsov-Ogievskiy Subject: [PATCH 3/5] iotests/nbd-commands: exercise the simple and structured reply modes Date: Wed, 26 Aug 2026 18:57:45 +0200 Message-ID: <20260826165747.3768674-4-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826165747.3768674-1-den@openvz.org> References: <20260826165747.3768674-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::62a; envelope-from=den@openvz.org; helo=mail-ej1-x62a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @openvz.org) X-ZM-MESSAGEID: 1787763528640158500 Content-Type: text/plain; charset="utf-8" From: Denis V. Lunev Every NBD request the iotests send arrives in NBD_MODE_EXTENDED, so the server paths kept for older clients are never taken. Instrumenting nbd_co_receive_request() over the whole auto group and every test that touches NBD gives mode 4 for all of them, which leaves nbd_co_send_simple_reply() and the compact header handling dead under test. A regression there would only show against a third party client. libnbd can negotiate down, so run the same command set three times, once per mode, and assert the mode that was actually reached. Block status is limited to the two modes that can negotiate a meta context. Signed-off-by: Denis V. Lunev CC: Eric Blake CC: Vladimir Sementsov-Ogievskiy Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/tests/nbd-commands | 28 +++++++++++++++++++++++ tests/qemu-iotests/tests/nbd-commands.out | 4 ++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/tests/nbd-commands b/tests/qemu-iotests/tes= ts/nbd-commands index d2715b59a1..f0b40feb6b 100755 --- a/tests/qemu-iotests/tests/nbd-commands +++ b/tests/qemu-iotests/tests/nbd-commands @@ -113,6 +113,34 @@ class TestNbdCommands(iotests.QMPTestCase): self.assertEqual(self.top_extents(), [(0, size, 0)]) qemu_io('-c', f'read -P {pattern} 0 {size}', top) =20 + def check_commands(self, structured, extended): + with self.open_nbd(structured, extended) as h: + self.assertEqual(h.pread(4096, 4096), bytes([pattern]) * 4096) + + h.cache(size, 0) + + h.pwrite(b'x' * 4096, 4096) + h.flush() + self.assertEqual(h.pread(4096, 4096), b'x' * 4096) + + h.zero(4096, 8192) + self.assertEqual(h.pread(4096, 8192), bytes(4096)) + + h.trim(4096, 16384) + + if structured: + self.assertEqual(self.allocation_depth(h), + [(size, DEPTH_LOCAL)]) + + def test_commands_simple_replies(self): + self.check_commands(structured=3DFalse, extended=3DFalse) + + def test_commands_structured_replies(self): + self.check_commands(structured=3DTrue, extended=3DFalse) + + def test_commands_extended_headers(self): + self.check_commands(structured=3DTrue, extended=3DTrue) + def test_cache_past_end_of_export(self): with self.open_nbd() as h: self.assertRaises(nbd.Error, h.cache, size + 1, 0) diff --git a/tests/qemu-iotests/tests/nbd-commands.out b/tests/qemu-iotests= /tests/nbd-commands.out index 8d7e996700..3f8a935a08 100644 --- a/tests/qemu-iotests/tests/nbd-commands.out +++ b/tests/qemu-iotests/tests/nbd-commands.out @@ -1,5 +1,5 @@ -... +...... ---------------------------------------------------------------------- -Ran 3 tests +Ran 6 tests =20 OK --=20 2.53.0 From nobody Sat Sep 26 23:03:40 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=openvz.org ARC-Seal: i=1; a=rsa-sha256; t=1787763528; cv=none; d=zohomail.com; s=zohoarc; b=YQQ3lCOH1zt+ve50h33Bh/pyGVfbzdJAqr0FwtLJ1c3SdFo4e9QJm5N2bkSdC5ePks30IfYmQfp9FlnjO87riNAM8E0X98Wbm3U8DGi5f4tA6skxZw5uvk4rOL4wZ69fwygQIITdKux3IEw3l6aRa1+J9UCEkxeyu+0XJHj40kY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787763528; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=VoM33mpXT3RRLOZ4hTE7xoq2+FeMJU9XxB2rhWcx78c=; b=EGJGdMEyZFW1FtE+75iwRwl85gZHvE9wl4xdaExFfbTYLhNTUFuaySBUELumdNsAhldg5gE9RoST0S8uMQr5fkF7Mdjt3azLp7w0udKaoRADMRj4ooMr6Oin63zx7Yy0kJ0FpWP2LQ9XnmpdYVC4F8OZLgBxBVLwAB1rRAdftCM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787763528301944.5411268368223; Wed, 26 Aug 2026 09:58:48 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wzGwq-0006X3-Li; Wed, 26 Aug 2026 12:58:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wzGwo-0006Uq-Dy for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:57:58 -0400 Received: from mail-ed1-x533.google.com ([2a00:1450:4864:20::533]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wzGwm-00035O-Py for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:57:58 -0400 Received: by mail-ed1-x533.google.com with SMTP id 4fb4d7f45d1cf-6a5e392b2b3so1856570a12.1 for ; Wed, 26 Aug 2026 09:57:56 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:8a5:68e8:91b1:8a17]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c250a88ac46sm650557766b.29.2026.08.26.09.57.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 09:57:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1787763475; x=1788368275; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=VoM33mpXT3RRLOZ4hTE7xoq2+FeMJU9XxB2rhWcx78c=; b=NP/MjiTxAVaQ7cfXuwBtP1dDovzcNS+SqhZK5PrSOzFRTg1EBzITw69G4qNHQ0tIc8 QMJMm+toCtRPluq7jxQY4cj1yL95Io/c8aSgsJVJbMUc6iGwtnfbE5Kpg60U7cL4B5mt dfcCRKwa+fVQX5mJp3KYAWfdLvcyMm1HB4ZDvGG4VibcotXobHpzT8Q1Ygpec0Rq2FgZ 5owJ+ozK928AVS+NoUqDCw3pJy7WM1mwCtYzP7RNDF5VxyBJaCfpqKcCIs5we8fdsqqU 9n9nUpWbtt9mWBXOoM99wPiUVRp7juhf5uikoytu24vHLX0XfwSJgSI0PsNyAWsVwYX1 LT2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787763475; x=1788368275; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=VoM33mpXT3RRLOZ4hTE7xoq2+FeMJU9XxB2rhWcx78c=; b=CiCSoWPNoPk2SlOX0TmHxXntHxNauWG4gN4q5Xj+oQPz2AWyiWzvWk/lpRENrQ/yoo Zz8CwliG5dnmXlWgqZgHSE1zZT/cXKoGoPMOGvcY0x2SC2vVMGnrtgpv1LEoWiucbFby pE5s0hUu2qYYUuenJ+vaqbzuUMSFifCd7QuYdizYlrN21OOMFKVa9Wym9VOdAD47Bb3K tI1Sb0KSuJo0rG9Ud2xPWoEfzehlRmwM8DkM5+jfkXtbCMHcZJZ4ce4cKmIFrqg97D45 iyNQ96ho+Lpv9V/vN0b8VH1YJPDZD/i08s0H9OUs/CqwsSchFonT2HWCeKXrAKVP8Foe hDqA== X-Gm-Message-State: AFuF++noFMxDQy4BPnp+f7RnMqfDwVCriAGPoqT3OTo/cheA7BDpP+KP 4nQGwkFizAEaHCA5m2/nSN2NKpmg/BJ84HGsRelAbML4/YYJxYSuiVJx4lJKUO6JKNVW1uJcSL3 Q5wpL X-Gm-Gg: AR+sD12xuq1v/mf3N7z4a2um3tJVOaWiyGOe+pZHno77a+pZxd7eEaTGXWnDLxjHwtk VgovPD8Xs6F20beSrG5nknKt6rLi7yagl5WjvFYYgVh3r78nOF5iDWZU07fY8ok2E8PMA1eTxp6 Z41rukB3mPDvGuADN4gPe4/PkAFpz6zD7aOzMRsmDfWZQAd+f+MtlntN5C5xcHD2//F34o+g5A/ Kc9SATxFpxxDSlLI35Dvl08Wqmr3FnY67AIszSsmJgwsscY8gt/7NlQnMtc5/lrDcE4vViBkYfR k/hwJS/oKICM2h5mGSLXjjnS/31ano5bXKXDLZjrYJ7OYxqa9HYcTQYalK6CtnjfzUvqY+jBBxu s70x0SMTjeied63hcYCKwgNRrhsxLfPzq6EO8Hm6T9hmU2NKsxWnIlpctgSe0bQAOZbePzNROlq 0ppVt2l+udnZiL/f8l1dFbeLUL5Mo0I05IFfber9kZJcSms9qy+0KMRi4SVoLqk2PCEvY= X-Received: by 2002:a17:906:628b:b0:c16:66dc:3ab7 with SMTP id a640c23a62f3a-c250c4f025fmr956591466b.10.1787763475297; Wed, 26 Aug 2026 09:57:55 -0700 (PDT) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, "Denis V. Lunev" , Eric Blake , Vladimir Sementsov-Ogievskiy Subject: [PATCH 4/5] iotests/nbd-commands: cover NBD_CMD_BLOCK_STATUS with a payload Date: Wed, 26 Aug 2026 18:57:46 +0200 Message-ID: <20260826165747.3768674-5-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826165747.3768674-1-den@openvz.org> References: <20260826165747.3768674-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::533; envelope-from=den@openvz.org; helo=mail-ed1-x533.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @openvz.org) X-ZM-MESSAGEID: 1787763531210158500 Content-Type: text/plain; charset="utf-8" From: Denis V. Lunev With extended headers a client may name the meta contexts it wants in a request payload. Our own client never sends one, so the server side of it, nbd_co_block_status_payload_read(), is not exercised anywhere. Export two meta contexts and ask libnbd for each of them in turn, which is only answerable through that path. Signed-off-by: Denis V. Lunev CC: Eric Blake CC: Vladimir Sementsov-Ogievskiy Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/tests/nbd-commands | 20 ++++++++++++++++++++ tests/qemu-iotests/tests/nbd-commands.out | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/tests/nbd-commands b/tests/qemu-iotests/tes= ts/nbd-commands index f0b40feb6b..683a8303e3 100755 --- a/tests/qemu-iotests/tests/nbd-commands +++ b/tests/qemu-iotests/tests/nbd-commands @@ -141,6 +141,26 @@ class TestNbdCommands(iotests.QMPTestCase): def test_commands_extended_headers(self): self.check_commands(structured=3DTrue, extended=3DTrue) =20 + def contexts_reported(self, h, wanted=3DNone): + seen =3D [] + + def cb(meta, offset, entries, err): + seen.append(meta) + + if wanted is None: + h.block_status(size, 0, cb) + else: + h.block_status_filter(size, 0, wanted, cb) + return sorted(seen) + + def test_block_status_payload_filter(self): + with self.open_nbd() as h: + self.assertEqual(self.contexts_reported(h), + ['base:allocation', 'qemu:allocation-depth']) + + for wanted in (['base:allocation'], ['qemu:allocation-depth']): + self.assertEqual(self.contexts_reported(h, wanted), wanted) + def test_cache_past_end_of_export(self): with self.open_nbd() as h: self.assertRaises(nbd.Error, h.cache, size + 1, 0) diff --git a/tests/qemu-iotests/tests/nbd-commands.out b/tests/qemu-iotests= /tests/nbd-commands.out index 3f8a935a08..2f7d3902f2 100644 --- a/tests/qemu-iotests/tests/nbd-commands.out +++ b/tests/qemu-iotests/tests/nbd-commands.out @@ -1,5 +1,5 @@ -...... +....... ---------------------------------------------------------------------- -Ran 6 tests +Ran 7 tests =20 OK --=20 2.53.0 From nobody Sat Sep 26 23:03:40 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=openvz.org ARC-Seal: i=1; a=rsa-sha256; t=1787763526; cv=none; d=zohomail.com; s=zohoarc; b=RgxlVT/JTULWXkQjGgBsgY2xqmGIrIM89inOMMgqNN+4IQ87XkogjtjXj0MBLHEkQG4hLSGETygyQF7eTb7uSEDv7mNttAdEnVYPr4sXB9kczqXZkVaB8ggZHOV6xxs0Uaf3JTvhqjaz8CINJt/WoPxJ6gINxtJOIWb6dpp5sXo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1787763526; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=/t5s7xa7MIPf4HMotnoE+nqwnLijFlGOAxgQ9Zhk2OA=; b=C3M8rADvRGzAHJvKBO0t2OavRcDY8q8g2v79/2hcEK8RZhid/wge8hv4c0EyqhQLF/1Ayz6oCV5741oAcsTHza9xud6S+Xsti9wo3cK6lapzVO02Kw70EPEXsyeJA6bzQKbquJhjir7n/EMA1uUD7Z74B4VAu+/30OF9jOzF8Ps= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1787763526789204.1336272412625; Wed, 26 Aug 2026 09:58:46 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wzGwq-0006XG-VJ; Wed, 26 Aug 2026 12:58:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wzGwq-0006WO-0F for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:58:00 -0400 Received: from mail-ej1-x62f.google.com ([2a00:1450:4864:20::62f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1wzGwo-000360-6a for qemu-devel@nongnu.org; Wed, 26 Aug 2026 12:57:59 -0400 Received: by mail-ej1-x62f.google.com with SMTP id a640c23a62f3a-c197e7e4e94so179916966b.2 for ; Wed, 26 Aug 2026 09:57:57 -0700 (PDT) Received: from athena.sw.ru ([2a06:5b06:b600:300:8a5:68e8:91b1:8a17]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-c250a88ac46sm650557766b.29.2026.08.26.09.57.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2026 09:57:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=openvz.org; s=google; t=1787763476; x=1788368276; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=/t5s7xa7MIPf4HMotnoE+nqwnLijFlGOAxgQ9Zhk2OA=; b=r8smniCEbiHO4Ky5+V8QHRUZBXPjeqFzberkbYDhBwBL5mE4XMZGC2fpFVW56sEPkV pcvfOWMTRF0lKS4UK9odTyEXCHjxIzHXcyf6wCeZnKH2AvQEe25Fqndojixs/05Imz97 Bow4k4WEj4Zcw0a5oESA3lJI+QtvA7ePvqK81pECWFOgtDbr4IwUCv77WvOxiqzHjvHb U/AzlTEhxdmtAXHmFjyJmWXb/K2Vm1Idb5YJDzr0mwHhoCyTw7/K+619mR0c52xVq8oQ KFBsttTZ3YyMMtI68j30i8NWIOlF6qHJorlnbBN5t3vs16xkYXUO11YfmTnWly1X7vLf D3QA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1787763476; x=1788368276; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=/t5s7xa7MIPf4HMotnoE+nqwnLijFlGOAxgQ9Zhk2OA=; b=mo81CyDB+oO+pG4d9GsJRCK5+vtiSh4vYzlKi/JgphokU1gkkQrX7IKP9XNTQKNQaH BWAgfwU1oPZZqDu7Gr8pQcwXvMg4iM04dujuLVnpsBTxRJGBUVrHJ7lF1Kcy4srOkcKc KszFcIFbXPkWQX4/Z2rJRXdTr2xKj5mrspOzuBzsUFixAIxmrTkUGJC/TZwYqfrOEu+4 j3xT+yXegK2k9WnSNVlYfBnk9pT8ZZfryFjzLCPJK/3lI1LU+/ycFDjpE1/OC2vyh83H xrRuvHMhF5DXW9E5fTJPzX5zvGG15jqkMptMIQzmkClYATHkrmiiomQwUI/ig+xAgPBk fM4A== X-Gm-Message-State: AFuF++kHkHF1MKyVqPsCFnkE05htHETjpIkXc7MTFEmDAQiqjCIq/LaP Hn3hrtxSSHBqCzl9F7OLni+LpjJDaGHJTiuLijZe+Mv/oNg8F5z8mVpcwCtU54t0QgVrttX41sR GVQQw X-Gm-Gg: AR+sD11aQPPFOIWDPZclWoOPN+eC+YJ2KNn+4uCwNyXzqmRpEWQU8+o3L5kV1jRQcoE kBU/SrachY+5dmxPBhFhgkGBXfatEEUu7R9wD4vNp/LMLi1Yxvv3PjJjhqITlcAhE0MPQoffwxd gZV4xtTjDXfSSA04tOuriJp7aEiMBWNcvi91YOrNjFFb1010tsFDxA9ZyZeDipd/wqdDMHMLypq M151V5z1Ke3Zzg345rc8RVB0f32zB17EDxSlUUjX3A0+F9OuJfYkRGl5mFZotiT/X5kQ6/MKGGF 8nf3h7e/8tQdDnt5eFjeDkUD/l0EIGdgnYyu+gmHP0T06TajmbiWXd/XiwNMraAKfi8SRJVuE5R qFkF8zgnB8mquDMaUbZIeOyrOFsQ5zy2neYn7fRD5taNus3Nv+dqTUaKQHrnGE16vvA/SAKzmZK cq68I8GY8VhL8VnUY1rSVRER4Pz6cPuZWeC4zu6o042/GBVbzJWhBw1ahU X-Received: by 2002:a17:907:6c16:b0:c12:3059:4071 with SMTP id a640c23a62f3a-c250c330fdcmr1012465166b.15.1787763476417; Wed, 26 Aug 2026 09:57:56 -0700 (PDT) From: "Denis V. Lunev" To: qemu-devel@nongnu.org Cc: qemu-block@nongnu.org, "Denis V. Lunev" , Eric Blake , Vladimir Sementsov-Ogievskiy Subject: [PATCH 5/5] iotests/nbd-commands: cover the command flags and sparse replies Date: Wed, 26 Aug 2026 18:57:47 +0200 Message-ID: <20260826165747.3768674-6-den@openvz.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260826165747.3768674-1-den@openvz.org> References: <20260826165747.3768674-1-den@openvz.org> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists1p.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::62f; envelope-from=den@openvz.org; helo=mail-ej1-x62f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @openvz.org) X-ZM-MESSAGEID: 1787763528653158500 Content-Type: text/plain; charset="utf-8" From: Denis V. Lunev No test sends the NBD command flags, so the server paths behind them go unexercised. Send them from the new client. A structured read answers a hole with an offset and a length rather than a cluster of zeroes. Lay out data, a hole and data again, and read the three arrangements a hole can appear in, since a leading hole and a hole between two extents take different turns through nbd_co_send_sparse_read(). NBD_CMD_FLAG_DF asks for one chunk instead, which is the same layout sent as real zeroes. Check the chunk boundaries in both forms, and that the data still reads back. NBD_CMD_FLAG_REQ_ONE caps the extent array at one entry, so the block status reply covers only the first cluster of the three asked about. That a reply may describe less than was requested is also how the server keeps NBD_MAX_BLOCK_STATUS_EXTENTS from being exceeded on a long fragmented range, and a client assuming full coverage believes stale status. NBD_CMD_FLAG_FAST_ZERO becomes BDRV_REQ_NO_FALLBACK. A cluster aligned zero can be done by marking the cluster, while zeroing part of a cluster over a backing file needs the read modify write the flag forbids, so check both the success and the ENOTSUP. NBD_CMD_FLAG_FUA is added to a write and a trim. Signed-off-by: Denis V. Lunev CC: Eric Blake CC: Vladimir Sementsov-Ogievskiy Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/tests/nbd-commands | 86 +++++++++++++++++++++++ tests/qemu-iotests/tests/nbd-commands.out | 4 +- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/tests/qemu-iotests/tests/nbd-commands b/tests/qemu-iotests/tes= ts/nbd-commands index 683a8303e3..f727ea3161 100755 --- a/tests/qemu-iotests/tests/nbd-commands +++ b/tests/qemu-iotests/tests/nbd-commands @@ -26,6 +26,7 @@ nbd: ModuleType =20 DEPTH_LOCAL =3D 1 DEPTH_BACKING =3D 2 +CLUSTER =3D 65536 =20 =20 class TestNbdCommands(iotests.QMPTestCase): @@ -161,6 +162,91 @@ class TestNbdCommands(iotests.QMPTestCase): for wanted in (['base:allocation'], ['qemu:allocation-depth']): self.assertEqual(self.contexts_reported(h, wanted), wanted) =20 + def read_chunks(self, h, count, offset, flags=3D0): + chunks =3D [] + + def cb(subbuf, off, status, err): + chunks.append((off, len(subbuf), status)) + + h.pread_structured(count, offset, cb, flags) + return chunks + + @staticmethod + def make_sparse(h): + """Lay out data, a hole and data again, one cluster each.""" + h.pwrite(b'z' * CLUSTER, 0) + h.zero(CLUSTER, CLUSTER) + h.pwrite(b'z' * CLUSTER, 2 * CLUSTER) + + def test_read_sparse_chunks(self): + with self.open_nbd() as h: + self.make_sparse(h) + + first =3D (0, CLUSTER, nbd.READ_DATA) + hole =3D (CLUSTER, CLUSTER, nbd.READ_HOLE) + second =3D (2 * CLUSTER, CLUSTER, nbd.READ_DATA) + + # A hole is an offset and a length, not a cluster of zeroes, + # wherever it falls in the reply + self.assertEqual(self.read_chunks(h, 2 * CLUSTER, 0), + [first, hole]) + self.assertEqual(self.read_chunks(h, 2 * CLUSTER, CLUSTER), + [hole, second]) + self.assertEqual(self.read_chunks(h, 3 * CLUSTER, 0), + [first, hole, second]) + + self.assertEqual(h.pread(CLUSTER, CLUSTER), bytes(CLUSTER)) + self.assertEqual(h.pread(CLUSTER, 0), b'z' * CLUSTER) + + def test_read_dont_fragment(self): + with self.open_nbd() as h: + self.make_sparse(h) + + self.assertEqual(self.read_chunks(h, 3 * CLUSTER, 0, + nbd.CMD_FLAG_DF), + [(0, 3 * CLUSTER, nbd.READ_DATA)]) + + def status_extents(self, h, count, flags=3D0): + extents =3D [] + + def cb(meta, offset, entries, err): + if meta =3D=3D 'base:allocation': + extents.extend(zip(entries[0::2], entries[1::2])) + + h.block_status(count, 0, cb, flags) + return extents + + def test_block_status_req_one(self): + hole =3D nbd.STATE_HOLE | nbd.STATE_ZERO + + with self.open_nbd() as h: + self.make_sparse(h) + + self.assertEqual(self.status_extents(h, 3 * CLUSTER), + [(CLUSTER, 0), (CLUSTER, hole), (CLUSTER, 0)]) + + # One extent, so the reply covers less than was asked for and + # the client has to come back for the rest + self.assertEqual(self.status_extents(h, 3 * CLUSTER, + nbd.CMD_FLAG_REQ_ONE), + [(CLUSTER, 0)]) + + def test_write_and_trim_fua(self): + with self.open_nbd() as h: + h.pwrite(b'y' * 4096, 4096, nbd.CMD_FLAG_FUA) + self.assertEqual(h.pread(4096, 4096), b'y' * 4096) + h.trim(4096, 4096, nbd.CMD_FLAG_FUA) + + def test_fast_zero(self): + with self.open_nbd() as h: + h.zero(CLUSTER, CLUSTER, nbd.CMD_FLAG_FAST_ZERO) + self.assertEqual(h.pread(CLUSTER, CLUSTER), bytes(CLUSTER)) + + # Zeroing part of a cluster needs the fallback the flag forbids + with self.assertRaises(nbd.Error) as caught: + h.zero(4096, 4096, nbd.CMD_FLAG_FAST_ZERO) + self.assertEqual(caught.exception.errno, 'ENOTSUP') + def test_cache_past_end_of_export(self): with self.open_nbd() as h: self.assertRaises(nbd.Error, h.cache, size + 1, 0) diff --git a/tests/qemu-iotests/tests/nbd-commands.out b/tests/qemu-iotests= /tests/nbd-commands.out index 2f7d3902f2..281b69efea 100644 --- a/tests/qemu-iotests/tests/nbd-commands.out +++ b/tests/qemu-iotests/tests/nbd-commands.out @@ -1,5 +1,5 @@ -....... +............ ---------------------------------------------------------------------- -Ran 7 tests +Ran 12 tests =20 OK --=20 2.53.0