qapi: convert add_client

Also fixes a few issues while there:

 1. The fd returned by monitor_get_fd() leaks in most error conditions
 2. monitor_get_fd() return value is not checked. Best case we get
    an error that is not correctly reported, worse case one of the
    functions using the fd (with value of -1) will explode
 3. A few error conditions aren't reported
 4. We now "use up" @fdname always.  Before, it was left alone for
    invalid @protocol

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
This commit is contained in:
Luiz Capitulino 2012-09-13 16:52:20 -03:00
parent a9940fc4cb
commit b224e5e216
4 changed files with 69 additions and 43 deletions

View File

@ -944,45 +944,6 @@ static void do_trace_print_events(Monitor *mon)
trace_print_events((FILE *)mon, &monitor_fprintf);
}
static int add_graphics_client(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
const char *protocol = qdict_get_str(qdict, "protocol");
const char *fdname = qdict_get_str(qdict, "fdname");
CharDriverState *s;
if (strcmp(protocol, "spice") == 0) {
int fd = monitor_get_fd(mon, fdname, NULL);
int skipauth = qdict_get_try_bool(qdict, "skipauth", 0);
int tls = qdict_get_try_bool(qdict, "tls", 0);
if (!using_spice) {
/* correct one? spice isn't a device ,,, */
qerror_report(QERR_DEVICE_NOT_ACTIVE, "spice");
return -1;
}
if (qemu_spice_display_add_client(fd, skipauth, tls) < 0) {
close(fd);
}
return 0;
#ifdef CONFIG_VNC
} else if (strcmp(protocol, "vnc") == 0) {
int fd = monitor_get_fd(mon, fdname, NULL);
int skipauth = qdict_get_try_bool(qdict, "skipauth", 0);
vnc_display_add_client(NULL, fd, skipauth);
return 0;
#endif
} else if ((s = qemu_chr_find(protocol)) != NULL) {
int fd = monitor_get_fd(mon, fdname, NULL);
if (qemu_chr_add_client(s, fd) < 0) {
qerror_report(QERR_ADD_CLIENT_FAILED);
return -1;
}
return 0;
}
qerror_report(QERR_INVALID_PARAMETER, "protocol");
return -1;
}
static int client_migrate_info(Monitor *mon, const QDict *qdict,
MonitorCompletion cb, void *opaque)
{

View File

@ -32,6 +32,31 @@
'DeviceNotActive', 'DeviceNotFound', 'KVMMissingCap',
'MigrationExpected' ] }
##
# @add_client
#
# Allow client connections for VNC, Spice and socket based
# character devices to be passed in to QEMU via SCM_RIGHTS.
#
# @protocol: protocol name. Valid names are "vnc", "spice" or the
# name of a character device (eg. from -chardev id=XXXX)
#
# @fdname: file descriptor name previously passed via 'getfd' command
#
# @skipauth: #optional whether to skip authentication. Only applies
# to "vnc" and "spice" protocols
#
# @tls: #optional whether to perform TLS. Only applies to the "spice"
# protocol
#
# Returns: nothing on success.
#
# Since: 0.14.0
##
{ 'command': 'add_client',
'data': { 'protocol': 'str', 'fdname': 'str', '*skipauth': 'bool',
'*tls': 'bool' } }
##
# @NameInfo:
#

View File

@ -1231,10 +1231,7 @@ EQMP
{
.name = "add_client",
.args_type = "protocol:s,fdname:s,skipauth:b?,tls:b?",
.params = "protocol fdname skipauth tls",
.help = "add a graphics client",
.user_print = monitor_user_noop,
.mhandler.cmd_new = add_graphics_client,
.mhandler.cmd_new = qmp_marshal_input_add_client,
},
SQMP

43
qmp.c
View File

@ -479,3 +479,46 @@ CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
return arch_query_cpu_definitions(errp);
}
void qmp_add_client(const char *protocol, const char *fdname,
bool has_skipauth, bool skipauth, bool has_tls, bool tls,
Error **errp)
{
CharDriverState *s;
int fd;
fd = monitor_get_fd(cur_mon, fdname, errp);
if (fd < 0) {
return;
}
if (strcmp(protocol, "spice") == 0) {
if (!using_spice) {
error_set(errp, QERR_DEVICE_NOT_ACTIVE, "spice");
close(fd);
return;
}
skipauth = has_skipauth ? skipauth : false;
tls = has_tls ? tls : false;
if (qemu_spice_display_add_client(fd, skipauth, tls) < 0) {
error_setg(errp, "spice failed to add client");
close(fd);
}
return;
#ifdef CONFIG_VNC
} else if (strcmp(protocol, "vnc") == 0) {
skipauth = has_skipauth ? skipauth : false;
vnc_display_add_client(NULL, fd, skipauth);
return;
#endif
} else if ((s = qemu_chr_find(protocol)) != NULL) {
if (qemu_chr_add_client(s, fd) < 0) {
error_setg(errp, "failed to add client");
close(fd);
return;
}
return;
}
error_setg(errp, "protocol '%s' is invalid", protocol);
close(fd);
}