librbd: permit disabling QCOW migration format support

Downstream Red Hat products do not support the older QCOW format. This
will allow the support for the legacy QCOW format to be disabled for the
new RBD import-only migration support.

Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2021-02-22 10:23:01 -05:00
parent d8b02aef52
commit bc0b9f52ad
6 changed files with 43 additions and 1 deletions

View File

@ -232,6 +232,10 @@ CMAKE_DEPENDENT_OPTION(WITH_SYSTEM_LIBURING "Require and build with system libur
CMAKE_DEPENDENT_OPTION(WITH_BLUESTORE_PMEM "Enable PMDK libraries" OFF
"WITH_BLUESTORE" OFF)
CMAKE_DEPENDENT_OPTION(WITH_RBD_MIGRATION_FORMAT_QCOW_V1
"Enable librbd QCOW v1 migration format support" ON
"WITH_RBD" OFF)
CMAKE_DEPENDENT_OPTION(WITH_RBD_RWL "Enable librbd persistent write back cache" OFF
"WITH_RBD" OFF)

View File

@ -162,8 +162,17 @@ test_import_qcow_format() {
EOF
cat ${TEMPDIR}/spec.json
set +e
rbd migration prepare --import-only \
--source-spec-path ${TEMPDIR}/spec.json ${dest_image}
local error_code=$?
set -e
if [ $error_code -eq 95 ]; then
echo "skipping QCOW test (librbd support disabled)"
return 0
fi
test $error_code -eq 0
compare_images "${base_image}" "${dest_image}"

View File

@ -360,6 +360,9 @@
/* Define if unit tests are built. */
#cmakedefine UNIT_TESTS_BUILT
/* Define if RBD QCOW migration format is enabled */
#cmakedefine WITH_RBD_MIGRATION_FORMAT_QCOW_V1
/* Define if RWL is enabled */
#cmakedefine WITH_RBD_RWL

View File

@ -901,7 +901,12 @@ void QCOWFormat<I>::handle_probe(int r, Context* on_finish) {
m_bl.clear();
if (header_probe.version == 1) {
#ifdef WITH_RBD_MIGRATION_FORMAT_QCOW_V1
read_v1_header(on_finish);
#else // WITH_RBD_MIGRATION_FORMAT_QCOW_V1
lderr(cct) << "QCOW is not supported" << dendl;
on_finish->complete(-ENOTSUP);
#endif // WITH_RBD_MIGRATION_FORMAT_QCOW_V1
return;
} else if (header_probe.version >= 2 && header_probe.version <= 3) {
read_v2_header(on_finish);
@ -914,6 +919,8 @@ void QCOWFormat<I>::handle_probe(int r, Context* on_finish) {
}
}
#ifdef WITH_RBD_MIGRATION_FORMAT_QCOW_V1
template <typename I>
void QCOWFormat<I>::read_v1_header(Context* on_finish) {
auto cct = m_image_ctx->cct;
@ -1014,6 +1021,8 @@ void QCOWFormat<I>::handle_read_v1_header(int r, Context* on_finish) {
read_l1_table(on_finish);
}
#endif // WITH_RBD_MIGRATION_FORMAT_QCOW_V1
template <typename I>
void QCOWFormat<I>::read_v2_header(Context* on_finish) {
auto cct = m_image_ctx->cct;

View File

@ -8,6 +8,7 @@
#include "librbd/Types.h"
#include "librbd/migration/FormatInterface.h"
#include "librbd/migration/QCOW.h"
#include "acconfig.h"
#include "json_spirit/json_spirit.h"
#include <boost/asio/io_context_strand.hpp>
#include <boost/iostreams/filter/zlib.hpp>
@ -175,8 +176,10 @@ private:
void probe(Context* on_finish);
void handle_probe(int r, Context* on_finish);
#ifdef WITH_RBD_MIGRATION_FORMAT_QCOW_V1
void read_v1_header(Context* on_finish);
void handle_read_v1_header(int r, Context* on_finish);
#endif // WITH_RBD_MIGRATION_FORMAT_QCOW_V1
void read_v2_header(Context* on_finish);
void handle_read_v2_header(int r, Context* on_finish);

View File

@ -8,6 +8,7 @@
#include "common/ceph_mutex.h"
#include "librbd/migration/QCOWFormat.h"
#include "librbd/migration/SourceSpecBuilder.h"
#include "acconfig.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "json_spirit/json_spirit.h"
@ -291,6 +292,7 @@ TEST_F(TestMockMigrationQCOWFormat, OpenCloseV1) {
expect_stream_open(*mock_stream_interface, 0);
int expected_open_ret_val = 0;
QCowHeaderV1 qcow_header;
memset(&qcow_header, 0, sizeof(qcow_header));
qcow_header.magic = htobe32(QCOW_MAGIC);
@ -304,6 +306,8 @@ TEST_F(TestMockMigrationQCOWFormat, OpenCloseV1) {
probe_bl.append(std::string_view(reinterpret_cast<char*>(&qcow_header), 8));
expect_stream_read(*mock_stream_interface, {{0, 8}}, probe_bl, 0);
#ifdef WITH_RBD_MIGRATION_FORMAT_QCOW_V1
bufferlist header_bl;
header_bl.append(std::string_view(reinterpret_cast<char*>(&qcow_header),
sizeof(qcow_header)));
@ -314,6 +318,12 @@ TEST_F(TestMockMigrationQCOWFormat, OpenCloseV1) {
l1_table_bl.append_zero(16);
expect_stream_read(*mock_stream_interface, {{1<<20, 16}}, l1_table_bl, 0);
#else // WITH_RBD_MIGRATION_FORMAT_QCOW_V1
expected_open_ret_val = -ENOTSUP;
#endif // WITH_RBD_MIGRATION_FORMAT_QCOW_V1
expect_stream_close(*mock_stream_interface, 0);
MockQCOWFormat mock_qcow_format(&mock_image_ctx, json_object,
@ -321,7 +331,7 @@ TEST_F(TestMockMigrationQCOWFormat, OpenCloseV1) {
C_SaferCond ctx1;
mock_qcow_format.open(&ctx1);
ASSERT_EQ(0, ctx1.wait());
ASSERT_EQ(expected_open_ret_val, ctx1.wait());
C_SaferCond ctx2;
mock_qcow_format.close(&ctx2);
@ -434,6 +444,8 @@ TEST_F(TestMockMigrationQCOWFormat, ProbeError) {
ASSERT_EQ(0, ctx2.wait());
}
#ifdef WITH_RBD_MIGRATION_FORMAT_QCOW_V1
TEST_F(TestMockMigrationQCOWFormat, ReadHeaderV1Error) {
MockTestImageCtx mock_image_ctx(*m_image_ctx);
@ -476,6 +488,8 @@ TEST_F(TestMockMigrationQCOWFormat, ReadHeaderV1Error) {
ASSERT_EQ(0, ctx2.wait());
}
#endif // WITH_RBD_MIGRATION_FORMAT_QCOW_V1
TEST_F(TestMockMigrationQCOWFormat, ReadHeaderV2Error) {
MockTestImageCtx mock_image_ctx(*m_image_ctx);