[PATCH 6/6] iotests: add preallocate filter checks

Denis V. Lunev via posted 6 patches 4 weeks ago
[PATCH 6/6] iotests: add preallocate filter checks
Posted by Denis V. Lunev via 4 weeks ago
From: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>

This test summaries the cases faced inside Virtuozzo with the
preallocation filter worth to be added to unit tests:

  1. Launch a VM whose block graph has preallocate filter node and
     migrate it locally into a file.
  2. Same, but make sure preallocate filter is activated by performing a
     write op to it beyond the current disk length (which is zero).
  3. Add testcase which would perform write operation to VM disk to make
     sure preallocation filter is active, and then run 'blockdev-snapshot'
     command to turn another image (also with preallocation) into an
     external snapshot and make it an active disk.

Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
CC: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Hanna Reitz <hreitz@redhat.com>
---
 tests/qemu-iotests/tests/prealloc-checks     | 222 +++++++++++++++++++
 tests/qemu-iotests/tests/prealloc-checks.out |  81 +++++++
 2 files changed, 303 insertions(+)
 create mode 100644 tests/qemu-iotests/tests/prealloc-checks
 create mode 100644 tests/qemu-iotests/tests/prealloc-checks.out

diff --git a/tests/qemu-iotests/tests/prealloc-checks b/tests/qemu-iotests/tests/prealloc-checks
new file mode 100644
index 0000000000..fc55353cb9
--- /dev/null
+++ b/tests/qemu-iotests/tests/prealloc-checks
@@ -0,0 +1,222 @@
+#!/usr/bin/env bash
+# group: rw
+#
+# Checks for preallocate filter.
+#
+# Copyright (c) 2024 Virtuozzo International GmbH. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=andrey.drobyshev@virtuozzo.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+status=1 # failure is the default!
+
+_cleanup()
+{
+    _cleanup_qemu
+    rm -f $SOCK_DIR/nbd.sock
+    rm -f $TEST_IMG.snap
+    _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ../common.rc
+. ../common.filter
+. ../common.qemu
+
+_supported_fmt qcow2
+
+_recreate_test_img()
+{
+    local size="1M"
+    local imgopts="cluster_size=$size,extended_l2=on,lazy_refcounts=on"
+    local image="$TEST_IMG"
+
+    if test -n "$1" ; then
+        image="$1"
+    fi
+
+    rm -f $image
+    TEST_IMG=$image _make_test_img -o "$imgopts" $size
+}
+
+blkopts="node-name=disk,driver=qcow2,file.driver=preallocate,"
+blkopts+="file.node-name=prealloc,file.file.driver=file,"
+blkopts+="file.file.filename=$TEST_IMG,file.file.node-name=storage"
+
+#
+# 1. Launch a VM so that its block graph contains preallocate filter node,
+# and perform its local migration to a file.  That is similar to doing
+# "virsh save VM /path/to/vmsave".
+#
+
+echo
+echo === 1. Migration to a local file ===
+echo
+
+echo "# Create image and start VM with preallocate filter:"
+echo
+_recreate_test_img
+qemu_comm_method="monitor" _launch_qemu -blockdev "$blkopts"
+handle=$QEMU_HANDLE
+_send_qemu_cmd $handle "" "(qemu)"
+
+echo
+echo "# Migrate VM to a local file (/dev/null):"
+echo
+_send_qemu_cmd $handle "migrate \"exec: cat > '/dev/null'\"" "(qemu)"
+
+echo
+echo "# Exit VM:"
+echo
+_send_qemu_cmd $handle "quit" ""
+wait=yes _cleanup_qemu
+
+#
+# 2. Same as 1st, but this time we make sure that preallocate filter is
+# actually active. To do that we perform a write op beyond current length
+# (which is 0 as the image's just created).  Then migrate VM to a local
+# file (/dev/null).
+#
+
+echo
+echo === 2. Migration to a local file after a write operation ===
+echo
+
+echo "# Create image and start VM with preallocate filter:"
+echo
+_recreate_test_img
+qemu_comm_method="monitor" _launch_qemu -blockdev "$blkopts"
+handle=$QEMU_HANDLE
+_send_qemu_cmd $handle "" "(qemu)"
+
+echo
+echo "# Perform write op to the image to activate preallocate filter:"
+echo
+_send_qemu_cmd $handle 'qemu-io disk "write -P 0xff 0 1M"' "1 MiB"
+
+echo
+echo "# Migrate VM to a local file (/dev/null):"
+echo
+_send_qemu_cmd $handle "migrate \"exec: cat > '/dev/null'\"" "(qemu)"
+
+echo
+echo "# Exit VM:"
+echo
+_send_qemu_cmd $handle "quit" ""
+wait=yes _cleanup_qemu
+
+#
+# 3. Add another overlay image (with preallocation filter as well), launch
+# VM, export its disk via nbd to perform a write operation and activate the
+# preallocation filter, and then run 'blockdev-snapshot' to turn the overlay
+# image into an external snapshot of the disk.
+#
+
+echo
+echo === 3. Taking external snapshot after a write operation ===
+echo
+
+snapblkopts="node-name=snap,driver=qcow2,file.driver=preallocate,"
+snapblkopts+="file.node-name=snap-prealloc,file.file.driver=file,"
+snapblkopts+="file.file.filename=$TEST_IMG.snap,"
+snapblkopts+="file.file.node-name=snap-storage"
+
+echo "# Create disk and snapshot images and start VM with preallocate filter:"
+echo
+_recreate_test_img
+_recreate_test_img $TEST_IMG.snap
+
+qemu_comm_method="qmp" qmp_pretty= \
+    _launch_qemu -blockdev "$snapblkopts" -blockdev "$blkopts"
+handle=$QEMU_HANDLE
+_send_qemu_cmd $handle "{ 'execute': 'qmp_capabilities' }" "return"
+
+silent=yes
+
+echo
+echo "# Start nbd server:"
+echo
+_send_qemu_cmd $handle \
+    "{ 'execute': 'nbd-server-start',
+       'arguments': { 'addr': { 'type': 'unix',
+                                'data': { 'path': '$SOCK_DIR/nbd.sock' }}}}"
+_send_qemu_cmd $handle "" "return"
+
+echo
+echo "# Export 'disk' node via nbd server:"
+echo
+_send_qemu_cmd $handle \
+    "{ 'execute': 'block-export-add',
+       'arguments': { 'type': 'nbd', 'node-name': 'disk', 'id': 'nbdexp',
+                      'name': 'nbdexp', 'writable': true }}"
+_send_qemu_cmd $handle "" "return"
+
+echo
+echo "# Perform write op to the nbd-exported disk:"
+echo
+silent=
+$QEMU_IO_PROG -f raw -c "write -P 0xff 0 1M" \
+    "nbd+unix:///nbdexp?socket=$SOCK_DIR/nbd.sock" 2>&1 \
+    | _filter_qemu_io | _filter_nbd
+
+echo
+echo "# Delete nbd export:"
+echo
+silent=yes
+_send_qemu_cmd $handle \
+    "{ 'execute': 'block-export-del', 'arguments': { 'id': 'nbdexp' }}"
+_send_qemu_cmd $handle "" "return"
+
+echo
+echo "# Stop nbd server:"
+echo
+_send_qemu_cmd $handle \
+    "{ 'execute': 'nbd-server-stop' }"
+_send_qemu_cmd $handle "" "return"
+
+echo
+echo "# Turn 'snap' node into the external snapshot of 'disk' node:"
+echo
+silent=
+_send_qemu_cmd $handle \
+    "{ 'execute': 'blockdev-snapshot',
+       'arguments': { 'node': 'disk', 'overlay': 'snap' }}"
+_send_qemu_cmd $handle "" "return"
+
+echo
+echo "# Check block graph:"
+echo
+_send_qemu_cmd $handle \
+    "{ 'execute': 'x-debug-query-block-graph' }"
+_send_qemu_cmd $handle "" "return"
+
+echo
+echo "# Exit VM:"
+echo
+qmp_pretty=
+silent=yes
+_send_qemu_cmd $handle "{ 'execute': 'quit' }" "qmp-quit"
+wait=yes _cleanup_qemu
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/tests/prealloc-checks.out b/tests/qemu-iotests/tests/prealloc-checks.out
new file mode 100644
index 0000000000..10b5f8fa8e
--- /dev/null
+++ b/tests/qemu-iotests/tests/prealloc-checks.out
@@ -0,0 +1,81 @@
+QA output created by prealloc-checks
+
+=== 1. Migration to a local file ===
+
+# Create image and start VM with preallocate filter:
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu)
+
+# Migrate VM to a local file (/dev/null):
+
+(qemu) migrate "exec: cat > '/dev/null'"
+
+# Exit VM:
+
+(qemu) quit
+
+=== 2. Migration to a local file after a write operation ===
+
+# Create image and start VM with preallocate filter:
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+QEMU X.Y.Z monitor - type 'help' for more information
+(qemu)
+
+# Perform write op to the image to activate preallocate filter:
+
+(qemu) qemu-io disk "write -P 0xff 0 1M"
+wrote 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+# Migrate VM to a local file (/dev/null):
+
+(qemu) migrate "exec: cat > '/dev/null'"
+
+# Exit VM:
+
+(qemu) quit
+
+=== 3. Taking external snapshot after a write operation ===
+
+# Create disk and snapshot images and start VM with preallocate filter:
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
+Formatting 'TEST_DIR/t.IMGFMT.snap', fmt=IMGFMT size=1048576
+{ 'execute': 'qmp_capabilities' }
+{"return": {}}
+
+# Start nbd server:
+
+
+# Export 'disk' node via nbd server:
+
+
+# Perform write op to the nbd-exported disk:
+
+wrote 1048576/1048576 bytes at offset 0
+1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+# Delete nbd export:
+
+
+# Stop nbd server:
+
+
+# Turn 'snap' node into the external snapshot of 'disk' node:
+
+{ 'execute': 'blockdev-snapshot',
+       'arguments': { 'node': 'disk', 'overlay': 'snap' }}
+{"return": {}}
+
+# Check block graph:
+
+{ 'execute': 'x-debug-query-block-graph' }
+{"return": {"edges": [{"name": "file", "parent": 4, "shared-perm": ["write-unchanged", "consistent-read"], "perm": ["consistent-read"], "child": 6}, {"name": "file", "parent": 6, "shared-perm": ["write-unchanged", "consistent-read"], "perm": ["consistent-read"], "child": 5}, {"name": "file", "parent": 3, "shared-perm": ["write-unchanged", "consistent-read"], "perm": ["resize", "write", "consistent-read"], "child": 2}, {"name": "backing", "parent": 3, "shared-perm": ["resize", "write-unchanged", "write", "consistent-read"], "perm": [], "child": 4}, {"name": "file", "parent": 2, "shared-perm": ["write-unchanged", "consistent-read"], "perm": ["resize", "write", "consistent-read"], "child": 1}], "nodes": [{"name": "disk", "type": "block-driver", "id": 4}, {"name": "prealloc", "type": "block-driver", "id": 6}, {"name": "storage", "type": "block-driver", "id": 5}, {"name": "snap", "type": "block-driver", "id": 3}, {"name": "snap-prealloc", "type": "block-driver", "id": 2}, {"name": "snap-storage", "type": "block-driver", "id": 1}]}}
+
+# Exit VM:
+
+{"return": {}}
+*** done
-- 
2.45.2