[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

 


Rackspace

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