Skip to content

Commit dc8eed6

Browse files
effi-oferidryomov
andcommitted
librbd/migration: add nbd stream
Co-authored-by: Ilya Dryomov <[email protected]> Signed-off-by: Effi Ofer <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent b0d8273 commit dc8eed6

26 files changed

+701
-10
lines changed

CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,12 @@ if(WITH_RBD AND LINUX)
259259
set(HAVE_LIBCRYPTSETUP ${LIBCRYPTSETUP_FOUND})
260260
endif()
261261

262+
# libnbd
263+
if(WITH_RBD AND NOT WIN32)
264+
find_package(libnbd 1.0 REQUIRED)
265+
set(HAVE_LIBNBD ${LIBNBD_FOUND})
266+
endif()
267+
262268
include(CMakeDependentOption)
263269

264270
CMAKE_DEPENDENT_OPTION(WITH_LIBURING "Enable io_uring bluestore backend" ON

ceph.spec.in

+1
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ BuildRequires: gperftools-devel >= 2.4
286286
BuildRequires: libaio-devel
287287
BuildRequires: libblkid-devel >= 2.17
288288
BuildRequires: cryptsetup-devel
289+
BuildRequires: libnbd-devel
289290
BuildRequires: libcurl-devel
290291
BuildRequires: libcap-devel
291292
BuildRequires: libcap-ng-devel

cmake/modules/Findlibnbd.cmake

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# - Find libnbd
2+
# Sets the following:
3+
#
4+
# LIBNBD_INCLUDE_DIR
5+
# LIBNBD_LIBRARIES
6+
# LIBNBD_VERSION
7+
# LIBNBD_FOUND
8+
9+
find_package(PkgConfig QUIET REQUIRED)
10+
pkg_search_module(PC_libnbd libnbd)
11+
12+
find_path(LIBNBD_INCLUDE_DIR
13+
NAMES libnbd.h
14+
PATHS ${PC_libnbd_INCLUDE_DIRS})
15+
16+
find_library(LIBNBD_LIBRARIES
17+
NAMES libnbd.so
18+
PATHS ${PC_libnbd_LIBRARY_DIRS})
19+
20+
set(LIBNBD_VERSION ${PC_libnbd_VERSION})
21+
22+
include(FindPackageHandleStandardArgs)
23+
24+
find_package_handle_standard_args(libnbd
25+
REQUIRED_VARS
26+
LIBNBD_INCLUDE_DIR
27+
LIBNBD_LIBRARIES
28+
VERSION_VAR LIBNBD_VERSION)
29+
30+
mark_as_advanced(
31+
LIBNBD_LIBRARIES
32+
LIBNBD_INCLUDE_DIR
33+
LIBNBD_VERSION)

debian/control

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ Build-Depends: automake,
5454
liblttng-ust-dev,
5555
liblua5.3-dev,
5656
liblz4-dev (>= 0.0~r131),
57+
libnbd-dev,
5758
libncurses-dev,
5859
libnss3-dev,
5960
liboath-dev,

doc/rbd/rbd-live-migration.rst

+16-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ parent.
2020
The live-migration process can also be used in an import-only mode where the
2121
source image remains unmodified and the target image can be linked to an image
2222
in another Ceph cluster or to an external data source such as a backing file,
23-
HTTP(s) file, or S3 object.
23+
HTTP(s) file, S3 object, or NBD export.
2424

2525
The live-migration copy process can safely run in the background while the new
2626
target image is in use. There is currently a requirement to temporarily stop
@@ -145,8 +145,8 @@ The general format for the ``source-spec`` JSON is as follows::
145145
}
146146

147147
The following formats are currently supported: ``native``, ``qcow``, and
148-
``raw``. The following streams are currently supported: ``file``, ``http``, and
149-
``s3``.
148+
``raw``. The following streams are currently supported: ``file``, ``http``,
149+
``s3``, and ``nbd``.
150150

151151
Formats
152152
~~~~~~~
@@ -306,6 +306,19 @@ as follows::
306306
stored in the config-key store via ``ceph config-key set <key-path> <value>``
307307
(e.g. ``ceph config-key set rbd/s3/access_key NX5QOQKC6BH2IDN8HC7A``).
308308

309+
The ``nbd`` stream can be used to import from a remote NBD export. Its
310+
``source-spec`` JSON is encoded as follows::
311+
312+
{
313+
<format unique parameters>
314+
"stream": {
315+
"type": "nbd",
316+
"server": "<server>",
317+
"port": "<port>"
318+
}
319+
}
320+
321+
309322
Execute Migration
310323
=================
311324

qa/workunits/rbd/cli_migration.sh

+44
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ IMAGE3=image3
88
IMAGES="${IMAGE1} ${IMAGE2} ${IMAGE3}"
99

1010
cleanup() {
11+
kill_nbd_server
1112
cleanup_tempdir
1213
remove_images
1314
}
@@ -65,6 +66,10 @@ remove_images() {
6566
done
6667
}
6768

69+
kill_nbd_server() {
70+
pkill -9 qemu-nbd || true
71+
}
72+
6873
show_diff()
6974
{
7075
local file1=$1
@@ -390,6 +395,42 @@ EOF
390395
remove_image "${dest_image}"
391396
}
392397

398+
test_import_nbd_stream() {
399+
local base_image=$1
400+
local dest_image=$2
401+
402+
qemu-nbd -f qcow2 --read-only --shared 10 --persistent --fork \
403+
${TEMPDIR}/${base_image}.qcow2
404+
405+
cat > ${TEMPDIR}/spec.json <<EOF
406+
{
407+
"type": "raw",
408+
"stream": {
409+
"type": "nbd",
410+
"server": "localhost",
411+
"port": "10809"
412+
}
413+
}
414+
EOF
415+
cat ${TEMPDIR}/spec.json
416+
417+
cat ${TEMPDIR}/spec.json | rbd migration prepare --import-only \
418+
--source-spec-path - ${dest_image}
419+
compare_images ${base_image} ${dest_image}
420+
rbd migration abort ${dest_image}
421+
422+
rbd migration prepare --import-only \
423+
--source-spec-path ${TEMPDIR}/spec.json ${dest_image}
424+
compare_images ${base_image} ${dest_image}
425+
rbd migration execute ${dest_image}
426+
compare_images ${base_image} ${dest_image}
427+
rbd migration commit ${dest_image}
428+
compare_images ${base_image} ${dest_image}
429+
remove_image "${dest_image}"
430+
431+
kill_nbd_server
432+
}
433+
393434
# make sure rbd pool is EMPTY.. this is a test script!!
394435
rbd ls 2>&1 | wc -l | grep -v '^0$' && echo "nonempty rbd pool, aborting! run this script on an empty test cluster only." && exit 1
395436

@@ -401,7 +442,10 @@ export_base_image ${IMAGE1}
401442

402443
test_import_native_format ${IMAGE1} ${IMAGE2}
403444
test_import_qcow_format ${IMAGE1} ${IMAGE2}
445+
404446
test_import_qcow2_format ${IMAGE2} ${IMAGE3}
447+
test_import_nbd_stream ${IMAGE2} ${IMAGE3}
448+
405449
test_import_raw_format ${IMAGE1} ${IMAGE2}
406450

407451
echo OK

src/include/config-h.in.cmake

+3
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,9 @@
393393
/* Define if libcryptsetup can be used (linux only) */
394394
#cmakedefine HAVE_LIBCRYPTSETUP
395395

396+
/* Define if libnbd can be used */
397+
#cmakedefine HAVE_LIBNBD
398+
396399
/* Shared library extension, such as .so, .dll or .dylib */
397400
#cmakedefine CMAKE_SHARED_LIBRARY_SUFFIX "@CMAKE_SHARED_LIBRARY_SUFFIX@"
398401

src/librbd/CMakeLists.txt

+9
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,11 @@ if(LINUX AND HAVE_LIBCRYPTSETUP)
219219
crypto/luks/Magic.cc)
220220
endif()
221221

222+
if(HAVE_LIBNBD)
223+
list(APPEND librbd_internal_srcs
224+
migration/NBDStream.cc)
225+
endif()
226+
222227
add_library(rbd_api STATIC librbd.cc)
223228
add_library(rbd_internal STATIC
224229
${librbd_internal_srcs}
@@ -240,6 +245,10 @@ if(LINUX AND HAVE_LIBCRYPTSETUP)
240245
target_include_directories(rbd_internal PRIVATE ${LIBCRYPTSETUP_INCLUDE_DIR})
241246
target_link_libraries(rbd_internal PRIVATE ${LIBCRYPTSETUP_LIBRARIES})
242247
endif()
248+
if(HAVE_LIBNBD)
249+
target_include_directories(rbd_internal PRIVATE ${LIBNBD_INCLUDE_DIR})
250+
target_link_libraries(rbd_internal PRIVATE ${LIBNBD_LIBRARIES})
251+
endif()
243252

244253
add_custom_target(librbd_plugins)
245254
set(librbd_plugins_dir ${CEPH_INSTALL_PKGLIBDIR}/librbd)

src/librbd/migration/FileStream.cc

+12
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,18 @@ void FileStream<I>::read(io::Extents&& byte_extents, bufferlist* data,
226226

227227
#endif // BOOST_ASIO_HAS_POSIX_STREAM_DESCRIPTOR
228228

229+
template <typename I>
230+
void FileStream<I>::list_sparse_extents(io::Extents&& byte_extents,
231+
io::SparseExtents* sparse_extents,
232+
Context* on_finish) {
233+
// TODO: list sparse extents based on SEEK_HOLE/SEEK_DATA
234+
for (auto [byte_offset, byte_length] : byte_extents) {
235+
sparse_extents->insert(byte_offset, byte_length,
236+
{io::SPARSE_EXTENT_STATE_DATA, byte_length});
237+
}
238+
on_finish->complete(0);
239+
}
240+
229241
} // namespace migration
230242
} // namespace librbd
231243

src/librbd/migration/FileStream.h

+4
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ class FileStream : public StreamInterface {
4444
void read(io::Extents&& byte_extents, bufferlist* data,
4545
Context* on_finish) override;
4646

47+
void list_sparse_extents(io::Extents&& byte_extents,
48+
io::SparseExtents* sparse_extents,
49+
Context* on_finish) override;
50+
4751
private:
4852
CephContext* m_cct;
4953
std::shared_ptr<AsioEngine> m_asio_engine;

src/librbd/migration/HttpStream.cc

+12
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@ void HttpStream<I>::read(io::Extents&& byte_extents, bufferlist* data,
7777
m_http_client->read(std::move(byte_extents), data, on_finish);
7878
}
7979

80+
template <typename I>
81+
void HttpStream<I>::list_sparse_extents(io::Extents&& byte_extents,
82+
io::SparseExtents* sparse_extents,
83+
Context* on_finish) {
84+
// no sparseness information -- list the full range as DATA
85+
for (auto [byte_offset, byte_length] : byte_extents) {
86+
sparse_extents->insert(byte_offset, byte_length,
87+
{io::SPARSE_EXTENT_STATE_DATA, byte_length});
88+
}
89+
on_finish->complete(0);
90+
}
91+
8092
} // namespace migration
8193
} // namespace librbd
8294

src/librbd/migration/HttpStream.h

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class HttpStream : public StreamInterface {
4545
void read(io::Extents&& byte_extents, bufferlist* data,
4646
Context* on_finish) override;
4747

48+
void list_sparse_extents(io::Extents&& byte_extents,
49+
io::SparseExtents* sparse_extents,
50+
Context* on_finish) override;
51+
4852
private:
4953
using HttpResponse = boost::beast::http::response<
5054
boost::beast::http::string_body>;

0 commit comments

Comments
 (0)