Commit 05eb4a25 authored by Marc-André Lureau's avatar Marc-André Lureau Committed by Markus Armbruster
Browse files

qapi: add conditions to VNC type/commands/events on the schema



Add #if defined(CONFIG_VNC) in generated code, and adjust the
qmp/hmp code accordingly.

query-qmp-schema no longer reports the command/events etc as
available when disabled at compile.

Commands made conditional:

* query-vnc, query-vnc-servers, change-vnc-password

  Before the patch, the commands for !CONFIG_VNC are stubs that fail
  like this:

    {"error": {"class": "GenericError",
               "desc": "The feature 'vnc' is not enabled"}}

  Afterwards, they fail like this:

    {"error": {"class": "CommandNotFound",
               "desc": "The command FOO has not been found"}}

  I call that an improvement, because it lets clients distinguish
  between command unavailable (class CommandNotFound) and command failed
  (class GenericError).

Events made conditional:

* VNC_CONNECTED, VNC_INITIALIZED, VNC_DISCONNECTED

HMP change:

* info vnc

  Will return "unknown command: 'info vnc'" when VNC is compiled
  out (same as error for spice when --disable-spice)

Occurrences of VNC (case insensitive) in the schema that aren't
covered by this change:

* add_client

  Command has other uses, including "socket bases character devices".
  These are unconditional as far as I can tell.

* set_password, expire_password

  In theory, these commands could be used for managing any service's
  password.  In practice, they're used for VNC and SPICE services.
  They're documented for "remote display session" / "remote display
  server".

  The service is selected by argument @protocol.  The code special-cases
  protocol-specific argument checking, then calls a protocol-specific
  function to do the work.  If it fails, the command fails with "Could
  not set password".  It does when the service isn't compiled in (it's a
  stub then).

  We could make these commands conditional on the conjunction of all
  services [currently: defined(CONFIG_VNC) || defined(CONFIG_SPICE)],
  but I doubt it's worthwhile.

* change

  Command has other uses, namely changing media.
  This patch inlines a stub; no functional change.

Signed-off-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: default avatarGerd Hoffmann <kraxel@redhat.com>
Reviewed-by: default avatarMarkus Armbruster <armbru@redhat.com>
Message-Id: <20180703155648.11933-14-marcandre.lureau@redhat.com>
Signed-off-by: default avatarMarkus Armbruster <armbru@redhat.com>
parent 901a34a4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -426,6 +426,7 @@ STEXI
Show which guest mouse is receiving events.
ETEXI

#if defined(CONFIG_VNC)
    {
        .name       = "vnc",
        .args_type  = "",
@@ -433,6 +434,7 @@ ETEXI
        .help       = "show the vnc server status",
        .cmd        = hmp_info_vnc,
    },
#endif

STEXI
@item info vnc
+8 −1
Original line number Diff line number Diff line
@@ -616,6 +616,7 @@ void hmp_info_blockstats(Monitor *mon, const QDict *qdict)
    qapi_free_BlockStatsList(stats_list);
}

#ifdef CONFIG_VNC
/* Helper for hmp_info_vnc_clients, _servers */
static void hmp_info_VncBasicInfo(Monitor *mon, VncBasicInfo *info,
                                  const char *name)
@@ -703,6 +704,7 @@ void hmp_info_vnc(Monitor *mon, const QDict *qdict)
    qapi_free_VncInfo2List(info2l);

}
#endif

#ifdef CONFIG_SPICE
void hmp_info_spice(Monitor *mon, const QDict *qdict)
@@ -1772,12 +1774,14 @@ void hmp_eject(Monitor *mon, const QDict *qdict)
    hmp_handle_error(mon, &err);
}

#ifdef CONFIG_VNC
static void hmp_change_read_arg(void *opaque, const char *password,
                                void *readline_opaque)
{
    qmp_change_vnc_password(password, NULL);
    monitor_read_command(opaque, 1);
}
#endif

void hmp_change(Monitor *mon, const QDict *qdict)
{
@@ -1788,6 +1792,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
    BlockdevChangeReadOnlyMode read_only_mode = 0;
    Error *err = NULL;

#ifdef CONFIG_VNC
    if (strcmp(device, "vnc") == 0) {
        if (read_only) {
            monitor_printf(mon,
@@ -1802,7 +1807,9 @@ void hmp_change(Monitor *mon, const QDict *qdict)
            }
        }
        qmp_change("vnc", target, !!arg, arg, &err);
    } else {
    } else
#endif
    {
        if (read_only) {
            read_only_mode =
                qapi_enum_parse(&BlockdevChangeReadOnlyMode_lookup,
+28 −17
Original line number Diff line number Diff line
@@ -377,7 +377,8 @@
  'data': { 'host': 'str',
            'service': 'str',
            'family': 'NetworkAddressFamily',
            'websocket': 'bool' } }
            'websocket': 'bool' },
  'if': 'defined(CONFIG_VNC)' }

##
# @VncServerInfo:
@@ -391,7 +392,8 @@
##
{ 'struct': 'VncServerInfo',
  'base': 'VncBasicInfo',
  'data': { '*auth': 'str' } }
  'data': { '*auth': 'str' },
  'if': 'defined(CONFIG_VNC)' }

##
# @VncClientInfo:
@@ -408,7 +410,8 @@
##
{ 'struct': 'VncClientInfo',
  'base': 'VncBasicInfo',
  'data': { '*x509_dname': 'str', '*sasl_username': 'str' } }
  'data': { '*x509_dname': 'str', '*sasl_username': 'str' },
  'if': 'defined(CONFIG_VNC)' }

##
# @VncInfo:
@@ -449,7 +452,8 @@
{ 'struct': 'VncInfo',
  'data': {'enabled': 'bool', '*host': 'str',
           '*family': 'NetworkAddressFamily',
           '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']} }
           '*service': 'str', '*auth': 'str', '*clients': ['VncClientInfo']},
  'if': 'defined(CONFIG_VNC)' }

##
# @VncPrimaryAuth:
@@ -460,7 +464,8 @@
##
{ 'enum': 'VncPrimaryAuth',
  'data': [ 'none', 'vnc', 'ra2', 'ra2ne', 'tight', 'ultra',
            'tls', 'vencrypt', 'sasl' ] }
            'tls', 'vencrypt', 'sasl' ],
  'if': 'defined(CONFIG_VNC)' }

##
# @VncVencryptSubAuth:
@@ -474,8 +479,8 @@
            'tls-none',  'x509-none',
            'tls-vnc',   'x509-vnc',
            'tls-plain', 'x509-plain',
            'tls-sasl',  'x509-sasl' ] }

            'tls-sasl',  'x509-sasl' ],
  'if': 'defined(CONFIG_VNC)' }

##
# @VncServerInfo2:
@@ -492,8 +497,8 @@
{ 'struct': 'VncServerInfo2',
  'base': 'VncBasicInfo',
  'data': { 'auth'      : 'VncPrimaryAuth',
            '*vencrypt' : 'VncVencryptSubAuth' } }

            '*vencrypt' : 'VncVencryptSubAuth' },
  'if': 'defined(CONFIG_VNC)' }

##
# @VncInfo2:
@@ -525,7 +530,8 @@
            'clients'   : ['VncClientInfo'],
            'auth'      : 'VncPrimaryAuth',
            '*vencrypt' : 'VncVencryptSubAuth',
            '*display'  : 'str' } }
            '*display'  : 'str' },
  'if': 'defined(CONFIG_VNC)' }

##
# @query-vnc:
@@ -556,8 +562,8 @@
#    }
#
##
{ 'command': 'query-vnc', 'returns': 'VncInfo' }

{ 'command': 'query-vnc', 'returns': 'VncInfo',
  'if': 'defined(CONFIG_VNC)' }
##
# @query-vnc-servers:
#
@@ -567,7 +573,8 @@
#
# Since: 2.3
##
{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'] }
{ 'command': 'query-vnc-servers', 'returns': ['VncInfo2'],
  'if': 'defined(CONFIG_VNC)' }

##
# @change-vnc-password:
@@ -581,7 +588,8 @@
# Notes:  An empty password in this command will set the password to the empty
#         string.  Existing clients are unaffected by executing this command.
##
{ 'command': 'change-vnc-password', 'data': {'password': 'str'} }
{ 'command': 'change-vnc-password', 'data': {'password': 'str'},
  'if': 'defined(CONFIG_VNC)' }

##
# @VNC_CONNECTED:
@@ -610,7 +618,8 @@
##
{ 'event': 'VNC_CONNECTED',
  'data': { 'server': 'VncServerInfo',
            'client': 'VncBasicInfo' } }
            'client': 'VncBasicInfo' },
  'if': 'defined(CONFIG_VNC)' }

##
# @VNC_INITIALIZED:
@@ -637,7 +646,8 @@
##
{ 'event': 'VNC_INITIALIZED',
  'data': { 'server': 'VncServerInfo',
            'client': 'VncClientInfo' } }
            'client': 'VncClientInfo' },
  'if': 'defined(CONFIG_VNC)' }

##
# @VNC_DISCONNECTED:
@@ -663,7 +673,8 @@
##
{ 'event': 'VNC_DISCONNECTED',
  'data': { 'server': 'VncServerInfo',
            'client': 'VncClientInfo' } }
            'client': 'VncClientInfo' },
  'if': 'defined(CONFIG_VNC)' }

##
# = Input
+4 −26
Original line number Diff line number Diff line
@@ -129,22 +129,6 @@ void qmp_cpu_add(int64_t id, Error **errp)
    }
}

#ifndef CONFIG_VNC
/* If VNC support is enabled, the "true" query-vnc command is
   defined in the VNC subsystem */
VncInfo *qmp_query_vnc(Error **errp)
{
    error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
    return NULL;
};

VncInfo2List *qmp_query_vnc_servers(Error **errp)
{
    error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
    return NULL;
};
#endif

#ifndef CONFIG_SPICE
/*
 * qmp_unregister_commands_hack() ensures that QMP command query-spice
@@ -412,23 +396,17 @@ static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
        qmp_change_vnc_listen(target, errp);
    }
}
#else
void qmp_change_vnc_password(const char *password, Error **errp)
{
    error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
}
static void qmp_change_vnc(const char *target, bool has_arg, const char *arg,
                           Error **errp)
{
    error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
}
#endif /* !CONFIG_VNC */

void qmp_change(const char *device, const char *target,
                bool has_arg, const char *arg, Error **errp)
{
    if (strcmp(device, "vnc") == 0) {
#ifdef CONFIG_VNC
        qmp_change_vnc(target, has_arg, arg, errp);
#else
        error_setg(errp, QERR_FEATURE_DISABLED, "vnc");
#endif
    } else {
        qmp_blockdev_change_medium(true, device, false, NULL, target,
                                   has_arg, arg, false, 0, errp);
+2 −0
Original line number Diff line number Diff line
@@ -297,7 +297,9 @@ struct VncState
    bool encode_ws;
    bool websocket;

#ifdef CONFIG_VNC
    VncClientInfo *info;
#endif

    /* Job thread bottom half has put data for a forced update
     * into the output buffer. This offset points to the end of