Merge pull request #60109 from idryomov/wip-63184

librbd/crypto/LoadRequest: clone format for migration source image

Reviewed-by: Sunil Angadi <Sunil.Angadi@ibm.com>
Reviewed-by: Ramana Raja <rraja@redhat.com>
This commit is contained in:
Ilya Dryomov 2024-10-07 20:15:54 +02:00 committed by GitHub
commit 7e5ebb7934
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 102 additions and 11 deletions

View File

@ -2,7 +2,7 @@
set -ex
CEPH_ID=${CEPH_ID:-admin}
TMP_FILES="/tmp/passphrase /tmp/passphrase2 /tmp/testdata1 /tmp/testdata2 /tmp/cmpdata /tmp/rawexport /tmp/export.qcow2"
TMP_FILES="/tmp/passphrase /tmp/passphrase1 /tmp/passphrase2 /tmp/testdata1 /tmp/testdata2 /tmp/cmpdata /tmp/rawexport /tmp/export.qcow2"
_sudo()
{
@ -278,8 +278,7 @@ function test_migration_clone() {
rbd migration prepare testimg1 testimg2
# test reading
# FIXME: https://tracker.ceph.com/issues/63184
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)
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase)
cmp $LIBRBD_DEV /tmp/cmpdata
# trigger copyup for an unwritten area
@ -297,8 +296,7 @@ function test_migration_clone() {
_sudo rbd device unmap -t nbd $LIBRBD_DEV
# test reading on a fresh mapping
# FIXME: https://tracker.ceph.com/issues/63184
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)
LIBRBD_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd -o encryption-passphrase-file=/tmp/passphrase2,encryption-passphrase-file=/tmp/passphrase)
cmp $LIBRBD_DEV /tmp/cmpdata
_sudo rbd device unmap -t nbd $LIBRBD_DEV
@ -320,6 +318,85 @@ function test_migration_clone() {
rbd rm testimg
}
function test_migration_open_clone_chain() {
rbd create --size 32M testimg
rbd encryption format testimg luks1 /tmp/passphrase
rbd snap create testimg@snap
rbd snap protect testimg@snap
rbd clone testimg@snap testimg1
rbd encryption format testimg1 luks2 /tmp/passphrase1
rbd snap create testimg1@snap
rbd snap protect testimg1@snap
rbd clone testimg1@snap testimg2
rbd encryption format testimg2 luks1 /tmp/passphrase2
# 1. X <-- X <-- X
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)
_sudo rbd device unmap -t nbd $LIBRBD_DEV
# 2. X <-- X <-- migrating
rbd migration prepare testimg2 testimg2
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)
_sudo rbd device unmap -t nbd $LIBRBD_DEV
rbd migration abort testimg2
# 3. X <-- migrating <-- X
rbd migration prepare testimg1 testimg1
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)
_sudo rbd device unmap -t nbd $LIBRBD_DEV
rbd migration abort testimg1
# 4. migrating <-- X <-- X
rbd migration prepare testimg testimg
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)
_sudo rbd device unmap -t nbd $LIBRBD_DEV
rbd migration abort testimg
# 5. migrating <-- migrating <-- X
rbd migration prepare testimg testimg
rbd migration prepare testimg1 testimg1
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)
_sudo rbd device unmap -t nbd $LIBRBD_DEV
rbd migration abort testimg1
rbd migration abort testimg
# 6. migrating <-- X <-- migrating
rbd migration prepare testimg testimg
rbd migration prepare testimg2 testimg2
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)
_sudo rbd device unmap -t nbd $LIBRBD_DEV
rbd migration abort testimg2
rbd migration abort testimg
# 7. X <-- migrating <-- migrating
rbd migration prepare testimg1 testimg1
rbd migration prepare testimg2 testimg2
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)
_sudo rbd device unmap -t nbd $LIBRBD_DEV
rbd migration abort testimg2
rbd migration abort testimg1
# 8. migrating <-- migrating <-- migrating
rbd migration prepare testimg testimg
rbd migration prepare testimg1 testimg1
rbd migration prepare testimg2 testimg2
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)
_sudo rbd device unmap -t nbd $LIBRBD_DEV
rbd migration abort testimg2
rbd rm testimg2
rbd migration abort testimg1
rbd snap unprotect testimg1@snap
rbd snap rm testimg1@snap
rbd rm testimg1
rbd migration abort testimg
rbd snap unprotect testimg@snap
rbd snap rm testimg@snap
rbd rm testimg
}
function get_nbd_device_paths {
rbd device list -t nbd | tail -n +2 | egrep "\s+rbd\s+testimg" | awk '{print $5;}'
}
@ -343,6 +420,7 @@ function clean_up {
rbd snap unprotect testimg1@snap || true
rbd snap remove testimg1@snap || true
rbd remove testimg1 || true
rbd migration abort testimg || true
rbd snap remove testimg@snap2 || true
rbd snap remove testimg@snap1 || true
rbd snap unprotect testimg@snap || true
@ -371,6 +449,7 @@ dd if=/dev/urandom of=/tmp/testdata2 bs=4M count=4
# create passphrase files
printf "pass\0word\n" > /tmp/passphrase
printf " passwo\nrd 1,1" > /tmp/passphrase1
printf "\t password2 " > /tmp/passphrase2
# create an image
@ -401,4 +480,6 @@ test_migration_clone luks1
rbd create --size 48M testimg
test_migration_clone luks2
test_migration_open_clone_chain
echo OK

View File

@ -31,7 +31,7 @@ LoadRequest<I>::LoadRequest(
Context* on_finish) : m_image_ctx(image_ctx),
m_on_finish(on_finish),
m_format_idx(0),
m_is_current_format_cloned(false),
m_is_current_format_assumed(false),
m_formats(std::move(formats)) {
}
@ -108,7 +108,7 @@ void LoadRequest<I>::handle_load(int r) {
ldout(m_image_ctx->cct, 20) << "r=" << r << dendl;
if (r < 0) {
if (m_is_current_format_cloned &&
if (m_is_current_format_assumed &&
m_detected_format_name == UNKNOWN_FORMAT) {
// encryption format was not detected, assume plaintext
ldout(m_image_ctx->cct, 5) << "assuming plaintext for image "
@ -125,19 +125,29 @@ void LoadRequest<I>::handle_load(int r) {
}
ldout(m_image_ctx->cct, 5) << "loaded format " << m_detected_format_name
<< (m_is_current_format_cloned ? " (cloned)" : "")
<< (m_is_current_format_assumed ? " (assumed)" : "")
<< " for image " << m_current_image_ctx->name
<< dendl;
m_format_idx++;
if (!m_current_image_ctx->migration_info.empty()) {
// prepend the format to use for the migration source image
// it's done implicitly here because this image is moved to the
// trash when migration is prepared
ceph_assert(m_current_image_ctx->parent != nullptr);
ldout(m_image_ctx->cct, 20) << "under migration, cloning format" << dendl;
m_formats.insert(m_formats.begin() + m_format_idx,
m_formats[m_format_idx - 1]->clone());
}
m_current_image_ctx = m_current_image_ctx->parent;
if (m_current_image_ctx != nullptr) {
// move on to loading parent
if (m_format_idx >= m_formats.size()) {
// try to load next ancestor using the same format
ldout(m_image_ctx->cct, 20) << "cloning format" << dendl;
m_is_current_format_cloned = true;
ldout(m_image_ctx->cct, 20) << "out of formats, cloning format" << dendl;
m_formats.push_back(m_formats[m_formats.size() - 1]->clone());
m_is_current_format_assumed = true;
}
load();

View File

@ -44,7 +44,7 @@ private:
Context* m_on_finish;
size_t m_format_idx;
bool m_is_current_format_cloned;
bool m_is_current_format_assumed;
std::vector<EncryptionFormat> m_formats;
I* m_current_image_ctx;
std::string m_detected_format_name;