[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

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.