qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Anthony Liguori <aliguori@us.ibm.com>
To: Michael Roth <mdroth@linux.vnet.ibm.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 1/2] guest agent: add RPC blacklist command-line option
Date: Mon, 12 Dec 2011 17:34:43 -0600	[thread overview]
Message-ID: <4EE68F93.4060808@us.ibm.com> (raw)
In-Reply-To: <1323230623-8709-1-git-send-email-mdroth@linux.vnet.ibm.com>

On 12/06/2011 10:03 PM, Michael Roth wrote:
> This adds a command-line option, -b/--blacklist, that accepts a
> comma-seperated list of RPCs to disable, or prints a list of
> available RPCs if passed "?".
>
> In consequence this also adds general blacklisting and RPC listing
> facilities to the new QMP dispatch/registry facilities, should the
> QMP monitor ever have a need for such a thing.
>
> Ideally, to avoid support/compatability issues in the future,
> blacklisting guest agent functionality will be the exceptional
> case, but we add the functionality here to handle guest administrators
> with specific requirements.
>
> Signed-off-by: Michael Roth<mdroth@linux.vnet.ibm.com>

Applied.  Thanks.

Regards,

Anthony Liguori

> ---
>   qapi/qmp-core.h     |    3 +++
>   qapi/qmp-dispatch.c |    4 ++++
>   qapi/qmp-registry.c |   43 ++++++++++++++++++++++++++++++++++++++-----
>   qemu-ga.c           |   37 ++++++++++++++++++++++++++++++++++---
>   qerror.c            |    4 ++++
>   qerror.h            |    3 +++
>   6 files changed, 86 insertions(+), 8 deletions(-)
>
> diff --git a/qapi/qmp-core.h b/qapi/qmp-core.h
> index f1c26e4..3cf1781 100644
> --- a/qapi/qmp-core.h
> +++ b/qapi/qmp-core.h
> @@ -31,11 +31,14 @@ typedef struct QmpCommand
>       QmpCommandType type;
>       QmpCommandFunc *fn;
>       QTAILQ_ENTRY(QmpCommand) node;
> +    bool enabled;
>   } QmpCommand;
>
>   void qmp_register_command(const char *name, QmpCommandFunc *fn);
>   QmpCommand *qmp_find_command(const char *name);
>   QObject *qmp_dispatch(QObject *request);
> +void qmp_disable_command(const char *name);
> +char **qmp_get_command_list(void);
>
>   #endif
>
> diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
> index 5584693..43f640a 100644
> --- a/qapi/qmp-dispatch.c
> +++ b/qapi/qmp-dispatch.c
> @@ -79,6 +79,10 @@ static QObject *do_qmp_dispatch(QObject *request, Error **errp)
>           error_set(errp, QERR_COMMAND_NOT_FOUND, command);
>           return NULL;
>       }
> +    if (!cmd->enabled) {
> +        error_set(errp, QERR_COMMAND_DISABLED, command);
> +        return NULL;
> +    }
>
>       if (!qdict_haskey(dict, "arguments")) {
>           args = qdict_new();
> diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
> index 5ff99cf..abafa34 100644
> --- a/qapi/qmp-registry.c
> +++ b/qapi/qmp-registry.c
> @@ -14,7 +14,7 @@
>
>   #include "qapi/qmp-core.h"
>
> -static QTAILQ_HEAD(, QmpCommand) qmp_commands =
> +static QTAILQ_HEAD(QmpCommandList, QmpCommand) qmp_commands =
>       QTAILQ_HEAD_INITIALIZER(qmp_commands);
>
>   void qmp_register_command(const char *name, QmpCommandFunc *fn)
> @@ -24,17 +24,50 @@ void qmp_register_command(const char *name, QmpCommandFunc *fn)
>       cmd->name = name;
>       cmd->type = QCT_NORMAL;
>       cmd->fn = fn;
> +    cmd->enabled = true;
>       QTAILQ_INSERT_TAIL(&qmp_commands, cmd, node);
>   }
>
>   QmpCommand *qmp_find_command(const char *name)
>   {
> -    QmpCommand *i;
> +    QmpCommand *cmd;
>
> -    QTAILQ_FOREACH(i,&qmp_commands, node) {
> -        if (strcmp(i->name, name) == 0) {
> -            return i;
> +    QTAILQ_FOREACH(cmd,&qmp_commands, node) {
> +        if (strcmp(cmd->name, name) == 0) {
> +            return cmd;
>           }
>       }
>       return NULL;
>   }
> +
> +void qmp_disable_command(const char *name)
> +{
> +    QmpCommand *cmd;
> +
> +    QTAILQ_FOREACH(cmd,&qmp_commands, node) {
> +        if (strcmp(cmd->name, name) == 0) {
> +            cmd->enabled = false;
> +            return;
> +        }
> +    }
> +}
> +
> +char **qmp_get_command_list(void)
> +{
> +    QmpCommand *cmd;
> +    int count = 1;
> +    char **list_head, **list;
> +
> +    QTAILQ_FOREACH(cmd,&qmp_commands, node) {
> +        count++;
> +    }
> +
> +    list_head = list = g_malloc0(count * sizeof(char *));
> +
> +    QTAILQ_FOREACH(cmd,&qmp_commands, node) {
> +        *list = strdup(cmd->name);
> +        list++;
> +    }
> +
> +    return list_head;
> +}
> diff --git a/qemu-ga.c b/qemu-ga.c
> index 4932013..200bb15 100644
> --- a/qemu-ga.c
> +++ b/qemu-ga.c
> @@ -27,6 +27,7 @@
>   #include "signal.h"
>   #include "qerror.h"
>   #include "error_int.h"
> +#include "qapi/qmp-core.h"
>
>   #define QGA_VIRTIO_PATH_DEFAULT "/dev/virtio-ports/org.qemu.guest_agent.0"
>   #define QGA_PIDFILE_DEFAULT "/var/run/qemu-ga.pid"
> @@ -91,6 +92,8 @@ static void usage(const char *cmd)
>   "  -v, --verbose     log extra debugging information\n"
>   "  -V, --version     print version information and exit\n"
>   "  -d, --daemonize   become a daemon\n"
> +"  -b, --blacklist   comma-seperated list of RPCs to disable (no spaces, \"?\""
> +"                    to list available RPCs)\n"
>   "  -h, --help        display this help and exit\n"
>   "\n"
>   "Report bugs to<mdroth@linux.vnet.ibm.com>\n"
> @@ -548,7 +551,7 @@ static void init_guest_agent(GAState *s)
>
>   int main(int argc, char **argv)
>   {
> -    const char *sopt = "hVvdm:p:l:f:";
> +    const char *sopt = "hVvdm:p:l:f:b:";
>       const char *method = NULL, *path = NULL, *pidfile = QGA_PIDFILE_DEFAULT;
>       const struct option lopt[] = {
>           { "help", 0, NULL, 'h' },
> @@ -559,13 +562,16 @@ int main(int argc, char **argv)
>           { "method", 0, NULL, 'm' },
>           { "path", 0, NULL, 'p' },
>           { "daemonize", 0, NULL, 'd' },
> +        { "blacklist", 0, NULL, 'b' },
>           { NULL, 0, NULL, 0 }
>       };
> -    int opt_ind = 0, ch, daemonize = 0;
> +    int opt_ind = 0, ch, daemonize = 0, i, j, len;
>       GLogLevelFlags log_level = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL;
>       FILE *log_file = stderr;
>       GAState *s;
>
> +    module_call_init(MODULE_INIT_QAPI);
> +
>       while ((ch = getopt_long(argc, argv, sopt, lopt,&opt_ind)) != -1) {
>           switch (ch) {
>           case 'm':
> @@ -595,6 +601,32 @@ int main(int argc, char **argv)
>           case 'd':
>               daemonize = 1;
>               break;
> +        case 'b': {
> +            char **list_head, **list;
> +            if (*optarg == '?') {
> +                list_head = list = qmp_get_command_list();
> +                while (*list != NULL) {
> +                    printf("%s\n", *list);
> +                    g_free(*list);
> +                    list++;
> +                }
> +                g_free(list_head);
> +                return 0;
> +            }
> +            for (j = 0, i = 0, len = strlen(optarg); i<  len; i++) {
> +                if (optarg[i] == ',') {
> +                    optarg[i] = 0;
> +                    qmp_disable_command(&optarg[j]);
> +                    g_debug("disabling command: %s",&optarg[j]);
> +                    j = i + 1;
> +                }
> +            }
> +            if (j<  i) {
> +                qmp_disable_command(&optarg[j]);
> +                g_debug("disabling command: %s",&optarg[j]);
> +            }
> +            break;
> +        }
>           case 'h':
>               usage(argv[0]);
>               return 0;
> @@ -624,7 +656,6 @@ int main(int argc, char **argv)
>       ga_command_state_init_all(s->command_state);
>       ga_state = s;
>
> -    module_call_init(MODULE_INIT_QAPI);
>       init_guest_agent(ga_state);
>       register_signal_handlers();
>
> diff --git a/qerror.c b/qerror.c
> index 656efc2..a998d2f 100644
> --- a/qerror.c
> +++ b/qerror.c
> @@ -65,6 +65,10 @@ static const QErrorStringTable qerror_table[] = {
>           .desc      = "The command %(name) has not been found",
>       },
>       {
> +        .error_fmt = QERR_COMMAND_DISABLED,
> +        .desc      = "The command %(name) has been disabled for this instance",
> +    },
> +    {
>           .error_fmt = QERR_DEVICE_ENCRYPTED,
>           .desc      = "Device '%(device)' is encrypted",
>       },
> diff --git a/qerror.h b/qerror.h
> index 161d654..0d3d4c5 100644
> --- a/qerror.h
> +++ b/qerror.h
> @@ -66,6 +66,9 @@ QError *qobject_to_qerror(const QObject *obj);
>   #define QERR_COMMAND_NOT_FOUND \
>       "{ 'class': 'CommandNotFound', 'data': { 'name': %s } }"
>
> +#define QERR_COMMAND_DISABLED \
> +    "{ 'class': 'CommandDisabled', 'data': { 'name': %s } }"
> +
>   #define QERR_DEVICE_ENCRYPTED \
>       "{ 'class': 'DeviceEncrypted', 'data': { 'device': %s } }"
>

      parent reply	other threads:[~2011-12-12 23:35 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-07  4:03 [Qemu-devel] [PATCH 1/2] guest agent: add RPC blacklist command-line option Michael Roth
2011-12-07  4:03 ` [Qemu-devel] [PATCH 2/2] guest agent: add supported command list to guest-info RPC Michael Roth
2011-12-07 10:34 ` [Qemu-devel] [PATCH 1/2] guest agent: add RPC blacklist command-line option Dor Laor
2011-12-07 10:52   ` Daniel P. Berrange
2011-12-07 12:12     ` Dor Laor
2011-12-07 16:45       ` Michael Roth
2011-12-08 22:53         ` Dor Laor
2011-12-08 23:38           ` Michael Roth
2011-12-12 23:34 ` Anthony Liguori [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4EE68F93.4060808@us.ibm.com \
    --to=aliguori@us.ibm.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).