diff options
author | Michael Roth <mdroth@linux.vnet.ibm.com> | 2011-12-06 22:03:42 -0600 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2011-12-12 17:06:21 -0600 |
commit | abd6cf6d8e6be55a6535bf27b692bdf520462c15 (patch) | |
tree | fec8702ec9241e5fdb04e56574b69276686f3ad4 /qapi | |
parent | 4cb016587a34fee08f42ab04ba6daa7842f41228 (diff) |
guest agent: add RPC blacklist command-line option
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>
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'qapi')
-rw-r--r-- | qapi/qmp-core.h | 3 | ||||
-rw-r--r-- | qapi/qmp-dispatch.c | 4 | ||||
-rw-r--r-- | qapi/qmp-registry.c | 43 |
3 files changed, 45 insertions, 5 deletions
diff --git a/qapi/qmp-core.h b/qapi/qmp-core.h index f1c26e4b2e..3cf1781fa4 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 558469325c..43f640a95e 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 5ff99cff14..abafa347fb 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; +} |