qapi: Convert query-spice
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
This commit is contained in:
		
							parent
							
								
									2b54aa879e
								
							
						
					
					
						commit
						d1f29646f2
					
				
							
								
								
									
										43
									
								
								hmp.c
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								hmp.c
									
									
									
									
									
								
							| @ -306,6 +306,49 @@ out: | ||||
|     qapi_free_VncInfo(info); | ||||
| } | ||||
| 
 | ||||
| void hmp_info_spice(Monitor *mon) | ||||
| { | ||||
|     SpiceChannelList *chan; | ||||
|     SpiceInfo *info; | ||||
| 
 | ||||
|     info = qmp_query_spice(NULL); | ||||
| 
 | ||||
|     if (!info->enabled) { | ||||
|         monitor_printf(mon, "Server: disabled\n"); | ||||
|         goto out; | ||||
|     } | ||||
| 
 | ||||
|     monitor_printf(mon, "Server:\n"); | ||||
|     if (info->has_port) { | ||||
|         monitor_printf(mon, "     address: %s:%" PRId64 "\n", | ||||
|                        info->host, info->port); | ||||
|     } | ||||
|     if (info->has_tls_port) { | ||||
|         monitor_printf(mon, "     address: %s:%" PRId64 " [tls]\n", | ||||
|                        info->host, info->tls_port); | ||||
|     } | ||||
|     monitor_printf(mon, "        auth: %s\n", info->auth); | ||||
|     monitor_printf(mon, "    compiled: %s\n", info->compiled_version); | ||||
| 
 | ||||
|     if (!info->has_channels || info->channels == NULL) { | ||||
|         monitor_printf(mon, "Channels: none\n"); | ||||
|     } else { | ||||
|         for (chan = info->channels; chan; chan = chan->next) { | ||||
|             monitor_printf(mon, "Channel:\n"); | ||||
|             monitor_printf(mon, "     address: %s:%s%s\n", | ||||
|                            chan->value->host, chan->value->port, | ||||
|                            chan->value->tls ? " [tls]" : ""); | ||||
|             monitor_printf(mon, "     session: %" PRId64 "\n", | ||||
|                            chan->value->connection_id); | ||||
|             monitor_printf(mon, "     channel: %" PRId64 ":%" PRId64 "\n", | ||||
|                            chan->value->channel_type, chan->value->channel_id); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| out: | ||||
|     qapi_free_SpiceInfo(info); | ||||
| } | ||||
| 
 | ||||
| void hmp_quit(Monitor *mon, const QDict *qdict) | ||||
| { | ||||
|     monitor_suspend(mon); | ||||
|  | ||||
							
								
								
									
										1
									
								
								hmp.h
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								hmp.h
									
									
									
									
									
								
							| @ -29,6 +29,7 @@ void hmp_info_cpus(Monitor *mon); | ||||
| void hmp_info_block(Monitor *mon); | ||||
| void hmp_info_blockstats(Monitor *mon); | ||||
| void hmp_info_vnc(Monitor *mon); | ||||
| void hmp_info_spice(Monitor *mon); | ||||
| void hmp_quit(Monitor *mon, const QDict *qdict); | ||||
| void hmp_stop(Monitor *mon, const QDict *qdict); | ||||
| void hmp_system_reset(Monitor *mon, const QDict *qdict); | ||||
|  | ||||
							
								
								
									
										13
									
								
								monitor.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								monitor.c
									
									
									
									
									
								
							| @ -2857,8 +2857,7 @@ static const mon_cmd_t info_cmds[] = { | ||||
|         .args_type  = "", | ||||
|         .params     = "", | ||||
|         .help       = "show the spice server status", | ||||
|         .user_print = do_info_spice_print, | ||||
|         .mhandler.info_new = do_info_spice, | ||||
|         .mhandler.info = hmp_info_spice, | ||||
|     }, | ||||
| #endif | ||||
|     { | ||||
| @ -2965,16 +2964,6 @@ static const mon_cmd_t qmp_query_cmds[] = { | ||||
|         .user_print = do_pci_info_print, | ||||
|         .mhandler.info_new = do_pci_info, | ||||
|     }, | ||||
| #if defined(CONFIG_SPICE) | ||||
|     { | ||||
|         .name       = "spice", | ||||
|         .args_type  = "", | ||||
|         .params     = "", | ||||
|         .help       = "show the spice server status", | ||||
|         .user_print = do_info_spice_print, | ||||
|         .mhandler.info_new = do_info_spice, | ||||
|     }, | ||||
| #endif | ||||
|     { | ||||
|         .name       = "balloon", | ||||
|         .args_type  = "", | ||||
|  | ||||
| @ -584,6 +584,80 @@ | ||||
| ## | ||||
| { 'command': 'query-vnc', 'returns': 'VncInfo' } | ||||
| 
 | ||||
| ## | ||||
| # @SpiceChannel | ||||
| # | ||||
| # Information about a SPICE client channel. | ||||
| # | ||||
| # @host: The host name of the client.  QEMU tries to resolve this to a DNS name | ||||
| #        when possible. | ||||
| # | ||||
| # @family: 'ipv6' if the client is connected via IPv6 and TCP | ||||
| #          'ipv4' if the client is connected via IPv4 and TCP | ||||
| #          'unix' if the client is connected via a unix domain socket | ||||
| #          'unknown' otherwise | ||||
| # | ||||
| # @port: The client's port number. | ||||
| # | ||||
| # @connection-id: SPICE connection id number.  All channels with the same id | ||||
| #                 belong to the same SPICE session. | ||||
| # | ||||
| # @connection-type: SPICE channel type number.  "1" is the main control channel, | ||||
| #                   filter for this one if you want track spice sessions only | ||||
| # | ||||
| # @channel-id: SPICE channel ID number.  Usually "0", might be different needed | ||||
| #              when multiple channels of the same type exist, such as multiple | ||||
| #              display channels in a multihead setup | ||||
| # | ||||
| # @tls: true if the channel is encrypted, false otherwise. | ||||
| # | ||||
| # Since: 0.14.0 | ||||
| ## | ||||
| { 'type': 'SpiceChannel', | ||||
|   'data': {'host': 'str', 'family': 'str', 'port': 'str', | ||||
|            'connection-id': 'int', 'channel-type': 'int', 'channel-id': 'int', | ||||
|            'tls': 'bool'} } | ||||
| 
 | ||||
| ## | ||||
| # @SpiceInfo | ||||
| # | ||||
| # Information about the SPICE session. | ||||
| #  | ||||
| # @enabled: true if the SPICE server is enabled, false otherwise | ||||
| # | ||||
| # @host: #optional The hostname the SPICE server is bound to.  This depends on | ||||
| #        the name resolution on the host and may be an IP address. | ||||
| # | ||||
| # @port: #optional The SPICE server's port number. | ||||
| # | ||||
| # @compiled-version: #optional SPICE server version. | ||||
| # | ||||
| # @tls-port: #optional The SPICE server's TLS port number. | ||||
| # | ||||
| # @auth: #optional the current authentication type used by the server | ||||
| #        'none' if no authentication is being used | ||||
| #        'spice' (TODO: describe) | ||||
| # | ||||
| # @channels: a list of @SpiceChannel for each active spice channel | ||||
| # | ||||
| # Since: 0.14.0 | ||||
| ## | ||||
| { 'type': 'SpiceInfo', | ||||
|   'data': {'enabled': 'bool', '*host': 'str', '*port': 'int', | ||||
|            '*tls-port': 'int', '*auth': 'str', '*compiled-version': 'str', | ||||
|            '*channels': ['SpiceChannel']} } | ||||
| 
 | ||||
| ## | ||||
| # @query-spice | ||||
| # | ||||
| # Returns information about the current SPICE server | ||||
| # | ||||
| # Returns: @SpiceInfo | ||||
| # | ||||
| # Since: 0.14.0 | ||||
| ## | ||||
| { 'command': 'query-spice', 'returns': 'SpiceInfo' } | ||||
| 
 | ||||
| ## | ||||
| # @quit: | ||||
| # | ||||
|  | ||||
| @ -1817,6 +1817,14 @@ Example: | ||||
| 
 | ||||
| EQMP | ||||
| 
 | ||||
| #if defined(CONFIG_SPICE) | ||||
|     { | ||||
|         .name       = "query-spice", | ||||
|         .args_type  = "", | ||||
|         .mhandler.cmd_new = qmp_marshal_input_query_spice, | ||||
|     }, | ||||
| #endif | ||||
| 
 | ||||
| SQMP | ||||
| query-name | ||||
| ---------- | ||||
|  | ||||
							
								
								
									
										12
									
								
								qmp.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								qmp.c
									
									
									
									
									
								
							| @ -105,3 +105,15 @@ VncInfo *qmp_query_vnc(Error **errp) | ||||
|     return NULL; | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_SPICE | ||||
| /* If SPICE support is enabled, the "true" query-spice command is
 | ||||
|    defined in the SPICE subsystem. Also note that we use a small | ||||
|    trick to maintain query-spice's original behavior, which is not | ||||
|    to be available in the namespace if SPICE is not compiled in */ | ||||
| SpiceInfo *qmp_query_spice(Error **errp) | ||||
| { | ||||
|     error_set(errp, QERR_COMMAND_NOT_FOUND, "query-spice"); | ||||
|     return NULL; | ||||
| }; | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										143
									
								
								ui/spice-core.c
									
									
									
									
									
								
							
							
						
						
									
										143
									
								
								ui/spice-core.c
									
									
									
									
									
								
							| @ -27,6 +27,7 @@ | ||||
| #include "qemu-queue.h" | ||||
| #include "qemu-x509.h" | ||||
| #include "qemu_socket.h" | ||||
| #include "qmp-commands.h" | ||||
| #include "qint.h" | ||||
| #include "qbool.h" | ||||
| #include "qstring.h" | ||||
| @ -194,22 +195,6 @@ static void add_channel_info(QDict *dict, SpiceChannelEventInfo *info) | ||||
|     qdict_put(dict, "tls", qbool_from_int(tls)); | ||||
| } | ||||
| 
 | ||||
| static QList *channel_list_get(void) | ||||
| { | ||||
|     ChannelList *item; | ||||
|     QList *list; | ||||
|     QDict *dict; | ||||
| 
 | ||||
|     list = qlist_new(); | ||||
|     QTAILQ_FOREACH(item, &channel_list, link) { | ||||
|         dict = qdict_new(); | ||||
|         add_addr_info(dict, &item->info->paddr, item->info->plen); | ||||
|         add_channel_info(dict, item->info); | ||||
|         qlist_append(list, dict); | ||||
|     } | ||||
|     return list; | ||||
| } | ||||
| 
 | ||||
| static void channel_event(int event, SpiceChannelEventInfo *info) | ||||
| { | ||||
|     static const int qevent[] = { | ||||
| @ -351,98 +336,90 @@ static const char *wan_compression_names[] = { | ||||
| 
 | ||||
| /* functions for the rest of qemu */ | ||||
| 
 | ||||
| static void info_spice_iter(QObject *obj, void *opaque) | ||||
| static SpiceChannelList *qmp_query_spice_channels(void) | ||||
| { | ||||
|     QDict *client; | ||||
|     Monitor *mon = opaque; | ||||
|     SpiceChannelList *cur_item = NULL, *head = NULL; | ||||
|     ChannelList *item; | ||||
| 
 | ||||
|     client = qobject_to_qdict(obj); | ||||
|     monitor_printf(mon, "Channel:\n"); | ||||
|     monitor_printf(mon, "     address: %s:%s%s\n", | ||||
|                    qdict_get_str(client, "host"), | ||||
|                    qdict_get_str(client, "port"), | ||||
|                    qdict_get_bool(client, "tls") ? " [tls]" : ""); | ||||
|     monitor_printf(mon, "     session: %" PRId64 "\n", | ||||
|                    qdict_get_int(client, "connection-id")); | ||||
|     monitor_printf(mon, "     channel: %d:%d\n", | ||||
|                    (int)qdict_get_int(client, "channel-type"), | ||||
|                    (int)qdict_get_int(client, "channel-id")); | ||||
|     QTAILQ_FOREACH(item, &channel_list, link) { | ||||
|         SpiceChannelList *chan; | ||||
|         char host[NI_MAXHOST], port[NI_MAXSERV]; | ||||
| 
 | ||||
|         chan = g_malloc0(sizeof(*chan)); | ||||
|         chan->value = g_malloc0(sizeof(*chan->value)); | ||||
| 
 | ||||
|         getnameinfo(&item->info->paddr, item->info->plen, | ||||
|                     host, sizeof(host), port, sizeof(port), | ||||
|                     NI_NUMERICHOST | NI_NUMERICSERV); | ||||
|         chan->value->host = g_strdup(host); | ||||
|         chan->value->port = g_strdup(port); | ||||
|         chan->value->family = g_strdup(inet_strfamily(item->info->paddr.sa_family)); | ||||
| 
 | ||||
|         chan->value->connection_id = item->info->connection_id; | ||||
|         chan->value->channel_type = item->info->type; | ||||
|         chan->value->channel_id = item->info->id; | ||||
|         chan->value->tls = item->info->flags & SPICE_CHANNEL_EVENT_FLAG_TLS; | ||||
| 
 | ||||
|        /* XXX: waiting for the qapi to support GSList */ | ||||
|         if (!cur_item) { | ||||
|             head = cur_item = chan; | ||||
|         } else { | ||||
|             cur_item->next = chan; | ||||
|             cur_item = chan; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return head; | ||||
| } | ||||
| 
 | ||||
| void do_info_spice_print(Monitor *mon, const QObject *data) | ||||
| { | ||||
|     QDict *server; | ||||
|     QList *channels; | ||||
|     const char *host; | ||||
|     int port; | ||||
| 
 | ||||
|     server = qobject_to_qdict(data); | ||||
|     if (qdict_get_bool(server, "enabled") == 0) { | ||||
|         monitor_printf(mon, "Server: disabled\n"); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     monitor_printf(mon, "Server:\n"); | ||||
|     host = qdict_get_str(server, "host"); | ||||
|     port = qdict_get_try_int(server, "port", -1); | ||||
|     if (port != -1) { | ||||
|         monitor_printf(mon, "     address: %s:%d\n", host, port); | ||||
|     } | ||||
|     port = qdict_get_try_int(server, "tls-port", -1); | ||||
|     if (port != -1) { | ||||
|         monitor_printf(mon, "     address: %s:%d [tls]\n", host, port); | ||||
|     } | ||||
|     monitor_printf(mon, "        auth: %s\n", qdict_get_str(server, "auth")); | ||||
|     monitor_printf(mon, "    compiled: %s\n", | ||||
|                    qdict_get_str(server, "compiled-version")); | ||||
| 
 | ||||
|     channels = qdict_get_qlist(server, "channels"); | ||||
|     if (qlist_empty(channels)) { | ||||
|         monitor_printf(mon, "Channels: none\n"); | ||||
|     } else { | ||||
|         qlist_iter(channels, info_spice_iter, mon); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void do_info_spice(Monitor *mon, QObject **ret_data) | ||||
| SpiceInfo *qmp_query_spice(Error **errp) | ||||
| { | ||||
|     QemuOpts *opts = QTAILQ_FIRST(&qemu_spice_opts.head); | ||||
|     QDict *server; | ||||
|     QList *clist; | ||||
|     const char *addr; | ||||
|     int port, tls_port; | ||||
|     const char *addr; | ||||
|     SpiceInfo *info; | ||||
|     char version_string[20]; /* 12 = |255.255.255\0| is the max */ | ||||
| 
 | ||||
|     info = g_malloc0(sizeof(*info)); | ||||
| 
 | ||||
|     if (!spice_server) { | ||||
|         *ret_data = qobject_from_jsonf("{ 'enabled': false }"); | ||||
|         return; | ||||
|         info->enabled = false; | ||||
|         return info; | ||||
|     } | ||||
| 
 | ||||
|     info->enabled = true; | ||||
| 
 | ||||
|     addr = qemu_opt_get(opts, "addr"); | ||||
|     port = qemu_opt_get_number(opts, "port", 0); | ||||
|     tls_port = qemu_opt_get_number(opts, "tls-port", 0); | ||||
|     clist = channel_list_get(); | ||||
| 
 | ||||
|     server = qdict_new(); | ||||
|     qdict_put(server, "enabled", qbool_from_int(true)); | ||||
|     qdict_put(server, "auth", qstring_from_str(auth)); | ||||
|     qdict_put(server, "host", qstring_from_str(addr ? addr : "0.0.0.0")); | ||||
|     info->has_auth = true; | ||||
|     info->auth = g_strdup(auth); | ||||
| 
 | ||||
|     info->has_host = true; | ||||
|     info->host = g_strdup(addr ? addr : "0.0.0.0"); | ||||
| 
 | ||||
|     info->has_compiled_version = true; | ||||
|     snprintf(version_string, sizeof(version_string), "%d.%d.%d", | ||||
|              (SPICE_SERVER_VERSION & 0xff0000) >> 16, | ||||
|              (SPICE_SERVER_VERSION & 0xff00) >> 8, | ||||
|              SPICE_SERVER_VERSION & 0xff); | ||||
|     qdict_put(server, "compiled-version", qstring_from_str(version_string)); | ||||
|     info->compiled_version = g_strdup(version_string); | ||||
| 
 | ||||
|     if (port) { | ||||
|         qdict_put(server, "port", qint_from_int(port)); | ||||
|         info->has_port = true; | ||||
|         info->port = port; | ||||
|     } | ||||
|     if (tls_port) { | ||||
|         qdict_put(server, "tls-port", qint_from_int(tls_port)); | ||||
|     } | ||||
|     if (clist) { | ||||
|         qdict_put(server, "channels", clist); | ||||
|         info->has_tls_port = true; | ||||
|         info->tls_port = tls_port; | ||||
|     } | ||||
| 
 | ||||
|     *ret_data = QOBJECT(server); | ||||
|     /* for compatibility with the original command */ | ||||
|     info->has_channels = true; | ||||
|     info->channels = qmp_query_spice_channels(); | ||||
| 
 | ||||
|     return info; | ||||
| } | ||||
| 
 | ||||
| static void migration_state_notifier(Notifier *notifier, void *data) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Luiz Capitulino
						Luiz Capitulino