@@ -678,6 +678,33 @@ static int qemu_rbd_convert_options(QDict *options, BlockdevOptionsRbd **opts,
return 0;
}
+static int qemu_rbd_attempt_legacy_options(QDict *options,
+ BlockdevOptionsRbd **opts,
+ char **keypairs)
+{
+ char *filename;
+ int r;
+
+ filename = g_strdup(qdict_get_try_str(options, "filename"));
+ if (!filename) {
+ return -EINVAL;
+ }
+ qdict_del(options, "filename");
+
+ qemu_rbd_parse_filename(filename, options, NULL);
+
+ /* keypairs freed by caller */
+ *keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs"));
+ if (*keypairs) {
+ qdict_del(options, "=keyvalue-pairs");
+ }
+
+ r = qemu_rbd_convert_options(options, opts, NULL);
+
+ g_free(filename);
+ return r;
+}
+
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
@@ -700,8 +727,31 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
r = qemu_rbd_convert_options(options, &opts, &local_err);
if (local_err) {
- error_propagate(errp, local_err);
- goto out;
+ /* If keypairs are present, that means some options are present in
+ * the modern option format. Don't attempt to parse legacy option
+ * formats, as we won't support mixed usage. */
+ if (keypairs) {
+ error_propagate(errp, local_err);
+ goto out;
+ }
+
+ /* If the initial attempt to convert and process the options failed,
+ * we may be attempting to open an image file that has the rbd options
+ * specified in the older format consisting of all key/value pairs
+ * encoded in the filename. Go ahead and attempt to parse the
+ * filename, and see if we can pull out the required options. */
+ r = qemu_rbd_attempt_legacy_options(options, &opts, &keypairs);
+ if (r < 0) {
+ /* Propagate the original error, not the legacy parsing fallback
+ * error, as the latter was just a best-effort attempt. */
+ error_propagate(errp, local_err);
+ goto out;
+ }
+ /* Take care whenever deciding to actually deprecate; once this ability
+ * is removed, we will not be able to open any images with legacy-styled
+ * backing image strings. */
+ error_report("RBD options encoded in the filename as keyvalue pairs "
+ "is deprecated");
}
/* Remove the processed options from the QDict (the visitor processes