Skip to content

Commit 7b2085d

Browse files
committed
librbd/crypto/LoadRequest: clone format for migration source image
Migration source and migration target images naturally have the same encryption format, but the user shouldn't have to need to specify it for the image that they can't even immediately see -- migration source image gets moved to the RBD trash to avoid mistaken usage while migration is in progress. Fixes: https://tracker.ceph.com/issues/63184 Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 6352952 commit 7b2085d

File tree

2 files changed

+97
-6
lines changed

2 files changed

+97
-6
lines changed

qa/workunits/rbd/luks-encryption.sh

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
set -ex
33

44
CEPH_ID=${CEPH_ID:-admin}
5-
TMP_FILES="/tmp/passphrase /tmp/passphrase2 /tmp/testdata1 /tmp/testdata2 /tmp/cmpdata /tmp/rawexport /tmp/export.qcow2"
5+
TMP_FILES="/tmp/passphrase /tmp/passphrase1 /tmp/passphrase2 /tmp/testdata1 /tmp/testdata2 /tmp/cmpdata /tmp/rawexport /tmp/export.qcow2"
66

77
_sudo()
88
{
@@ -278,8 +278,7 @@ function test_migration_clone() {
278278
rbd migration prepare testimg1 testimg2
279279

280280
# test reading
281-
# FIXME: https://tracker.ceph.com/issues/63184
282-
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase)
281+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase)
283282
cmp $LIBRBD_DEV /tmp/cmpdata
284283

285284
# trigger copyup for an unwritten area
@@ -297,8 +296,7 @@ function test_migration_clone() {
297296
_sudo rbd device unmap -t nbd $LIBRBD_DEV
298297

299298
# test reading on a fresh mapping
300-
# FIXME: https://tracker.ceph.com/issues/63184
301-
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase)
299+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase)
302300
cmp $LIBRBD_DEV /tmp/cmpdata
303301
_sudo rbd device unmap -t nbd $LIBRBD_DEV
304302

@@ -320,6 +318,85 @@ function test_migration_clone() {
320318
rbd rm testimg
321319
}
322320

321+
function test_migration_open_clone_chain() {
322+
rbd create --size 32M testimg
323+
rbd encryption format testimg luks1 /tmp/passphrase
324+
rbd snap create testimg@snap
325+
rbd snap protect testimg@snap
326+
327+
rbd clone testimg@snap testimg1
328+
rbd encryption format testimg1 luks2 /tmp/passphrase1
329+
rbd snap create testimg1@snap
330+
rbd snap protect testimg1@snap
331+
332+
rbd clone testimg1@snap testimg2
333+
rbd encryption format testimg2 luks1 /tmp/passphrase2
334+
335+
# 1. X <-- X <-- X
336+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase1,encryption-passphrase-file=/tmp/passphrase)
337+
_sudo rbd device unmap -t nbd $LIBRBD_DEV
338+
339+
# 2. X <-- X <-- migrating
340+
rbd migration prepare testimg2 testimg2
341+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase1,encryption-passphrase-file=/tmp/passphrase)
342+
_sudo rbd device unmap -t nbd $LIBRBD_DEV
343+
rbd migration abort testimg2
344+
345+
# 3. X <-- migrating <-- X
346+
rbd migration prepare testimg1 testimg1
347+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase1,encryption-passphrase-file=/tmp/passphrase)
348+
_sudo rbd device unmap -t nbd $LIBRBD_DEV
349+
rbd migration abort testimg1
350+
351+
# 4. migrating <-- X <-- X
352+
rbd migration prepare testimg testimg
353+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase1,encryption-passphrase-file=/tmp/passphrase)
354+
_sudo rbd device unmap -t nbd $LIBRBD_DEV
355+
rbd migration abort testimg
356+
357+
# 5. migrating <-- migrating <-- X
358+
rbd migration prepare testimg testimg
359+
rbd migration prepare testimg1 testimg1
360+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase1,encryption-passphrase-file=/tmp/passphrase)
361+
_sudo rbd device unmap -t nbd $LIBRBD_DEV
362+
rbd migration abort testimg1
363+
rbd migration abort testimg
364+
365+
# 6. migrating <-- X <-- migrating
366+
rbd migration prepare testimg testimg
367+
rbd migration prepare testimg2 testimg2
368+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase1,encryption-passphrase-file=/tmp/passphrase)
369+
_sudo rbd device unmap -t nbd $LIBRBD_DEV
370+
rbd migration abort testimg2
371+
rbd migration abort testimg
372+
373+
# 7. X <-- migrating <-- migrating
374+
rbd migration prepare testimg1 testimg1
375+
rbd migration prepare testimg2 testimg2
376+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase1,encryption-passphrase-file=/tmp/passphrase)
377+
_sudo rbd device unmap -t nbd $LIBRBD_DEV
378+
rbd migration abort testimg2
379+
rbd migration abort testimg1
380+
381+
# 8. migrating <-- migrating <-- migrating
382+
rbd migration prepare testimg testimg
383+
rbd migration prepare testimg1 testimg1
384+
rbd migration prepare testimg2 testimg2
385+
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase1,encryption-passphrase-file=/tmp/passphrase)
386+
_sudo rbd device unmap -t nbd $LIBRBD_DEV
387+
388+
rbd migration abort testimg2
389+
rbd rm testimg2
390+
rbd migration abort testimg1
391+
rbd snap unprotect testimg1@snap
392+
rbd snap rm testimg1@snap
393+
rbd rm testimg1
394+
rbd migration abort testimg
395+
rbd snap unprotect testimg@snap
396+
rbd snap rm testimg@snap
397+
rbd rm testimg
398+
}
399+
323400
function get_nbd_device_paths {
324401
rbd device list -t nbd | tail -n +2 | egrep "\s+rbd\s+testimg" | awk '{print $5;}'
325402
}
@@ -343,6 +420,7 @@ function clean_up {
343420
rbd snap unprotect testimg1@snap || true
344421
rbd snap remove testimg1@snap || true
345422
rbd remove testimg1 || true
423+
rbd migration abort testimg || true
346424
rbd snap remove testimg@snap2 || true
347425
rbd snap remove testimg@snap1 || true
348426
rbd snap unprotect testimg@snap || true
@@ -371,6 +449,7 @@ dd if=/dev/urandom of=/tmp/testdata2 bs=4M count=4
371449

372450
# create passphrase files
373451
printf "pass\0word\n" > /tmp/passphrase
452+
printf " passwo\nrd 1,1" > /tmp/passphrase1
374453
printf "\t password2 " > /tmp/passphrase2
375454

376455
# create an image
@@ -401,4 +480,6 @@ test_migration_clone luks1
401480
rbd create --size 48M testimg
402481
test_migration_clone luks2
403482

483+
test_migration_open_clone_chain
484+
404485
echo OK

src/librbd/crypto/LoadRequest.cc

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,22 @@ void LoadRequest<I>::handle_load(int r) {
130130
<< dendl;
131131

132132
m_format_idx++;
133+
if (!m_current_image_ctx->migration_info.empty()) {
134+
// prepend the format to use for the migration source image
135+
// it's done implicitly here because this image is moved to the
136+
// trash when migration is prepared
137+
ceph_assert(m_current_image_ctx->parent != nullptr);
138+
ldout(m_image_ctx->cct, 20) << "under migration, cloning format" << dendl;
139+
m_formats.insert(m_formats.begin() + m_format_idx,
140+
m_formats[m_format_idx - 1]->clone());
141+
}
142+
133143
m_current_image_ctx = m_current_image_ctx->parent;
134144
if (m_current_image_ctx != nullptr) {
135145
// move on to loading parent
136146
if (m_format_idx >= m_formats.size()) {
137147
// try to load next ancestor using the same format
138-
ldout(m_image_ctx->cct, 20) << "cloning format" << dendl;
148+
ldout(m_image_ctx->cct, 20) << "out of formats, cloning format" << dendl;
139149
m_formats.push_back(m_formats[m_formats.size() - 1]->clone());
140150
m_is_current_format_assumed = true;
141151
}

0 commit comments

Comments
 (0)