Commit b5fabdc072 for qemu.org
commit b5fabdc072f357a950a5052697bf03e86197f4bc
Author: Kevin Wolf <kwolf@redhat.com>
Date: Fri Oct 30 00:09:59 2026 +0100
virtio-blk-test: Add a basic GET_ID test case
This covers the simple common case with no surprises: A serial that is
shorter than 20 characters and can fit in the request buffer.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20261029231001.194240-3-kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
diff --git a/tests/qtest/virtio-blk-test.c b/tests/qtest/virtio-blk-test.c
index 98c906ebb4..825ea261be 100644
--- a/tests/qtest/virtio-blk-test.c
+++ b/tests/qtest/virtio-blk-test.c
@@ -95,6 +95,8 @@ static uint64_t virtio_blk_request(QGuestAllocator *alloc, QVirtioDevice *d,
g_assert_cmpuint(data_size %
sizeof(struct virtio_blk_discard_write_zeroes), ==, 0);
break;
+ case VIRTIO_BLK_T_GET_ID:
+ break;
default:
g_assert_cmpuint(data_size, ==, 0);
}
@@ -771,6 +773,91 @@ static void resize(void *obj, void *data, QGuestAllocator *t_alloc)
}
+static QVirtQueue *get_id_setup(QVirtioDevice *dev, QGuestAllocator *t_alloc)
+{
+ QVirtQueue *vq;
+ uint64_t features = qvirtio_get_features(dev);
+
+ features = features & (1ull << VIRTIO_F_VERSION_1);
+ qvirtio_set_features(dev, features);
+
+ vq = qvirtqueue_setup(dev, t_alloc, 0);
+ qvirtio_set_driver_ok(dev);
+ return vq;
+}
+
+static uint8_t get_id_request(QVirtioDevice *dev, QVirtQueue *vq,
+ char *buf, size_t buf_len,
+ char pattern_byte,
+ QGuestAllocator *t_alloc)
+{
+ QTestState *qts = global_qtest;
+ uint64_t req_addr;
+ uint32_t free_head;
+ uint8_t status;
+
+ QVirtioBlkReq req = {
+ .type = VIRTIO_BLK_T_GET_ID,
+ .data = buf,
+ };
+
+ req_addr = virtio_blk_request(t_alloc, dev, &req, buf_len);
+
+ memset(req.data, pattern_byte, buf_len);
+ memwrite(req_addr + 16, req.data, buf_len);
+
+ free_head = qvirtqueue_add(qts, vq, req_addr, 16, false, true);
+ qvirtqueue_add(qts, vq, req_addr + 16, buf_len, true, true);
+ qvirtqueue_add(qts, vq, req_addr + 16 + buf_len, 1, true, false);
+
+ qvirtqueue_kick(qts, dev, vq, free_head);
+
+ qvirtio_wait_used_elem(qts, dev, vq, free_head, NULL,
+ QVIRTIO_BLK_TIMEOUT_US);
+ status = readb(req_addr + 16 + buf_len);
+ memread(req_addr + 16, buf, buf_len);
+
+ guest_free(t_alloc, req_addr);
+
+ return status;
+}
+
+static void get_id_serial_short(void *obj, void *data, QGuestAllocator *t_alloc)
+{
+ QVirtioBlk *blk_if = obj;
+ QVirtioDevice *dev = blk_if->vdev;
+ QVirtQueue *vq;
+ uint8_t status;
+ const char expected[20] = "abc";
+ char buf[20];
+
+ vq = get_id_setup(dev, t_alloc);
+ status = get_id_request(dev, vq, buf, 20, 0xa5, t_alloc);
+ g_assert_cmpint(status, ==, 0);
+ g_assert_cmpmem(buf, 20, expected, sizeof(expected));
+
+ qvirtqueue_cleanup(blk_if->vdev->bus, vq, t_alloc);
+}
+
+static void get_id_serial_short_20_characters(void *obj, void *data,
+ QGuestAllocator *t_alloc)
+{
+ QVirtioBlk *blk_if = obj;
+ QVirtioDevice *dev = blk_if->vdev;
+ QVirtQueue *vq;
+ uint8_t status;
+ /* Edge case of a serial with exactly 20 characters: No NUL termination */
+ const char expected[25] = "01234567890123456789\xa5\xa5\xa5\xa5\xa5";
+ char buf[25];
+
+ vq = get_id_setup(dev, t_alloc);
+ status = get_id_request(dev, vq, buf, 25, 0xa5, t_alloc);
+ g_assert_cmpint(status, ==, 0);
+ g_assert_cmpmem(buf, 25, expected, sizeof(expected));
+
+ qvirtqueue_cleanup(blk_if->vdev->bus, vq, t_alloc);
+}
+
static void *virtio_blk_test_setup(GString *cmd_line, void *arg)
{
char *tmp_path = drive_create();
@@ -802,6 +889,15 @@ static void register_virtio_blk_test(void)
qos_add_test("nxvirtq", "virtio-blk-pci",
test_nonexistent_virtqueue, &opts);
qos_add_test("hotplug", "virtio-blk-pci", pci_hotplug, &opts);
+
+ /* serial number tests */
+ opts.edge.extra_device_opts = "serial=abc";
+ qos_add_test("get_id/serial_short", "virtio-blk",
+ get_id_serial_short, &opts);
+
+ opts.edge.extra_device_opts = "serial=01234567890123456789";
+ qos_add_test("get_id/serial_short_20_characters", "virtio-blk",
+ get_id_serial_short_20_characters, &opts);
}
libqos_init(register_virtio_blk_test);