[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 3/6] xenstore: enhance control command support
The Xenstore protocol supports the XS_CONTROL command for triggering various actions in the Xenstore daemon. Enhance that support by using a command table and adding a help function. Support multiple control commands in the associated xenstore-control program used to issue XS_CONTROL commands. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- tools/xenstore/xenstore_control.c | 70 +++++++++++++++++++------- tools/xenstore/xenstored_control.c | 100 +++++++++++++++++++++++++++++++++---- 2 files changed, 140 insertions(+), 30 deletions(-) diff --git a/tools/xenstore/xenstore_control.c b/tools/xenstore/xenstore_control.c index 0a108df..afa0449 100644 --- a/tools/xenstore/xenstore_control.c +++ b/tools/xenstore/xenstore_control.c @@ -7,29 +7,61 @@ int main(int argc, char **argv) { - struct xs_handle * xsh; + struct xs_handle *xsh; + char *par = NULL; + char *ret; + unsigned int p, len = 0; + int rc = 0; - if (argc < 2 || - strcmp(argv[1], "check")) - { - fprintf(stderr, - "Usage:\n" - "\n" - " %s check\n" - "\n", argv[0]); - return 2; - } + if (argc < 2) { + fprintf(stderr, "Usage:\n" + "%s <command> [<arg>...]\n", argv[0]); + rc = 2; + goto out; + } - xsh = xs_daemon_open(); + for (p = 2; p < argc; p++) + len += strlen(argv[p]) + 1; + if (len) { + par = malloc(len); + if (!par) { + fprintf(stderr, "Allocation error.\n"); + rc = 1; + goto out; + } + len = 0; + for (p = 2; p < argc; p++) { + memcpy(par + len, argv[p], strlen(argv[p]) + 1); + len += strlen(argv[p]) + 1; + } + } - if (xsh == NULL) { - fprintf(stderr, "Failed to contact Xenstored.\n"); - return 1; - } + xsh = xs_open(0); + if (xsh == NULL) { + fprintf(stderr, "Failed to contact Xenstored.\n"); + rc = 1; + goto out; + } - xs_debug_command(xsh, argv[1], NULL, 0); + ret = xs_control_command(xsh, argv[1], par, len); + if (!ret) { + rc = 3; + if (errno == EINVAL) { + ret = xs_control_command(xsh, "help", NULL, 0); + if (ret) + fprintf(stderr, "Command not supported. Valid commands are:\n" + "%s\n", ret); + else + fprintf(stderr, "Error when executing command.\n"); + } else + fprintf(stderr, "Error %d when trying to execute command.\n", + errno); + } else if (strlen(ret) > 0) + printf("%s\n", ret); - xs_daemon_close(xsh); + xs_close(xsh); - return 0; + out: + free(par); + return rc; } diff --git a/tools/xenstore/xenstored_control.c b/tools/xenstore/xenstored_control.c index f169d23..3080e47 100644 --- a/tools/xenstore/xenstored_control.c +++ b/tools/xenstore/xenstored_control.c @@ -17,30 +17,108 @@ */ #include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> #include "utils.h" +#include "talloc.h" #include "xenstored_core.h" #include "xenstored_control.h" +struct cmd_s { + char *cmd; + int (*func)(void *, struct connection *, char **, int); + char *pars; +}; + +static int do_control_check(void *ctx, struct connection *conn, + char **vec, int num) +{ + if (num) + return EINVAL; + + check_store(); + + send_ack(conn, XS_CONTROL); + return 0; +} + +static int do_control_print(void *ctx, struct connection *conn, + char **vec, int num) +{ + if (num != 1) + return EINVAL; + + xprintf("control: %s", vec[0]); + + send_ack(conn, XS_CONTROL); + return 0; +} + +static int do_control_help(void *, struct connection *, char **, int); + +static struct cmd_s cmds[] = { + { "check", do_control_check, "" }, + { "print", do_control_print, "<string>" }, + { "help", do_control_help, "" }, +}; + +static int do_control_help(void *ctx, struct connection *conn, + char **vec, int num) +{ + int cmd, len = 0; + char *resp; + + if (num) + return EINVAL; + + for (cmd = 0; cmd < ARRAY_SIZE(cmds); cmd++) { + len += strlen(cmds[cmd].cmd) + 1; + len += strlen(cmds[cmd].pars) + 1; + } + len++; + + resp = talloc_array(ctx, char, len); + if (!resp) + return ENOMEM; + + len = 0; + for (cmd = 0; cmd < ARRAY_SIZE(cmds); cmd++) { + strcpy(resp + len, cmds[cmd].cmd); + len += strlen(cmds[cmd].cmd); + resp[len] = '\t'; + len++; + strcpy(resp + len, cmds[cmd].pars); + len += strlen(cmds[cmd].pars); + resp[len] = '\n'; + len++; + } + resp[len] = 0; + + send_reply(conn, XS_CONTROL, resp, len); + return 0; +} + int do_control(struct connection *conn, struct buffered_data *in) { int num; + int cmd; + char **vec; if (conn->id != 0) return EACCES; num = xs_count_strings(in->buffer, in->used); + vec = talloc_array(in, char *, num); + if (!vec) + return ENOMEM; + if (get_strings(in, vec, num) != num) + return EIO; - if (streq(in->buffer, "print")) { - if (num < 2) - return EINVAL; - xprintf("control: %s", in->buffer + strlen(in->buffer) + 1); - } + for (cmd = 0; cmd < ARRAY_SIZE(cmds); cmd++) + if (streq(vec[0], cmds[cmd].cmd)) + return cmds[cmd].func(in, conn, vec + 1, num - 1); - if (streq(in->buffer, "check")) - check_store(); - - send_ack(conn, XS_CONTROL); - - return 0; + return EINVAL; } -- 2.10.2 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |