]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librbd/crypto/LoadRequest: clone format for migration source image 60171/head
authorIlya Dryomov <idryomov@gmail.com>
Thu, 3 Oct 2024 15:54:07 +0000 (17:54 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Mon, 7 Oct 2024 18:25:43 +0000 (20:25 +0200)
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 <idryomov@gmail.com>
(cherry picked from commit 7b2085daad168d3d0e6357cd34979f91ecdc8486)

qa/workunits/rbd/luks-encryption.sh
src/librbd/crypto/LoadRequest.cc

index 97cb5a0fe87ef4b15f71ae9f9eec3a267ba0991f..b6305cb46c6c9049621cafddaa42221d02945469 100755 (executable)
@@ -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
index a751605e0d5ee2d684b20a535fa251c852ebc6e2..66beed59130fb1614b771cd6c831057f7b290376 100644 (file)
@@ -130,12 +130,22 @@ void LoadRequest<I>::handle_load(int r) {
                              << 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;
+      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;
     }