From bc0b9f52ad71ae0e2dbc9a6e3e884a8a7cd02e9b Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Mon, 22 Feb 2021 10:23:01 -0500 Subject: [PATCH] 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 --- CMakeLists.txt | 4 ++++ qa/workunits/rbd/cli_migration.sh | 9 +++++++++ src/include/config-h.in.cmake | 3 +++ src/librbd/migration/QCOWFormat.cc | 9 +++++++++ src/librbd/migration/QCOWFormat.h | 3 +++ .../librbd/migration/test_mock_QCOWFormat.cc | 16 +++++++++++++++- 6 files changed, 43 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 550f815d220..8b4effd89bb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/qa/workunits/rbd/cli_migration.sh b/qa/workunits/rbd/cli_migration.sh index 9e909985037..be8e031fd1b 100755 --- a/qa/workunits/rbd/cli_migration.sh +++ b/qa/workunits/rbd/cli_migration.sh @@ -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}" diff --git a/src/include/config-h.in.cmake b/src/include/config-h.in.cmake index 9a4e1a6479f..39aa5bbc427 100644 --- a/src/include/config-h.in.cmake +++ b/src/include/config-h.in.cmake @@ -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 diff --git a/src/librbd/migration/QCOWFormat.cc b/src/librbd/migration/QCOWFormat.cc index 4dfbbf0944c..7bd4a5ef748 100644 --- a/src/librbd/migration/QCOWFormat.cc +++ b/src/librbd/migration/QCOWFormat.cc @@ -901,7 +901,12 @@ void QCOWFormat::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::handle_probe(int r, Context* on_finish) { } } +#ifdef WITH_RBD_MIGRATION_FORMAT_QCOW_V1 + template void QCOWFormat::read_v1_header(Context* on_finish) { auto cct = m_image_ctx->cct; @@ -1014,6 +1021,8 @@ void QCOWFormat::handle_read_v1_header(int r, Context* on_finish) { read_l1_table(on_finish); } +#endif // WITH_RBD_MIGRATION_FORMAT_QCOW_V1 + template void QCOWFormat::read_v2_header(Context* on_finish) { auto cct = m_image_ctx->cct; diff --git a/src/librbd/migration/QCOWFormat.h b/src/librbd/migration/QCOWFormat.h index 1bceb7df762..b3650671650 100644 --- a/src/librbd/migration/QCOWFormat.h +++ b/src/librbd/migration/QCOWFormat.h @@ -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 #include @@ -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); diff --git a/src/test/librbd/migration/test_mock_QCOWFormat.cc b/src/test/librbd/migration/test_mock_QCOWFormat.cc index 3515a0e7aa1..6e7225d2243 100644 --- a/src/test/librbd/migration/test_mock_QCOWFormat.cc +++ b/src/test/librbd/migration/test_mock_QCOWFormat.cc @@ -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(&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(&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);