From patchwork Tue Feb 21 15:07:34 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?SsO8cmdlbiBHcm/Dnw==?= X-Patchwork-Id: 9584803 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 22651602A7 for ; Tue, 21 Feb 2017 15:10:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 09F8D285AD for ; Tue, 21 Feb 2017 15:10:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F3283285EB; Tue, 21 Feb 2017 15:10:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1B115285AD for ; Tue, 21 Feb 2017 15:10:14 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cgC2a-0005yi-Mc; Tue, 21 Feb 2017 15:07:44 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cgC2Z-0005xE-1O for xen-devel@lists.xenproject.org; Tue, 21 Feb 2017 15:07:43 +0000 Received: from [85.158.137.68] by server-7.bemta-3.messagelabs.com id AA/E2-23854-EB75CA85; Tue, 21 Feb 2017 15:07:42 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOLMWRWlGSWpSXmKPExsVyuP0Ov+7e8DU RBg33lC2+b5nM5MDocfjDFZYAxijWzLyk/IoE1ozOO0eZC874Vcz8fYi9gfGHXRcjJ4eEgJHE 24n/mLoYuTiEBBYyStw49Y8VJMEmoCqx4fopMFtEQEni3qrJTCA2s0CoxMl395hBbGEBR4mf2 +6CxVmA6g93n2DvYuTg4BUwkeg9LgoxX15i4fkjYCWcAqYS/x/0gtlCQCVTm5ayTGDkXsDIsI pRozi1qCy1SNfQWC+pKDM9oyQ3MTNH19DAWC83tbg4MT01JzGpWC85P3cTI9C7DECwg3Hbds9 DjJIcTEqivNmWayKE+JLyUyozEosz4otKc1KLDzHKcHAoSfBqhwHlBItS01Mr0jJzgGEGk5bg 4FES4S0GSfMWFyTmFmemQ6ROMRpznLpx+iUTx77tZ14yCbHk5eelSonzzgcpFQApzSjNgxsEC /9LjLJSwryMQKcJ8RSkFuVmlqDKv2IU52BUEubdCTKFJzOvBG7fK6BTmIBOuemxEuSUkkSElF QDY/TBSf+cXNK8mD7rbFVvu/+qPu3grqRZh4zueojNFJq29o1Ru/uxeTMOGIkf+5Cjo3yvvkV hceI/g6sb2951ebGYTbnBuXHGBXUzSwuOyL5TF5r8zCV2/BZ/tHPFe/f8NxavdKN6ttjOl/xu 7GJscLBSZ8fWA695cy/tVL5mkf+mLCvxQNliGSWW4oxEQy3mouJEAPYz1416AgAA X-Env-Sender: jgross@suse.com X-Msg-Ref: server-5.tower-31.messagelabs.com!1487689661!83484371!1 X-Originating-IP: [195.135.220.15] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 47357 invoked from network); 21 Feb 2017 15:07:41 -0000 Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by server-5.tower-31.messagelabs.com with DHE-RSA-CAMELLIA256-SHA encrypted SMTP; 21 Feb 2017 15:07:41 -0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 4C727AD62; Tue, 21 Feb 2017 15:07:41 +0000 (UTC) From: Juergen Gross To: xen-devel@lists.xenproject.org Date: Tue, 21 Feb 2017 16:07:34 +0100 Message-Id: <20170221150737.30589-3-jgross@suse.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170221150737.30589-1-jgross@suse.com> References: <20170221150737.30589-1-jgross@suse.com> Cc: Juergen Gross , wei.liu2@citrix.com, ian.jackson@eu.citrix.com Subject: [Xen-devel] [PATCH v2 2/5] xenstore: enhance control command support X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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 diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index 36b6fd4..bdca108 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_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 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 [...]\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_control.c b/tools/xenstore/xenstored_control.c new file mode 100644 index 0000000..3080e47 --- /dev/null +++ b/tools/xenstore/xenstored_control.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 . +*/ + +#include +#include +#include +#include + +#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, "" }, + { "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; +} diff --git a/tools/xenstore/xenstored_control.h b/tools/xenstore/xenstored_control.h new file mode 100644 index 0000000..207e0a6 --- /dev/null +++ b/tools/xenstore/xenstored_control.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 . +*/ + +int do_control(struct connection *conn, struct buffered_data *in); diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index e332d7f..e0f1261 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_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 = 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);