ae23c9
From 0433f2d3bd818b83908636ae240ecbfd256e0a9c Mon Sep 17 00:00:00 2001
ae23c9
From: John Snow <jsnow@redhat.com>
ae23c9
Date: Wed, 10 Oct 2018 20:30:13 +0100
ae23c9
Subject: [PATCH 2/4] block/rbd: Attempt to parse legacy filenames
ae23c9
ae23c9
RH-Author: John Snow <jsnow@redhat.com>
ae23c9
Message-id: <20181010203015.11719-3-jsnow@redhat.com>
ae23c9
Patchwork-id: 82629
ae23c9
O-Subject: [RHEL8/rhel qemu-kvm PATCH 2/4] block/rbd: Attempt to parse legacy filenames
ae23c9
Bugzilla: 1635585
ae23c9
RH-Acked-by: Markus Armbruster <armbru@redhat.com>
ae23c9
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
ae23c9
RH-Acked-by: Thomas Huth <thuth@redhat.com>
ae23c9
ae23c9
From: Jeff Cody <jcody@redhat.com>
ae23c9
ae23c9
When we converted rbd to get rid of the older key/value-centric
ae23c9
encoding format, we broke compatibility with image files with backing
ae23c9
file strings encoded in the old format.
ae23c9
ae23c9
This leaves a bit of an ugly conundrum, and a hacky solution.
ae23c9
ae23c9
If the initial attempt to parse the "proper" options fails, it assumes
ae23c9
that we may have an older key/value encoded filename.  Fall back to
ae23c9
attempting to parse the filename, and extract the required options from
ae23c9
it.  If that fails, pass along the original error message.
ae23c9
ae23c9
We do not support mixed modern usage alongside legacy keyvalue pair
ae23c9
usage.
ae23c9
ae23c9
A deprecation warning has been added, although care should be taken
ae23c9
when actually deprecating since the impact is not limited to
ae23c9
commandline or qapi usage, but also opening existing images.
ae23c9
ae23c9
Reviewed-by: Eric Blake <eblake@redhat.com>
ae23c9
Signed-off-by: Jeff Cody <jcody@redhat.com>
ae23c9
Message-id: 15b332e5432ad069441f7275a46080f465d789a0.1536704901.git.jcody@redhat.com
ae23c9
Signed-off-by: Jeff Cody <jcody@redhat.com>
ae23c9
(cherry picked from commit 084d1d13bdb753d558b991996e7686c077bd6d80)
ae23c9
Signed-off-by: John Snow <jsnow@redhat.com>
ae23c9
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ae23c9
---
ae23c9
 block/rbd.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
ae23c9
 1 file changed, 52 insertions(+), 2 deletions(-)
ae23c9
ae23c9
diff --git a/block/rbd.c b/block/rbd.c
ae23c9
index 1e4d339..ebe0701 100644
ae23c9
--- a/block/rbd.c
ae23c9
+++ b/block/rbd.c
ae23c9
@@ -671,6 +671,33 @@ static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts,
ae23c9
     return 0;
ae23c9
 }
ae23c9
 
ae23c9
+static int qemu_rbd_attempt_legacy_options(QDict *options,
ae23c9
+                                           BlockdevOptionsRbd **opts,
ae23c9
+                                           char **keypairs)
ae23c9
+{
ae23c9
+    char *filename;
ae23c9
+    int r;
ae23c9
+
ae23c9
+    filename = g_strdup(qdict_get_try_str(options, "filename"));
ae23c9
+    if (!filename) {
ae23c9
+        return -EINVAL;
ae23c9
+    }
ae23c9
+    qdict_del(options, "filename");
ae23c9
+
ae23c9
+    qemu_rbd_parse_filename(filename, options, NULL);
ae23c9
+
ae23c9
+    /* keypairs freed by caller */
ae23c9
+    *keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs"));
ae23c9
+    if (*keypairs) {
ae23c9
+        qdict_del(options, "=keyvalue-pairs");
ae23c9
+    }
ae23c9
+
ae23c9
+    r = qemu_rbd_convert_options(options, opts, NULL);
ae23c9
+
ae23c9
+    g_free(filename);
ae23c9
+    return r;
ae23c9
+}
ae23c9
+
ae23c9
 static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
ae23c9
                          Error **errp)
ae23c9
 {
ae23c9
@@ -693,8 +720,31 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
ae23c9
 
ae23c9
     r = qemu_rbd_convert_options(options, &opts, &local_err);
ae23c9
     if (local_err) {
ae23c9
-        error_propagate(errp, local_err);
ae23c9
-        goto out;
ae23c9
+        /* If keypairs are present, that means some options are present in
ae23c9
+         * the modern option format.  Don't attempt to parse legacy option
ae23c9
+         * formats, as we won't support mixed usage. */
ae23c9
+        if (keypairs) {
ae23c9
+            error_propagate(errp, local_err);
ae23c9
+            goto out;
ae23c9
+        }
ae23c9
+
ae23c9
+        /* If the initial attempt to convert and process the options failed,
ae23c9
+         * we may be attempting to open an image file that has the rbd options
ae23c9
+         * specified in the older format consisting of all key/value pairs
ae23c9
+         * encoded in the filename.  Go ahead and attempt to parse the
ae23c9
+         * filename, and see if we can pull out the required options. */
ae23c9
+        r = qemu_rbd_attempt_legacy_options(options, &opts, &keypairs);
ae23c9
+        if (r < 0) {
ae23c9
+            /* Propagate the original error, not the legacy parsing fallback
ae23c9
+             * error, as the latter was just a best-effort attempt. */
ae23c9
+            error_propagate(errp, local_err);
ae23c9
+            goto out;
ae23c9
+        }
ae23c9
+        /* Take care whenever deciding to actually deprecate; once this ability
ae23c9
+         * is removed, we will not be able to open any images with legacy-styled
ae23c9
+         * backing image strings. */
ae23c9
+        error_report("RBD options encoded in the filename as keyvalue pairs "
ae23c9
+                     "is deprecated");
ae23c9
     }
ae23c9
 
ae23c9
     /* Remove the processed options from the QDict (the visitor processes
ae23c9
-- 
ae23c9
1.8.3.1
ae23c9