[RFC PATCH 0/3] qemu: Add support for control of persistent reservation migration
Add support for migration of persistent reservations. Depends on RFC qemu patches: https://mail.gnu.org/archive/html/qemu-block/2026-01/msg00159.html Applies on top of my patches for new capabilities. Caps dump in 1/3 is based on a local build and thus will be replaced once I'll be doing an official update. Peter Krempa (3): DO_NOT_PUSH: qemucapabilitiestest: Regenerate with 'migrate-pr' patches qemu: capabilities: Introduce QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR qemu: Implement support for persistent reservation migration control docs/formatdomain.rst | 3 +++ src/conf/domain_conf.c | 21 +++++++++++++++++++ src/conf/schemas/storagecommon.rng | 5 +++++ src/conf/storage_source_conf.c | 10 +++++++++ src/conf/storage_source_conf.h | 2 ++ src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_command.c | 4 ++++ src/qemu/qemu_validate.c | 16 ++++++++++++++ .../caps_11.0.0_x86_64.replies | 8 ++++++- .../caps_11.0.0_x86_64.xml | 3 ++- ...irtio-scsi-reservations.x86_64-latest.args | 2 +- .../disk-virtio-scsi-reservations.xml | 2 +- 13 files changed, 75 insertions(+), 4 deletions(-) -- 2.52.0
From: Peter Krempa <pkrempa@redhat.com> --- tests/qemucapabilitiesdata/caps_11.0.0_x86_64.replies | 8 +++++++- tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.replies b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.replies index b440599948..168ebdf2d3 100644 --- a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.replies +++ b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.replies @@ -20,7 +20,7 @@ "minor": 2, "major": 10 }, - "package": "v10.2.0-476-gcf3e71d8fc" + "package": "v10.2.0-480-gb1cb7d3d1a" }, "id": "libvirt-2" } @@ -32972,6 +32972,12 @@ "description": "on/off", "type": "bool" }, + { + "default-value": true, + "name": "migrate-pr", + "description": "on/off", + "type": "bool" + }, { "default-value": "auto", "name": "werror", diff --git a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml index f5ef2b2e45..ab437c5367 100644 --- a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml @@ -217,7 +217,7 @@ <flag name='query-accelerators'/> <version>10002050</version> <microcodeVersion>43100286</microcodeVersion> - <package>v10.2.0-476-gcf3e71d8fc</package> + <package>v10.2.0-480-gb1cb7d3d1a</package> <arch>x86_64</arch> <hostCPU type='kvm' model='base' migratability='yes'> <property name='avx-ne-convert' type='boolean' value='false'/> -- 2.52.0
From: Peter Krempa <pkrempa@redhat.com> Introduce capability for persisten migration control support. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml | 1 + 3 files changed, 4 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index f456e8a378..f6e3b279a3 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -755,6 +755,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "disk-timed-stats", /* QEMU_CAPS_DISK_TIMED_STATS */ "query-accelerators", /* QEMU_CAPS_QUERY_ACCELERATORS */ "mshv", /* QEMU_CAPS_MSHV */ + "scsi-block.migrate-pr", /* QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR */ ); @@ -1536,6 +1537,7 @@ static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIDisk[] = { }; static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIBlock[] = { + { "migrate-pr", QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, NULL }, }; static struct virQEMUCapsDevicePropsFlags virQEMUCapsDevicePropsSCSIGeneric[] = { diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index f180844e66..0c76f2edda 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -730,6 +730,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_DISK_TIMED_STATS, /* timed stats support ('stats-intervals' property of disk frontends) */ QEMU_CAPS_QUERY_ACCELERATORS, /* query-accelerators command */ QEMU_CAPS_MSHV, /* -accel mshv */ + QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR, /* persistent reservation migration support */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml index ab437c5367..a4cc66e9ff 100644 --- a/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_11.0.0_x86_64.xml @@ -215,6 +215,7 @@ <flag name='acpi-generic-initiator'/> <flag name='disk-timed-stats'/> <flag name='query-accelerators'/> + <flag name='scsi-block.migrate-pr'/> <version>10002050</version> <microcodeVersion>43100286</microcodeVersion> <package>v10.2.0-480-gb1cb7d3d1a</package> -- 2.52.0
From: Peter Krempa <pkrempa@redhat.com> The 'migration' attribute for the '<reservations>' element allows to control the persistent reservation migration feature independently of the machine type default. Add the XML plumbing and qemu support. We consider it ABI for now since it influences qemu migration protocol. Signed-off-by: Peter Krempa <pkrempa@redhat.com> --- docs/formatdomain.rst | 3 +++ src/conf/domain_conf.c | 21 +++++++++++++++++++ src/conf/schemas/storagecommon.rng | 5 +++++ src/conf/storage_source_conf.c | 10 +++++++++ src/conf/storage_source_conf.h | 2 ++ src/qemu/qemu_command.c | 4 ++++ src/qemu/qemu_validate.c | 16 ++++++++++++++ ...irtio-scsi-reservations.x86_64-latest.args | 2 +- .../disk-virtio-scsi-reservations.xml | 2 +- 9 files changed, 63 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 04ef319a73..6366a07e54 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -3182,6 +3182,9 @@ paravirtualized driver is specified via the ``disk`` element. the socket, and finally ``mode`` which accepts one value ``client`` specifying the role of hypervisor. It's recommended to allow libvirt manage the persistent reservations. + :since:`Since 12.1.0` the ``migration`` (values ``yes``, ``no``) controls + whether the hypervisor should attempt to migrate persistent reservations + during migration. ``initiator`` :since:`Since 4.7.0`, the ``initiator`` element is supported for a disk ``type`` "network" that is using a ``source`` element with the diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9ca5c2450c..b57792b8f9 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -20917,6 +20917,27 @@ virDomainDiskDefCheckABIStability(virDomainDiskDef *src, return false; } + /* While not guest visible it influences the qemu migration stream so + * we need to keep it identical */ + if (src->src->pr || dst->src->pr) { + virTristateBool srcmig = VIR_TRISTATE_BOOL_ABSENT; + virTristateBool dstmig = VIR_TRISTATE_BOOL_ABSENT; + + if (src->src->pr) + srcmig = src->src->pr->migration; + + if (dst->src->pr) + dstmig = dst->src->pr->migration; + + if (srcmig != dstmig) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target disk reservations 'migration' property %1$s does not match source %2$s"), + virTristateBoolTypeToString(dstmig), + virTristateBoolTypeToString(srcmig)); + return false; + } + } + if (!virDomainVirtioOptionsCheckABIStability(src->virtio, dst->virtio)) return false; diff --git a/src/conf/schemas/storagecommon.rng b/src/conf/schemas/storagecommon.rng index 14704c737e..450d53131f 100644 --- a/src/conf/schemas/storagecommon.rng +++ b/src/conf/schemas/storagecommon.rng @@ -104,6 +104,11 @@ <ref name="virYesNo"/> </attribute> </optional> + <optional> + <attribute name="migration"> + <ref name="virYesNo"/> + </attribute> + </optional> <optional> <ref name="unixSocketSource"/> </optional> diff --git a/src/conf/storage_source_conf.c b/src/conf/storage_source_conf.c index d7b9bdfecb..e5f20fba80 100644 --- a/src/conf/storage_source_conf.c +++ b/src/conf/storage_source_conf.c @@ -331,6 +331,11 @@ virStoragePRDefParseXML(xmlXPathContextPtr ctxt) &prd->managed) < 0) goto cleanup; + if (virXMLPropTristateBool(ctxt->node, "migration", + VIR_XML_PROP_NONZERO, + &prd->migration) < 0) + goto cleanup; + type = virXPathString("string(./source[1]/@type)", ctxt); path = virXPathString("string(./source[1]/@path)", ctxt); mode = virXPathString("string(./source[1]/@mode)", ctxt); @@ -385,6 +390,11 @@ virStoragePRDefFormat(virBuffer *buf, { virBufferAsprintf(buf, "<reservations managed='%s'", virTristateBoolTypeToString(prd->managed)); + + if (prd->migration != VIR_TRISTATE_BOOL_ABSENT) + virBufferAsprintf(buf, " migration='%s'", + virTristateBoolTypeToString(prd->migration)); + if (prd->path && (prd->managed == VIR_TRISTATE_BOOL_NO || !migratable)) { virBufferAddLit(buf, ">\n"); diff --git a/src/conf/storage_source_conf.h b/src/conf/storage_source_conf.h index 22c35d420d..d3a9b0e7a2 100644 --- a/src/conf/storage_source_conf.h +++ b/src/conf/storage_source_conf.h @@ -236,6 +236,8 @@ struct _virStoragePRDef { virTristateBool managed; char *path; + virTristateBool migration; + /* manager object alias */ char *mgralias; }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 0de0a79b46..cc438435f7 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1692,6 +1692,7 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, g_autofree char *usbdiskalias = NULL; const virDomainDeviceInfo *deviceinfo = &disk->info; g_autoptr(virJSONValue) statistics = NULL; + virTristateBool migrate_pr = VIR_TRISTATE_BOOL_ABSENT; virDomainDeviceInfo usbSCSIinfo = { .type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE, .addr.drive = { .diskbus = VIR_DOMAIN_DISK_BUS_USB }, @@ -1717,6 +1718,8 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, case VIR_DOMAIN_DISK_BUS_SCSI: if (disk->device == VIR_DOMAIN_DISK_DEVICE_LUN) { driver = "scsi-block"; + if (disk->src->pr) + migrate_pr = disk->src->pr->migration; } else { if (disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) { driver = "scsi-cd"; @@ -1938,6 +1941,7 @@ qemuBuildDiskDeviceProps(const virDomainDef *def, "S:rerror", rpolicy, "A:stats-intervals", &statistics, "T:dpofua", disk->dpofua, /* SCSI-only, ensured by validation */ + "T:migrate-pr", migrate_pr, /* 'scsi-block' only, ensured by validation */ NULL) < 0) return NULL; diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 184c23d307..fcd59e62ee 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -3225,6 +3225,22 @@ qemuValidateDomainDeviceDefDiskFrontend(const virDomainDiskDef *disk, } } + if (disk->src->pr && + disk->src->pr->migration != VIR_TRISTATE_BOOL_ABSENT) { + if (disk->device != VIR_DOMAIN_DISK_DEVICE_LUN || + disk->bus != VIR_DOMAIN_DISK_BUS_SCSI) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("persistent reservation migration supported only with 'lun' disks on 'scsi' bus")); + return -1; + } + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SCSI_BLOCK_MIGRATE_PR)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("persistent reservation migration not supported by this qemu")); + return -1; + } + } + if (disk->rotation_rate) { if (disk->bus != VIR_DOMAIN_DISK_BUS_SCSI && disk->bus != VIR_DOMAIN_DISK_BUS_IDE && diff --git a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args index cbc2a0f398..f1d7a450ee 100644 --- a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args +++ b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.x86_64-latest.args @@ -33,7 +33,7 @@ XDG_CONFIG_HOME=/var/lib/libvirt/qemu/domain--1-QEMUGuest1/.config \ -device '{"driver":"scsi-block","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":0,"drive":"libvirt-2-storage","id":"scsi0-0-0-0","bootindex":1}' \ -object '{"qom-type":"pr-manager-helper","id":"pr-helper-libvirt-1-storage","path":"/path/to/qemu-pr-helper.sock"}' \ -blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest2","pr-manager":"pr-helper-libvirt-1-storage","node-name":"libvirt-1-storage","read-only":false}' \ --device '{"driver":"scsi-block","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":1,"drive":"libvirt-1-storage","id":"scsi0-0-0-1"}' \ +-device '{"driver":"scsi-block","bus":"scsi0.0","channel":0,"scsi-id":0,"lun":1,"drive":"libvirt-1-storage","id":"scsi0-0-0-1","migrate-pr":true}' \ -audiodev '{"id":"audio1","driver":"none"}' \ -device '{"driver":"virtio-balloon-pci","id":"balloon0","bus":"pci.0","addr":"0x4"}' \ -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ diff --git a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml index 9c55d6ec3e..7f9160ff3a 100644 --- a/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml +++ b/tests/qemuxmlconfdata/disk-virtio-scsi-reservations.xml @@ -28,7 +28,7 @@ <disk type='block' device='lun'> <driver name='qemu' type='raw'/> <source dev='/dev/HostVG/QEMUGuest2'> - <reservations managed='no'> + <reservations managed='no' migration='yes'> <source type='unix' path='/path/to/qemu-pr-helper.sock' mode='client'/> </reservations> </source> -- 2.52.0
participants (1)
-
Peter Krempa