From nobody Sun Dec 14 06:22:00 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1750709259; cv=none; d=zohomail.com; s=zohoarc; b=WBRHLRu5KF4sHa1YCMmCVaMiZCqyNw2k4DZNtK0gNJzXT5wPA1ggl6jDIGIQ4pRpl3HwWh/vHy+bVoCZxI/6XCWTSSBGIELo+RnwEFsfTmR6zhlrnWiWucgy6vrgMApXqWl60e8vzSBxOTTzMtnePwosne5A3w5j8vc4w0i/ojs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1750709259; h=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id:Cc; bh=TL3meG6+O1vv7XlYaEZBZs6Pur+RXYQAROw6YoA4rB4=; b=Y7ob8RETLeyyJ5uMnJe0F00BkQsT6zIHZpLBQRjpiRsF/SuFVv5qNsh3MIFe2KYmgyeoGc3K+OOiulnFUFlY3LV0y1g3D5RsSbWg0JxBNYD0R8InbhbiM8z8zBX+pZ2XhEWUxgyHrCp7e9EU7wsSYKGmtq6QcCxzbSdKDAgJuOY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1750709258765822.1843557777712; Mon, 23 Jun 2025 13:07:38 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id AF987D43; Mon, 23 Jun 2025 16:07:37 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 5D8D61287; Mon, 23 Jun 2025 16:00:10 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 574FE11AF; Mon, 23 Jun 2025 16:00:00 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id B7A1A1268 for ; Mon, 23 Jun 2025 15:59:35 -0400 (EDT) Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-613-SAT_HN-BPkSQZm2ShnfrHQ-1; Mon, 23 Jun 2025 15:59:33 -0400 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D81E4195608B for ; Mon, 23 Jun 2025 19:59:32 +0000 (UTC) Received: from speedmetal.redhat.com (unknown [10.45.242.5]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1EA6719560A3 for ; Mon, 23 Jun 2025 19:59:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1750708775; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3PyZJtyLPKhXBcr4/19AC3LW9h6tH7X/yaeh0X6tUV8=; b=U/KRp5sOq2u17kyFxON6GAL/x5nwUXE7Q3/H2Ls0ejl7yOAp8TcIpJiF+ngLV/vSwhlSO8 rbhwQQW9i/3LvH/6yTrjoAXp6Gt5HS9ASRQrgvhTIiaF8JTvtBaNsaNVyaoeZWpfmOCmCD w60qUr1YYF7OSZqkXW85IZ3gB79yFUc= X-MC-Unique: SAT_HN-BPkSQZm2ShnfrHQ-1 X-Mimecast-MFC-AGG-ID: SAT_HN-BPkSQZm2ShnfrHQ_1750708773 To: devel@lists.libvirt.org Subject: [PATCH v2 09/13] qemu: Fill in model of 'usb' disks to preserve ABI compatibility Date: Mon, 23 Jun 2025 21:59:14 +0200 Message-ID: <47e88602901a17f628882d14a68937d74667b61f.1750705681.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: L_H1HEKoAoivtNujdqBQNEFpWO7rq0fLnGddRNug7pw_1750708773 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: VLJYQI4JXVXYUXTH7BMQB5OF2J5FM7BR X-Message-ID-Hash: VLJYQI4JXVXYUXTH7BMQB5OF2J5FM7BR X-MailFrom: pkrempa@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: From: Peter Krempa via Devel Reply-To: Peter Krempa X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1750709260786116600 Content-Type: text/plain; charset="utf-8" From: Peter Krempa While 'usb-bot' and 'usb-storage' are ABI and migration compatible for disks it's not the case for cdroms. When migrating from a new config using 'usb-bot' to an older daemon which would use 'usb-storage' the guest os will get I/O errors. Thus we must properly fill in models for 'usb' disks so that cdroms can be handled properly. When parsing XML fill in the models and drop the appropriate models when formatting migratable XML. The logic is explained in comments in the code. Signed-off-by: Peter Krempa Reviewed-by: Jiri Denemark --- src/qemu/qemu_domain.c | 21 ++++++++ src/qemu/qemu_postparse.c | 49 ++++++++++++++++++- src/qemu/qemu_postparse.h | 4 +- tests/qemublocktest.c | 13 +++-- .../qemuhotplug-base-live+cdrom-usb.xml | 2 +- .../qemuhotplug-base-live+disk-usb.xml | 2 +- .../disk-cache.x86_64-latest.xml | 2 +- .../disk-usb-device-model.x86_64-latest.xml | 4 +- ...test.QEMU_CAPS_DEVICE_USB_BOT-disabled.xml | 24 ++++----- ...date.QEMU_CAPS_DEVICE_USB_BOT-disabled.xml | 24 ++++----- ...sk-usb-device.x86_64-latest.abi-update.xml | 24 ++++----- .../disk-usb-device.x86_64-latest.xml | 24 ++++----- 12 files changed, 132 insertions(+), 61 deletions(-) diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ace42b516a..6e147563f3 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -5342,6 +5342,27 @@ qemuDomainDefFormatBufInternal(virQEMUDriver *driver, } } + for (i =3D 0; i < def->ndisks; i++) { + virDomainDiskDef *disk =3D def->disks[i]; + + /* The 'mode' property for USB disks was introduced long after= USB + * disks to allow switching between 'usb-storage' and 'usb-bot' + * device. Despite sharing identical implementation 'usb-bot' = allows + * proper configuration of USB cdroms. Unfortunately it is not= ABI + * compatible. + * + * To preserve migration to older daemons we can strip the mod= el to + * the default if: + * - it's a normal disk (not cdrom) as both are identical + * - for a usb-cdrom strip the model if it's not 'usb-bot' as = that + * was the old configuration + */ + if (disk->bus =3D=3D VIR_DOMAIN_DISK_BUS_USB && + (disk->model =3D=3D VIR_DOMAIN_DISK_MODEL_USB_STORAGE || + disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_DISK)) + disk->model =3D VIR_DOMAIN_DISK_MODEL_DEFAULT; + } + /* Replace the CPU definition updated according to QEMU with the o= ne * used for starting the domain. The updated def will be sent * separately for backward compatibility. diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c index 8150dffac6..7db378c5ce 100644 --- a/src/qemu/qemu_postparse.c +++ b/src/qemu/qemu_postparse.c @@ -202,7 +202,8 @@ qemuDomainDeviceDiskDefPostParseRestoreSecAlias(virDoma= inDiskDef *disk, int qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk, - unsigned int parseFlags) + unsigned int parseFlags, + virQEMUCaps *qemuCaps) { virStorageSource *n; @@ -220,6 +221,50 @@ qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *dis= k, disk->mirror->format =3D=3D VIR_STORAGE_FILE_NONE) disk->mirror->format =3D VIR_STORAGE_FILE_RAW; + /* default USB disk model: + * + * Historically we didn't use model for USB disks. It became necessary= once + * it turned out that 'usb-storage' doesn't properly expose CDROM devi= ces + * with -blockdev. Additionally 'usb-bot' which does properly handle t= hem, + * while having identical implementation in qemu and driver in guest, = are + * not in fact ABI compatible. Thus the logic is as follows: + * + * If ABI update is not allowed: + * - use 'usb-storage' for either (unless only 'usb-bot' is supported) + * + * If ABI update is possible + * - for VIR_DOMAIN_DISK_DEVICE_DISK use 'usb-storage' as it doesn't m= atter + * (it is identical with 'usb-bot' ABI wise) + * - for VIR_DOMAIN_DISK_DEVICE_CDROM use 'usb-bot' if available + * (as it properly exposes cdrom) + * + * When formatting migratable XML the code strips 'usb-storage' to pre= serve + * migration to older daemons. If a new definition with 'usb-bot' cdro= m is + * created via new start or hotplug it will fail migrating. Users must + * explicitly set the broken config in XML or unplug the device. + */ + if (qemuCaps && + disk->bus =3D=3D VIR_DOMAIN_DISK_BUS_USB && + disk->model =3D=3D VIR_DOMAIN_DISK_MODEL_DEFAULT) { + + if (disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_CDROM && + parseFlags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE) { + + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_BOT)) { + disk->model =3D VIR_DOMAIN_DISK_MODEL_USB_BOT; + } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORA= GE)) { + disk->model =3D VIR_DOMAIN_DISK_MODEL_USB_STORAGE; + } + + } else { + if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE)) { + disk->model =3D VIR_DOMAIN_DISK_MODEL_USB_STORAGE; + } else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_BOT))= { + disk->model =3D VIR_DOMAIN_DISK_MODEL_USB_BOT; + } + } + } + /* default disk encryption engine */ for (n =3D disk->src; virStorageSourceIsBacking(n); n =3D n->backingSt= ore) { if (n->encryption && n->encryption->engine =3D=3D VIR_STORAGE_ENCR= YPTION_ENGINE_DEFAULT) @@ -843,7 +888,7 @@ qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev, break; case VIR_DOMAIN_DEVICE_DISK: - ret =3D qemuDomainDeviceDiskDefPostParse(dev->data.disk, parseFlag= s); + ret =3D qemuDomainDeviceDiskDefPostParse(dev->data.disk, parseFlag= s, qemuCaps); break; case VIR_DOMAIN_DEVICE_VIDEO: diff --git a/src/qemu/qemu_postparse.h b/src/qemu/qemu_postparse.h index ac69c14604..46945adbd6 100644 --- a/src/qemu/qemu_postparse.h +++ b/src/qemu/qemu_postparse.h @@ -22,10 +22,12 @@ #pragma once #include "virconftypes.h" +#include "qemu_capabilities.h" int qemuDomainDeviceDiskDefPostParse(virDomainDiskDef *disk, - unsigned int parseFlags); + unsigned int parseFlags, + virQEMUCaps *qemuCaps); int qemuDomainDeviceDefPostParse(virDomainDeviceDef *dev, diff --git a/tests/qemublocktest.c b/tests/qemublocktest.c index be3e421ac0..095a54e22c 100644 --- a/tests/qemublocktest.c +++ b/tests/qemublocktest.c @@ -271,7 +271,7 @@ testQemuDiskXMLToProps(const void *opaque) VIR_DOMAIN_DEF_PARSE_STATUS))) return -1; - if (qemuDomainDeviceDiskDefPostParse(disk, 0) < 0) + if (qemuDomainDeviceDiskDefPostParse(disk, 0, data->qemuCaps) < 0) return -1; if (!(vmdef =3D virDomainDefNew(data->driver->xmlopt))) @@ -464,7 +464,8 @@ static const char *testQemuImageCreatePath =3D abs_srcd= ir "/qemublocktestdata/imag static virStorageSource * testQemuImageCreateLoadDiskXML(const char *name, - virDomainXMLOption *xmlopt) + virDomainXMLOption *xmlopt, + virQEMUCaps *qemuCaps) { g_autoptr(virDomainDiskDef) disk =3D NULL; @@ -481,7 +482,7 @@ testQemuImageCreateLoadDiskXML(const char *name, VIR_DOMAIN_DEF_PARSE_STATUS))) return NULL; - if (qemuDomainDeviceDiskDefPostParse(disk, 0) < 0) + if (qemuDomainDeviceDiskDefPostParse(disk, 0, qemuCaps) < 0) return NULL; return g_steal_pointer(&disk->src); @@ -502,12 +503,14 @@ testQemuImageCreate(const void *opaque) g_autofree char *actual =3D NULL; g_autofree char *jsonpath =3D NULL; - if (!(src =3D testQemuImageCreateLoadDiskXML(data->name, data->driver-= >xmlopt))) + if (!(src =3D testQemuImageCreateLoadDiskXML(data->name, data->driver-= >xmlopt, + data->qemuCaps))) return -1; if (data->backingname && !(src->backingStore =3D testQemuImageCreateLoadDiskXML(data->backi= ngname, - data->driver-= >xmlopt))) + data->driver-= >xmlopt, + data->qemuCap= s))) return -1; if (testQemuDiskXMLToJSONFakeSecrets(src) < 0) diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+cdrom-usb.x= ml b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+cdrom-usb.xml index d31136dbc8..bed4dcec14 100644 --- a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+cdrom-usb.xml +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+cdrom-usb.xml @@ -22,7 +22,7 @@ restart /usr/bin/qemu-system-x86_64 - + diff --git a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-usb.xm= l b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-usb.xml index 5964c23ba0..6f974892be 100644 --- a/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-usb.xml +++ b/tests/qemuhotplugtestdomains/qemuhotplug-base-live+disk-usb.xml @@ -22,7 +22,7 @@ restart /usr/bin/qemu-system-x86_64 - + diff --git a/tests/qemuxmlconfdata/disk-cache.x86_64-latest.xml b/tests/qem= uxmlconfdata/disk-cache.x86_64-latest.xml index c770deaaab..a5d9cd388a 100644 --- a/tests/qemuxmlconfdata/disk-cache.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/disk-cache.x86_64-latest.xml @@ -41,7 +41,7 @@
- + diff --git a/tests/qemuxmlconfdata/disk-usb-device-model.x86_64-latest.xml = b/tests/qemuxmlconfdata/disk-usb-device-model.x86_64-latest.xml index 351257bc4a..9f2f383f30 100644 --- a/tests/qemuxmlconfdata/disk-usb-device-model.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/disk-usb-device-model.x86_64-latest.xml @@ -39,12 +39,12 @@ - + - + diff --git a/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.QEMU_CAPS_= DEVICE_USB_BOT-disabled.xml b/tests/qemuxmlconfdata/disk-usb-device.x86_64-= latest.QEMU_CAPS_DEVICE_USB_BOT-disabled.xml index 8b78f77e63..75e489ede3 100644 --- a/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.QEMU_CAPS_DEVICE_= USB_BOT-disabled.xml +++ b/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.QEMU_CAPS_DEVICE_= USB_BOT-disabled.xml @@ -17,51 +17,51 @@ destroy /usr/bin/qemu-system-x86_64 - + - + - + testserial1 - + testserial2 - + - + - + testserial3 - + @@ -69,24 +69,24 @@ testserial4 - + - + testserial5 - + - + diff --git a/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.abi-update= .QEMU_CAPS_DEVICE_USB_BOT-disabled.xml b/tests/qemuxmlconfdata/disk-usb-dev= ice.x86_64-latest.abi-update.QEMU_CAPS_DEVICE_USB_BOT-disabled.xml index 732230e722..b5954973c6 100644 --- a/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.abi-update.QEMU_C= APS_DEVICE_USB_BOT-disabled.xml +++ b/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.abi-update.QEMU_C= APS_DEVICE_USB_BOT-disabled.xml @@ -17,27 +17,27 @@ destroy /usr/bin/qemu-system-x86_64 - +
- +
- + testserial1
- + @@ -45,14 +45,14 @@ testserial2
- +
- + @@ -60,7 +60,7 @@
- + @@ -68,7 +68,7 @@
- + @@ -77,27 +77,27 @@
- +
- + testserial5
- +
- + diff --git a/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.abi-update= .xml b/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.abi-update.xml index 732230e722..b77bf4717c 100644 --- a/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.abi-update.xml +++ b/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.abi-update.xml @@ -17,27 +17,27 @@ destroy /usr/bin/qemu-system-x86_64 - +
- +
- + testserial1
- + @@ -45,14 +45,14 @@ testserial2
- +
- + @@ -60,7 +60,7 @@
- + @@ -68,7 +68,7 @@
- + @@ -77,27 +77,27 @@
- +
- + testserial5
- +
- + diff --git a/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.xml b/test= s/qemuxmlconfdata/disk-usb-device.x86_64-latest.xml index 8b78f77e63..75e489ede3 100644 --- a/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.xml +++ b/tests/qemuxmlconfdata/disk-usb-device.x86_64-latest.xml @@ -17,51 +17,51 @@ destroy /usr/bin/qemu-system-x86_64 - + - + - + testserial1 - + testserial2 - + - + - + testserial3 - + @@ -69,24 +69,24 @@ testserial4 - + - + testserial5 - + - + --=20 2.49.0