[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/4] xenstore: enhance debug command support
The Xenstore protocol supports the XS_DEBUG command for triggering various actions in the Xenstore daemon. Enhance that support by using a command table and adding a help function. Move all the XS_DEBUG related code to a new source file xenstored_debug.c. Support multiple debug commands in the associated xenstore-control program used to issue XS_DEBUG commands. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- tools/xenstore/Makefile | 4 +- tools/xenstore/xenstore_control.c | 65 ++++++++++++++------ tools/xenstore/xenstored_core.c | 29 +-------- tools/xenstore/xenstored_core.h | 2 +- tools/xenstore/xenstored_debug.c | 124 ++++++++++++++++++++++++++++++++++++++ tools/xenstore/xenstored_debug.h | 19 ++++++ tools/xenstore/xs.c | 1 - 7 files changed, 196 insertions(+), 48 deletions(-) create mode 100644 tools/xenstore/xenstored_debug.c create mode 100644 tools/xenstore/xenstored_debug.h diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index 36b6fd4..3a9ac02 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -23,7 +23,9 @@ LDFLAGS += $(LDFLAGS-y) CLIENTS := xenstore-exists xenstore-list xenstore-read xenstore-rm xenstore-chmod CLIENTS += xenstore-write xenstore-ls xenstore-watch -XENSTORED_OBJS = xenstored_core.o xenstored_watch.o xenstored_domain.o xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o hashtable.o +XENSTORED_OBJS = xenstored_core.o xenstored_watch.o xenstored_domain.o +XENSTORED_OBJS += xenstored_transaction.o xenstored_debug.o +XENSTORED_OBJS += xs_lib.o talloc.o utils.o tdb.o hashtable.o XENSTORED_OBJS_$(CONFIG_Linux) = xenstored_posix.o XENSTORED_OBJS_$(CONFIG_SunOS) = xenstored_solaris.o xenstored_posix.o xenstored_probes.o diff --git a/tools/xenstore/xenstore_control.c b/tools/xenstore/xenstore_control.c index 0a108df..e42d478 100644 --- a/tools/xenstore/xenstore_control.c +++ b/tools/xenstore/xenstore_control.c @@ -7,29 +7,56 @@ 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]); + return 2; + } - 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"); + return 1; + } + 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"); + return 1; + } - xs_debug_command(xsh, argv[1], NULL, 0); + ret = xs_debug_command(xsh, argv[1], par, len); + if (!ret) { + rc = 3; + if (errno == EINVAL) { + ret = xs_debug_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; + return rc; } diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 1e9b622..b84b081 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -51,6 +51,7 @@ #include "xenstored_watch.h" #include "xenstored_transaction.h" #include "xenstored_domain.h" +#include "xenstored_debug.h" #include "tdb.h" #include "hashtable.h" @@ -84,7 +85,6 @@ static TDB_CONTEXT *tdb_ctx = NULL; static bool trigger_talloc_report = false; static void corrupt(struct connection *conn, const char *fmt, ...); -static void check_store(void); static const char *sockmsg_string(enum xsd_sockmsg_type type); #define log(...) \ @@ -1261,34 +1261,11 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in) return 0; } -static int do_debug(struct connection *conn, struct buffered_data *in) -{ - int num; - - if (conn->id != 0) - return EACCES; - - num = xs_count_strings(in->buffer, in->used); - - if (streq(in->buffer, "print")) { - if (num < 2) - return EINVAL; - xprintf("debug: %s", in->buffer + get_string(in, 0)); - } - - if (streq(in->buffer, "check")) - check_store(); - - send_ack(conn, XS_DEBUG); - - return 0; -} - static struct { const char *str; int (*func)(struct connection *conn, struct buffered_data *in); } const wire_funcs[XS_TYPE_COUNT] = { - [XS_DEBUG] = { "DEBUG", do_debug }, + [XS_DEBUG] = { "DEBUG", do_xs_debug }, [XS_DIRECTORY] = { "DIRECTORY", send_directory }, [XS_READ] = { "READ", do_read }, [XS_GET_PERMS] = { "GET_PERMS", do_get_perms }, @@ -1764,7 +1741,7 @@ static void clean_store(struct hashtable *reachable) } -static void check_store(void) +void check_store(void) { char * root = talloc_strdup(NULL, "/"); struct hashtable * reachable = diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index f6a56f7..89c1d75 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -158,7 +158,7 @@ TDB_CONTEXT *tdb_context(struct connection *conn); bool replace_tdb(const char *newname, TDB_CONTEXT *newtdb); struct connection *new_connection(connwritefn_t *write, connreadfn_t *read); - +void check_store(void); /* Is this a valid node name? */ bool is_valid_nodename(const char *node); diff --git a/tools/xenstore/xenstored_debug.c b/tools/xenstore/xenstored_debug.c new file mode 100644 index 0000000..c01bfae --- /dev/null +++ b/tools/xenstore/xenstored_debug.c @@ -0,0 +1,124 @@ +/* + Interactive commands for Xen Store Daemon. + Copyright (C) 2017 Juergen Gross, SUSE Linux GmbH + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include "utils.h" +#include "talloc.h" +#include "xenstored_core.h" +#include "xenstored_debug.h" + +struct cmd_s { + char *cmd; + int (*func)(void *, struct connection *, char **, int); + char *pars; +}; + +static int do_debug_check(void *ctx, struct connection *conn, + char **vec, int num) +{ + if (num) + return EINVAL; + + check_store(); + + send_ack(conn, XS_DEBUG); + return 0; +} + +static int do_debug_print(void *ctx, struct connection *conn, + char **vec, int num) +{ + if (num != 1) + return EINVAL; + + xprintf("debug: %s", vec[0]); + + send_ack(conn, XS_DEBUG); + return 0; +} + +static int do_debug_help(void *, struct connection *, char **, int); + +static struct cmd_s cmds[] = { + { "check", do_debug_check, "" }, + { "print", do_debug_print, "<string>" }, + { "help", do_debug_help, "" }, +}; + +static int do_debug_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_DEBUG, resp, len); + return 0; +} + +int do_xs_debug(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; + + 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); + + return EINVAL; +} diff --git a/tools/xenstore/xenstored_debug.h b/tools/xenstore/xenstored_debug.h new file mode 100644 index 0000000..87343e8 --- /dev/null +++ b/tools/xenstore/xenstored_debug.h @@ -0,0 +1,19 @@ +/* + Interactive commands for Xen Store Daemon. + Copyright (C) 2017 Juergen Gross, SUSE Linux GmbH + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; If not, see <http://www.gnu.org/licenses/>. +*/ + +int do_xs_debug(struct connection *conn, struct buffered_data *in); diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c index 6fa1261..9c0787f 100644 --- a/tools/xenstore/xs.c +++ b/tools/xenstore/xs.c @@ -1165,7 +1165,6 @@ out: return port; } -/* Only useful for DEBUG versions */ char *xs_debug_command(struct xs_handle *h, const char *cmd, void *data, unsigned int len) { -- 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 |