Enable QXL device build
Enable building for ppc64le Re-added Spice support Don't remove slof.bin for ppc64le
This commit is contained in:
commit
2193b5dfba
273
kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch
Normal file
273
kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch
Normal file
@ -0,0 +1,273 @@
|
||||
From 1fe4e3379f5f3ae4e5554b18b4b8c50fedd9203f Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Mon, 11 Aug 2025 15:40:10 +0200
|
||||
Subject: [PATCH] rbd: Fix .bdrv_get_specific_info implementation
|
||||
|
||||
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
||||
RH-MergeRequest: 399: rbd: Fix .bdrv_get_specific_info implementation
|
||||
RH-Jira: RHEL-105440
|
||||
RH-Acked-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
RH-Commit: [1/1] 840c954c84c97f768ae6cfb4aa0e2766b22a6f06 (kmwolf/centos-qemu-kvm)
|
||||
|
||||
qemu_rbd_get_specific_info() has at least two problems:
|
||||
|
||||
The first is that it issues a blocking rbd_read() call in order to probe
|
||||
the encryption format for the image while querying the node. This means
|
||||
that if the connection to the server goes down, not only I/O is stuck
|
||||
(which is unavoidable), but query-names-block-nodes will actually make
|
||||
the whole QEMU instance unresponsive. .bdrv_get_specific_info
|
||||
implementations shouldn't perform blocking operations, but only return
|
||||
what is already known.
|
||||
|
||||
The second is that the information returned isn't even correct. If the
|
||||
image is already opened with encryption enabled at the RBD level, we'll
|
||||
probe for "double encryption", i.e. if the encrypted data contains
|
||||
another encryption header. If it doesn't (which is the normal case), we
|
||||
won't return the encryption format. If it does, we return misleading
|
||||
information because it looks like we're talking about the outer level
|
||||
(the encryption format of the image itself) while the information is
|
||||
about an encryption header in the guest data.
|
||||
|
||||
Fix this by storing the encryption format in BDRVRBDState when the image
|
||||
is opened (and we do blocking operations anyway) and returning only the
|
||||
stored information in qemu_rbd_get_specific_info().
|
||||
|
||||
The information we'll store is either the actual encryption format that
|
||||
we enabled on the RBD level, or if the image is unencrypted, the result
|
||||
of the same probing as we previously did when querying the node. Probing
|
||||
image formats based on content that can be modified by the guest has
|
||||
long been known as problematic, but as long as we only output it to the
|
||||
user instead of making decisions based on it, it should be okay. It is
|
||||
undoubtedly useful in the context of 'qemu-img info' when you're trying
|
||||
to figure out which encryption options you have to use to open the
|
||||
image successfully.
|
||||
|
||||
Fixes: 42e4ac9ef5a6 ("block/rbd: Add support for rbd image encryption")
|
||||
Buglink: https://issues.redhat.com/browse/RHEL-105440
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Message-ID: <20250811134010.81787-1-kwolf@redhat.com>
|
||||
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
(cherry picked from commit 4af976ef398e4e823addc00bf1c58787ba4952fe)
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/rbd.c | 104 ++++++++++++++++++++++++++++---------------
|
||||
qapi/block-core.json | 9 +++-
|
||||
2 files changed, 76 insertions(+), 37 deletions(-)
|
||||
|
||||
diff --git a/block/rbd.c b/block/rbd.c
|
||||
index 4f3d42a8e7..9b7b834f04 100644
|
||||
--- a/block/rbd.c
|
||||
+++ b/block/rbd.c
|
||||
@@ -99,6 +99,14 @@ typedef struct BDRVRBDState {
|
||||
char *namespace;
|
||||
uint64_t image_size;
|
||||
uint64_t object_size;
|
||||
+
|
||||
+ /*
|
||||
+ * If @bs->encrypted is true, this is the encryption format actually loaded
|
||||
+ * at the librbd level. If it is false, it is the result of probing.
|
||||
+ * RBD_IMAGE_ENCRYPTION_FORMAT__MAX means that encryption is not enabled and
|
||||
+ * probing didn't find any known encryption header either.
|
||||
+ */
|
||||
+ RbdImageEncryptionFormat encryption_format;
|
||||
} BDRVRBDState;
|
||||
|
||||
typedef struct RBDTask {
|
||||
@@ -471,10 +479,12 @@ static int qemu_rbd_encryption_format(rbd_image_t image,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int qemu_rbd_encryption_load(rbd_image_t image,
|
||||
+static int qemu_rbd_encryption_load(BlockDriverState *bs,
|
||||
+ rbd_image_t image,
|
||||
RbdEncryptionOptions *encrypt,
|
||||
Error **errp)
|
||||
{
|
||||
+ BDRVRBDState *s = bs->opaque;
|
||||
int r = 0;
|
||||
g_autofree char *passphrase = NULL;
|
||||
rbd_encryption_luks1_format_options_t luks_opts;
|
||||
@@ -545,15 +555,19 @@ static int qemu_rbd_encryption_load(rbd_image_t image,
|
||||
error_setg_errno(errp, -r, "encryption load fail");
|
||||
return r;
|
||||
}
|
||||
+ bs->encrypted = true;
|
||||
+ s->encryption_format = encrypt->format;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
|
||||
-static int qemu_rbd_encryption_load2(rbd_image_t image,
|
||||
+static int qemu_rbd_encryption_load2(BlockDriverState *bs,
|
||||
+ rbd_image_t image,
|
||||
RbdEncryptionOptions *encrypt,
|
||||
Error **errp)
|
||||
{
|
||||
+ BDRVRBDState *s = bs->opaque;
|
||||
int r = 0;
|
||||
int encrypt_count = 1;
|
||||
int i;
|
||||
@@ -639,6 +653,8 @@ static int qemu_rbd_encryption_load2(rbd_image_t image,
|
||||
error_setg_errno(errp, -r, "layered encryption load fail");
|
||||
goto exit;
|
||||
}
|
||||
+ bs->encrypted = true;
|
||||
+ s->encryption_format = encrypt->format;
|
||||
|
||||
exit:
|
||||
for (i = 0; i < encrypt_count; ++i) {
|
||||
@@ -672,6 +688,45 @@ exit:
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+/*
|
||||
+ * For an image without encryption enabled on the rbd layer, probe the start of
|
||||
+ * the image if it could be opened as an encrypted image so that we can display
|
||||
+ * it when the user queries the node (most importantly in qemu-img).
|
||||
+ *
|
||||
+ * If the guest writes an encryption header to its disk after this probing, this
|
||||
+ * won't be reflected when queried, but that's okay. There is no reason why the
|
||||
+ * user should want to apply encryption at the rbd level while the image is
|
||||
+ * still in use. This is just guest data.
|
||||
+ */
|
||||
+static void qemu_rbd_encryption_probe(BlockDriverState *bs)
|
||||
+{
|
||||
+ BDRVRBDState *s = bs->opaque;
|
||||
+ char buf[RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {0};
|
||||
+ int r;
|
||||
+
|
||||
+ assert(s->encryption_format == RBD_IMAGE_ENCRYPTION_FORMAT__MAX);
|
||||
+
|
||||
+ r = rbd_read(s->image, 0,
|
||||
+ RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN, buf);
|
||||
+ if (r < RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (memcmp(buf, rbd_luks_header_verification,
|
||||
+ RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||
+ s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
|
||||
+ } else if (memcmp(buf, rbd_luks2_header_verification,
|
||||
+ RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||
+ s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
|
||||
+ } else if (memcmp(buf, rbd_layered_luks_header_verification,
|
||||
+ RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||
+ s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
|
||||
+ } else if (memcmp(buf, rbd_layered_luks2_header_verification,
|
||||
+ RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||
+ s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/* FIXME Deprecate and remove keypairs or make it available in QMP. */
|
||||
static int qemu_rbd_do_create(BlockdevCreateOptions *options,
|
||||
const char *keypairs, const char *password_secret,
|
||||
@@ -1134,17 +1189,18 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
goto failed_open;
|
||||
}
|
||||
|
||||
+ s->encryption_format = RBD_IMAGE_ENCRYPTION_FORMAT__MAX;
|
||||
if (opts->encrypt) {
|
||||
#ifdef LIBRBD_SUPPORTS_ENCRYPTION
|
||||
if (opts->encrypt->parent) {
|
||||
#ifdef LIBRBD_SUPPORTS_ENCRYPTION_LOAD2
|
||||
- r = qemu_rbd_encryption_load2(s->image, opts->encrypt, errp);
|
||||
+ r = qemu_rbd_encryption_load2(bs, s->image, opts->encrypt, errp);
|
||||
#else
|
||||
r = -ENOTSUP;
|
||||
error_setg(errp, "RBD library does not support layered encryption");
|
||||
#endif
|
||||
} else {
|
||||
- r = qemu_rbd_encryption_load(s->image, opts->encrypt, errp);
|
||||
+ r = qemu_rbd_encryption_load(bs, s->image, opts->encrypt, errp);
|
||||
}
|
||||
if (r < 0) {
|
||||
goto failed_post_open;
|
||||
@@ -1154,6 +1210,8 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
error_setg(errp, "RBD library does not support image encryption");
|
||||
goto failed_post_open;
|
||||
#endif
|
||||
+ } else {
|
||||
+ qemu_rbd_encryption_probe(bs);
|
||||
}
|
||||
|
||||
r = rbd_stat(s->image, &info, sizeof(info));
|
||||
@@ -1413,17 +1471,6 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
|
||||
{
|
||||
BDRVRBDState *s = bs->opaque;
|
||||
ImageInfoSpecific *spec_info;
|
||||
- char buf[RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN] = {0};
|
||||
- int r;
|
||||
-
|
||||
- if (s->image_size >= RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) {
|
||||
- r = rbd_read(s->image, 0,
|
||||
- RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN, buf);
|
||||
- if (r < 0) {
|
||||
- error_setg_errno(errp, -r, "cannot read image start for probe");
|
||||
- return NULL;
|
||||
- }
|
||||
- }
|
||||
|
||||
spec_info = g_new(ImageInfoSpecific, 1);
|
||||
*spec_info = (ImageInfoSpecific){
|
||||
@@ -1431,28 +1478,13 @@ static ImageInfoSpecific *qemu_rbd_get_specific_info(BlockDriverState *bs,
|
||||
.u.rbd.data = g_new0(ImageInfoSpecificRbd, 1),
|
||||
};
|
||||
|
||||
- if (memcmp(buf, rbd_luks_header_verification,
|
||||
- RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||
- spec_info->u.rbd.data->encryption_format =
|
||||
- RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
|
||||
- spec_info->u.rbd.data->has_encryption_format = true;
|
||||
- } else if (memcmp(buf, rbd_luks2_header_verification,
|
||||
- RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||
- spec_info->u.rbd.data->encryption_format =
|
||||
- RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
|
||||
- spec_info->u.rbd.data->has_encryption_format = true;
|
||||
- } else if (memcmp(buf, rbd_layered_luks_header_verification,
|
||||
- RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||
- spec_info->u.rbd.data->encryption_format =
|
||||
- RBD_IMAGE_ENCRYPTION_FORMAT_LUKS;
|
||||
- spec_info->u.rbd.data->has_encryption_format = true;
|
||||
- } else if (memcmp(buf, rbd_layered_luks2_header_verification,
|
||||
- RBD_ENCRYPTION_LUKS_HEADER_VERIFICATION_LEN) == 0) {
|
||||
- spec_info->u.rbd.data->encryption_format =
|
||||
- RBD_IMAGE_ENCRYPTION_FORMAT_LUKS2;
|
||||
- spec_info->u.rbd.data->has_encryption_format = true;
|
||||
+ if (s->encryption_format == RBD_IMAGE_ENCRYPTION_FORMAT__MAX) {
|
||||
+ assert(!bs->encrypted);
|
||||
} else {
|
||||
- spec_info->u.rbd.data->has_encryption_format = false;
|
||||
+ ImageInfoSpecificRbd *rbd_info = spec_info->u.rbd.data;
|
||||
+
|
||||
+ rbd_info->has_encryption_format = true;
|
||||
+ rbd_info->encryption_format = s->encryption_format;
|
||||
}
|
||||
|
||||
return spec_info;
|
||||
diff --git a/qapi/block-core.json b/qapi/block-core.json
|
||||
index 7f70ec6d3c..d00161af87 100644
|
||||
--- a/qapi/block-core.json
|
||||
+++ b/qapi/block-core.json
|
||||
@@ -158,7 +158,14 @@
|
||||
##
|
||||
# @ImageInfoSpecificRbd:
|
||||
#
|
||||
-# @encryption-format: Image encryption format
|
||||
+# @encryption-format: Image encryption format. If encryption is enabled for the
|
||||
+# image (see encrypted in BlockNodeInfo), this is the actual format in which the
|
||||
+# image is accessed. If encryption is not enabled, this is the result of
|
||||
+# probing when the image was opened, to give a suggestion which encryption
|
||||
+# format could be enabled. Note that probing results can be changed by the
|
||||
+# guest by writing a (possibly partial) encryption format header to the
|
||||
+# image, so don't treat this information as trusted if the guest is not
|
||||
+# trusted.
|
||||
#
|
||||
# Since: 6.1
|
||||
##
|
||||
--
|
||||
2.39.3
|
||||
|
@ -158,7 +158,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \
|
||||
Summary: QEMU is a machine emulator and virtualizer
|
||||
Name: qemu-kvm
|
||||
Version: 10.0.0
|
||||
Release: 10%{?rcrel}%{?dist}%{?cc_suffix}.alma.1
|
||||
Release: 11%{?rcrel}%{?dist}%{?cc_suffix}.alma.1
|
||||
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
|
||||
# Epoch 15 used for RHEL 8
|
||||
# Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5)
|
||||
@ -433,6 +433,8 @@ Patch127: kvm-iotests-graph-changes-while-io-add-test-case-with-re.patch
|
||||
Patch128: kvm-Declare-rtl8139-as-deprecated.patch
|
||||
# For RHEL-102325 - [qemu] enable variable service for edk2
|
||||
Patch129: kvm-Enable-uefi-variable-service-for-edk2.patch
|
||||
# For RHEL-105440 - Openstack guest becomes inaccessible via network when storage network on the hypervisor is disabled/lost [rhel-10.1]
|
||||
Patch130: kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch
|
||||
|
||||
# AlmaLinux Patch
|
||||
Patch2001: 2001-Add-ppc64-support.patch
|
||||
@ -1564,12 +1566,17 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Aug 13 2025 Eduard Abdullin <eabdullin@almalinux.org> - 18:10.0.0-10.alma.1
|
||||
* Tue Aug 19 2025 Eduard Abdullin <eabdullin@almalinux.org> - 18:10.0.0-11.alma.1
|
||||
- Enable QXL device build
|
||||
- Enable building for ppc64le
|
||||
- Re-added Spice support
|
||||
- Don't remove slof.bin for ppc64le
|
||||
|
||||
* Mon Aug 18 2025 Miroslav Rezanina <mrezanin@redhat.com> - 10.0.0-11
|
||||
- kvm-rbd-Fix-.bdrv_get_specific_info-implementation.patch [RHEL-105440]
|
||||
- Resolves: RHEL-105440
|
||||
(Openstack guest becomes inaccessible via network when storage network on the hypervisor is disabled/lost [rhel-10.1])
|
||||
|
||||
* Tue Aug 12 2025 Miroslav Rezanina <mrezanin@redhat.com> - 10.0.0-10
|
||||
- kvm-Enable-uefi-variable-service-for-edk2.patch [RHEL-102325]
|
||||
- Resolves: RHEL-102325
|
||||
|
Loading…
Reference in New Issue
Block a user