@@ -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_control.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
@@ -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;
}
new file mode 100644
@@ -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_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;
+
+ 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;
+}
new file mode 100644
@@ -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_control(struct connection *conn, struct buffered_data *in);
@@ -51,6 +51,7 @@
#include "xenstored_watch.h"
#include "xenstored_transaction.h"
#include "xenstored_domain.h"
+#include "xenstored_control.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,29 +1261,6 @@ static int do_set_perms(struct connection *conn, struct buffered_data *in)
return 0;
}
-static int do_control(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("control: %s", in->buffer + get_string(in, 0));
- }
-
- if (streq(in->buffer, "check"))
- check_store();
-
- send_ack(conn, XS_CONTROL);
-
- return 0;
-}
-
static struct {
const char *str;
int (*func)(struct connection *conn, struct buffered_data *in);
@@ -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 =
@@ -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);
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. Move all the XS_CONTROL related code to a new source file xenstored_control.c. Support multiple control commands in the associated xenstore-control program used to issue XS_CONTROL commands. Signed-off-by: Juergen Gross <jgross@suse.com> --- tools/xenstore/Makefile | 4 +- tools/xenstore/xenstore_control.c | 65 +++++++++++++------ tools/xenstore/xenstored_control.c | 124 +++++++++++++++++++++++++++++++++++++ tools/xenstore/xenstored_control.h | 19 ++++++ tools/xenstore/xenstored_core.c | 27 +------- tools/xenstore/xenstored_core.h | 2 +- 6 files changed, 195 insertions(+), 46 deletions(-) create mode 100644 tools/xenstore/xenstored_control.c create mode 100644 tools/xenstore/xenstored_control.h