master
c 200 lines 5.63 KB
Raw
1 /*
2 * Human Monitor Interface commands
3 *
4 * Copyright IBM, Corp. 2011
5 *
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
8 *
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
11 *
12 * Contributions after 2012-01-13 are licensed under the terms of the
13 * GNU GPL, version 2 or (at your option) any later version.
14 */
15
16 #include "qemu/osdep.h"
17 #include "migration/misc.h"
18 #include "monitor/hmp.h"
19 #include "monitor/hmp-completion.h"
20 #include "monitor/monitor.h"
21 #include "net/net.h"
22 #include "qapi/clone-visitor.h"
23 #include "qapi/qapi-commands-net.h"
24 #include "qapi/qapi-visit-net.h"
25 #include "qapi/error.h"
26 #include "qobject/qdict.h"
27 #include "qemu/config-file.h"
28 #include "qemu/help_option.h"
29 #include "qemu/option.h"
30
31 static void hmp_print_client_info(MonitorHMP *hmp, NetworkClientInfo *ci)
32 {
33 NetFilterInfoList *f;
34
35 monitor_hmp_printf(hmp, "%s: index=%" PRIu32 ",type=%s,%s\n",
36 ci->name, ci->queue_index,
37 NetClientDriver_str(ci->type), ci->info_str);
38 if (ci->filters) {
39 monitor_hmp_printf(hmp, "filters:\n");
40 for (f = ci->filters; f; f = f->next) {
41 monitor_hmp_printf(hmp, " - %s: type=%s%s%s\n",
42 f->value->name, f->value->type,
43 f->value->info[0] ? "," : "", f->value->info);
44 }
45 }
46 }
47
48 void hmp_info_network(MonitorHMP *hmp, const QDict *qdict)
49 {
50 Error *err = NULL;
51 g_autoptr(NetworkInfo) info = qmp_x_query_network(&err);
52 NetHubInfoList *h;
53 NetworkClientInfoList *entry;
54
55 if (hmp_handle_error(hmp, err)) {
56 return;
57 }
58
59 for (h = info->hubs; h; h = h->next) {
60 NetHubPortInfoList *p;
61
62 monitor_hmp_printf(hmp, "hub %d\n", (int)h->value->id);
63 for (p = h->value->ports; p; p = p->next) {
64 if (p->value->peer) {
65 monitor_hmp_printf(hmp, " \\ %s: ", p->value->name);
66 hmp_print_client_info(hmp, p->value->peer);
67 } else {
68 monitor_hmp_printf(hmp, " \\ %s\n", p->value->name);
69 }
70 }
71 }
72
73 for (entry = info->clients; entry; entry = entry->next) {
74 NetworkClientInfo *ci = entry->value;
75
76 if (!ci->peer || ci->type == NET_CLIENT_DRIVER_NIC) {
77 hmp_print_client_info(hmp, ci);
78 } /* else it's a netdev connected to a NIC, printed with the NIC */
79 if (ci->peer && ci->type == NET_CLIENT_DRIVER_NIC) {
80 monitor_hmp_printf(hmp, " \\ ");
81 hmp_print_client_info(hmp, ci->peer);
82 }
83 }
84 }
85
86 void hmp_set_link(MonitorHMP *hmp, const QDict *qdict)
87 {
88 const char *name = qdict_get_str(qdict, "name");
89 bool up = qdict_get_bool(qdict, "up");
90 Error *err = NULL;
91
92 qmp_set_link(name, up, &err);
93 hmp_handle_error(hmp, err);
94 }
95
96
97 void hmp_announce_self(MonitorHMP *hmp, const QDict *qdict)
98 {
99 const char *interfaces_str = qdict_get_try_str(qdict, "interfaces");
100 const char *id = qdict_get_try_str(qdict, "id");
101 AnnounceParameters *params = QAPI_CLONE(AnnounceParameters,
102 migrate_announce_params());
103
104 qapi_free_strList(params->interfaces);
105 params->interfaces = hmp_split_at_comma(interfaces_str);
106 params->has_interfaces = params->interfaces != NULL;
107 params->id = g_strdup(id);
108 qmp_announce_self(params, NULL);
109 qapi_free_AnnounceParameters(params);
110 }
111
112 void hmp_netdev_add(MonitorHMP *hmp, const QDict *qdict)
113 {
114 Error *err = NULL;
115 QemuOpts *opts;
116 const char *type = qdict_get_try_str(qdict, "type");
117
118 if (type && is_help_option(type)) {
119 show_netdevs();
120 return;
121 }
122 opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
123 if (err) {
124 goto out;
125 }
126
127 netdev_add(opts, &err);
128 if (err) {
129 qemu_opts_del(opts);
130 }
131
132 out:
133 hmp_handle_error(hmp, err);
134 }
135
136 void hmp_netdev_del(MonitorHMP *hmp, const QDict *qdict)
137 {
138 const char *id = qdict_get_str(qdict, "id");
139 Error *err = NULL;
140
141 qmp_netdev_del(id, &err);
142 hmp_handle_error(hmp, err);
143 }
144
145
146 void netdev_add_completion(ReadLineState *rs, int nb_args, const char *str)
147 {
148 size_t len;
149 int i;
150
151 if (nb_args != 2) {
152 return;
153 }
154 len = strlen(str);
155 readline_set_completion_index(rs, len);
156 for (i = 0; i < NET_CLIENT_DRIVER__MAX; i++) {
157 readline_add_completion_of(rs, str, NetClientDriver_str(i));
158 }
159 }
160
161 void set_link_completion(ReadLineState *rs, int nb_args, const char *str)
162 {
163 size_t len;
164
165 len = strlen(str);
166 readline_set_completion_index(rs, len);
167 if (nb_args == 2) {
168 NetClientState *ncs[MAX_QUEUE_NUM];
169 int count, i;
170 count = qemu_find_net_clients_except(NULL, ncs,
171 NET_CLIENT_DRIVER_NONE,
172 MAX_QUEUE_NUM);
173 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
174 readline_add_completion_of(rs, str, ncs[i]->name);
175 }
176 } else if (nb_args == 3) {
177 readline_add_completion_of(rs, str, "on");
178 readline_add_completion_of(rs, str, "off");
179 }
180 }
181
182 void netdev_del_completion(ReadLineState *rs, int nb_args, const char *str)
183 {
184 int len, count, i;
185 NetClientState *ncs[MAX_QUEUE_NUM];
186
187 if (nb_args != 2) {
188 return;
189 }
190
191 len = strlen(str);
192 readline_set_completion_index(rs, len);
193 count = qemu_find_net_clients_except(NULL, ncs, NET_CLIENT_DRIVER_NIC,
194 MAX_QUEUE_NUM);
195 for (i = 0; i < MIN(count, MAX_QUEUE_NUM); i++) {
196 if (ncs[i]->is_netdev) {
197 readline_add_completion_of(rs, str, ncs[i]->name);
198 }
199 }
200 }