Blame 0106-qmp-access-the-local-QemuOptsLists-for-drive-option.patch

4b5742
From dd733d7097c126ee3b8ee8a0f4c38b8ccac76504 Mon Sep 17 00:00:00 2001
4b5742
From: Amos Kong <akong@redhat.com>
4b5742
Date: Fri, 15 Nov 2013 18:53:14 +0100
4b5742
Subject: [PATCH] qmp: access the local QemuOptsLists for drive option
4b5742
4b5742
Currently we have three QemuOptsList (qemu_common_drive_opts,
4b5742
qemu_legacy_drive_opts, and qemu_drive_opts), only qemu_drive_opts
4b5742
is added to vm_config_groups[].
4b5742
4b5742
This patch changes query-command-line-options to access three local
4b5742
QemuOptsLists for drive option, and merge the description items
4b5742
together.
4b5742
4b5742
Signed-off-by: Amos Kong <akong@redhat.com>
4b5742
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
4b5742
---
4b5742
 blockdev.c                 |  1 -
4b5742
 include/qemu/config-file.h |  1 +
4b5742
 include/sysemu/sysemu.h    |  1 +
4b5742
 util/qemu-config.c         | 77 +++++++++++++++++++++++++++++++++++++++++++++-
4b5742
 vl.c                       |  2 ++
4b5742
 5 files changed, 80 insertions(+), 2 deletions(-)
4b5742
4b5742
diff --git a/blockdev.c b/blockdev.c
4b5742
index 097932c..1a6892e 100644
4b5742
--- a/blockdev.c
4b5742
+++ b/blockdev.c
4b5742
@@ -45,7 +45,6 @@
4b5742
 #include "sysemu/arch_init.h"
4b5742
 
4b5742
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives);
4b5742
-extern QemuOptsList qemu_common_drive_opts;
4b5742
 extern QemuOptsList qemu_old_drive_opts;
4b5742
 
4b5742
 static const char *const if_name[IF_COUNT] = {
4b5742
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
4b5742
index ad4a9e5..508428f 100644
4b5742
--- a/include/qemu/config-file.h
4b5742
+++ b/include/qemu/config-file.h
4b5742
@@ -8,6 +8,7 @@
4b5742
 QemuOptsList *qemu_find_opts(const char *group);
4b5742
 QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
4b5742
 void qemu_add_opts(QemuOptsList *list);
4b5742
+void qemu_add_drive_opts(QemuOptsList *list);
4b5742
 int qemu_set_option(const char *str);
4b5742
 int qemu_global_option(const char *str);
4b5742
 void qemu_add_globals(void);
4b5742
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
4b5742
index 1a77c99..4962cef 100644
4b5742
--- a/include/sysemu/sysemu.h
4b5742
+++ b/include/sysemu/sysemu.h
4b5742
@@ -190,6 +190,7 @@ QemuOpts *qemu_get_machine_opts(void);
4b5742
 
4b5742
 bool usb_enabled(bool default_usb);
4b5742
 
4b5742
+extern QemuOptsList qemu_common_drive_opts;
4b5742
 extern QemuOptsList qemu_drive_opts;
4b5742
 extern QemuOptsList qemu_chardev_opts;
4b5742
 extern QemuOptsList qemu_device_opts;
4b5742
diff --git a/util/qemu-config.c b/util/qemu-config.c
4b5742
index a59568d..04da942 100644
4b5742
--- a/util/qemu-config.c
4b5742
+++ b/util/qemu-config.c
4b5742
@@ -8,6 +8,7 @@
4b5742
 #include "qmp-commands.h"
4b5742
 
4b5742
 static QemuOptsList *vm_config_groups[32];
4b5742
+static QemuOptsList *drive_config_groups[4];
4b5742
 
4b5742
 static QemuOptsList *find_list(QemuOptsList **lists, const char *group,
4b5742
                                Error **errp)
4b5742
@@ -77,6 +78,59 @@ static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
4b5742
     return param_list;
4b5742
 }
4b5742
 
4b5742
+/* remove repeated entry from the info list */
4b5742
+static void cleanup_infolist(CommandLineParameterInfoList *head)
4b5742
+{
4b5742
+    CommandLineParameterInfoList *pre_entry, *cur, *del_entry;
4b5742
+
4b5742
+    cur = head;
4b5742
+    while (cur->next) {
4b5742
+        pre_entry = head;
4b5742
+        while (pre_entry != cur->next) {
4b5742
+            if (!strcmp(pre_entry->value->name, cur->next->value->name)) {
4b5742
+                del_entry = cur->next;
4b5742
+                cur->next = cur->next->next;
4b5742
+                g_free(del_entry);
4b5742
+                break;
4b5742
+            }
4b5742
+            pre_entry = pre_entry->next;
4b5742
+        }
4b5742
+        cur = cur->next;
4b5742
+    }
4b5742
+}
4b5742
+
4b5742
+/* merge the description items of two parameter infolists */
4b5742
+static void connect_infolist(CommandLineParameterInfoList *head,
4b5742
+                             CommandLineParameterInfoList *new)
4b5742
+{
4b5742
+    CommandLineParameterInfoList *cur;
4b5742
+
4b5742
+    cur = head;
4b5742
+    while (cur->next) {
4b5742
+        cur = cur->next;
4b5742
+    }
4b5742
+    cur->next = new;
4b5742
+}
4b5742
+
4b5742
+/* access all the local QemuOptsLists for drive option */
4b5742
+static CommandLineParameterInfoList *get_drive_infolist(void)
4b5742
+{
4b5742
+    CommandLineParameterInfoList *head = NULL, *cur;
4b5742
+    int i;
4b5742
+
4b5742
+    for (i = 0; drive_config_groups[i] != NULL; i++) {
4b5742
+        if (!head) {
4b5742
+            head = query_option_descs(drive_config_groups[i]->desc);
4b5742
+        } else {
4b5742
+            cur = query_option_descs(drive_config_groups[i]->desc);
4b5742
+            connect_infolist(head, cur);
4b5742
+        }
4b5742
+    }
4b5742
+    cleanup_infolist(head);
4b5742
+
4b5742
+    return head;
4b5742
+}
4b5742
+
4b5742
 CommandLineOptionInfoList *qmp_query_command_line_options(bool has_option,
4b5742
                                                           const char *option,
4b5742
                                                           Error **errp)
4b5742
@@ -89,7 +143,12 @@ CommandLineOptionInfoList *qmp_query_command_line_options(bool has_option,
4b5742
         if (!has_option || !strcmp(option, vm_config_groups[i]->name)) {
4b5742
             info = g_malloc0(sizeof(*info));
4b5742
             info->option = g_strdup(vm_config_groups[i]->name);
4b5742
-            info->parameters = query_option_descs(vm_config_groups[i]->desc);
4b5742
+            if (!strcmp("drive", vm_config_groups[i]->name)) {
4b5742
+                info->parameters = get_drive_infolist();
4b5742
+            } else {
4b5742
+                info->parameters =
4b5742
+                    query_option_descs(vm_config_groups[i]->desc);
4b5742
+            }
4b5742
             entry = g_malloc0(sizeof(*entry));
4b5742
             entry->value = info;
4b5742
             entry->next = conf_list;
4b5742
@@ -109,6 +168,22 @@ QemuOptsList *qemu_find_opts_err(const char *group, Error **errp)
4b5742
     return find_list(vm_config_groups, group, errp);
4b5742
 }
4b5742
 
4b5742
+void qemu_add_drive_opts(QemuOptsList *list)
4b5742
+{
4b5742
+    int entries, i;
4b5742
+
4b5742
+    entries = ARRAY_SIZE(drive_config_groups);
4b5742
+    entries--; /* keep list NULL terminated */
4b5742
+    for (i = 0; i < entries; i++) {
4b5742
+        if (drive_config_groups[i] == NULL) {
4b5742
+            drive_config_groups[i] = list;
4b5742
+            return;
4b5742
+        }
4b5742
+    }
4b5742
+    fprintf(stderr, "ran out of space in drive_config_groups");
4b5742
+    abort();
4b5742
+}
4b5742
+
4b5742
 void qemu_add_opts(QemuOptsList *list)
4b5742
 {
4b5742
     int entries, i;
4b5742
diff --git a/vl.c b/vl.c
4b5742
index 2160933..63ecf16 100644
4b5742
--- a/vl.c
4b5742
+++ b/vl.c
4b5742
@@ -2942,6 +2942,8 @@ int main(int argc, char **argv, char **envp)
4b5742
     module_call_init(MODULE_INIT_QOM);
4b5742
 
4b5742
     qemu_add_opts(&qemu_drive_opts);
4b5742
+    qemu_add_drive_opts(&qemu_common_drive_opts);
4b5742
+    qemu_add_drive_opts(&qemu_drive_opts);
4b5742
     qemu_add_opts(&qemu_chardev_opts);
4b5742
     qemu_add_opts(&qemu_device_opts);
4b5742
     qemu_add_opts(&qemu_netdev_opts);