diff options
Diffstat (limited to 'cli/src/cli.c')
| -rw-r--r-- | cli/src/cli.c | 434 |
1 files changed, 228 insertions, 206 deletions
diff --git a/cli/src/cli.c b/cli/src/cli.c index d6c801967..91b315ff1 100644 --- a/cli/src/cli.c +++ b/cli/src/cli.c @@ -1,22 +1,12 @@ /* - Copyright (c) 2010 Gluster, Inc. <http://www.gluster.com> - This file is part of GlusterFS. - - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS 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 - Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. -*/ + Copyright (c) 2010-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -74,27 +64,23 @@ #include "call-stub.h" #include <fnmatch.h> +#include "xdr-generic.h" + extern int connected; /* using argp for command line parsing */ -static char gf_doc[] = ""; - -static char argp_doc[] = ""; const char *argp_program_version = "" \ PACKAGE_NAME" "PACKAGE_VERSION" built on "__DATE__" "__TIME__ \ "\nRepository revision: " GLUSTERFS_REPOSITORY_REVISION "\n" \ - "Copyright (c) 2006-2010 Gluster Inc. " \ + "Copyright (c) 2006-2011 Gluster Inc. " \ "<http://www.gluster.com>\n" \ "GlusterFS comes with ABSOLUTELY NO WARRANTY.\n" \ "You may redistribute copies of GlusterFS under the terms of "\ - "the GNU Affero General Public License."; + "the GNU General Public License."; const char *argp_program_bug_address = "<" PACKAGE_BUGREPORT ">"; -static struct argp_option gf_options[] = { - {0, 0, 0, 0, "Basic options:"}, - {0, } -}; + struct rpc_clnt *global_rpc; @@ -103,76 +89,6 @@ rpc_clnt_prog_t *cli_rpc_prog; extern struct rpc_clnt_program cli_prog; -static error_t -parse_opts (int key, char *arg, struct argp_state *argp_state) -{ - struct cli_state *state = NULL; - char **argv = NULL; - - state = argp_state->input; - - switch (key) { - case ARGP_KEY_ARG: - if (!state->argc) { - argv = calloc (state->argc + 2, - sizeof (*state->argv)); - } else { - argv = realloc (state->argv, (state->argc + 2) * - sizeof (*state->argv)); - } - if (!argv) - return -1; - - state->argv = argv; - - argv[state->argc] = strdup (arg); - if (!argv[state->argc]) - return -1; - state->argc++; - argv[state->argc] = NULL; - - break; - } - - return 0; -} - - - -static char * -generate_uuid () -{ - char tmp_str[1024] = {0,}; - char hostname[256] = {0,}; - struct timeval tv = {0,}; - struct tm now = {0, }; - char now_str[32]; - - if (gettimeofday (&tv, NULL) == -1) { - gf_log ("glusterfsd", GF_LOG_ERROR, - "gettimeofday: failed %s", - strerror (errno)); - } - - if (gethostname (hostname, 256) == -1) { - gf_log ("glusterfsd", GF_LOG_ERROR, - "gethostname: failed %s", - strerror (errno)); - } - - localtime_r (&tv.tv_sec, &now); - strftime (now_str, 32, "%Y/%m/%d-%H:%M:%S", &now); - snprintf (tmp_str, 1024, "%s-%d-%s:%" -#ifdef GF_DARWIN_HOST_OS - PRId32, -#else - "ld", -#endif - hostname, getpid(), now_str, tv.tv_usec); - - return gf_strdup (tmp_str); -} - static int glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx) { @@ -182,13 +98,13 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx) xlator_mem_acct_init (THIS, cli_mt_end); - ctx->process_uuid = generate_uuid (); + ctx->process_uuid = generate_glusterfs_ctx_id (); if (!ctx->process_uuid) return -1; ctx->page_size = 128 * GF_UNIT_KB; - ctx->iobuf_pool = iobuf_pool_new (8 * GF_UNIT_MB, ctx->page_size); + ctx->iobuf_pool = iobuf_pool_new (); if (!ctx->iobuf_pool) return -1; @@ -201,22 +117,33 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx) if (!pool) return -1; - /* frame_mem_pool size 112 * 16k */ - pool->frame_mem_pool = mem_pool_new (call_frame_t, 16384); - + /* frame_mem_pool size 112 * 64 */ + pool->frame_mem_pool = mem_pool_new (call_frame_t, 32); if (!pool->frame_mem_pool) return -1; - /* stack_mem_pool size 256 * 8k */ - pool->stack_mem_pool = mem_pool_new (call_stack_t, 8192); + /* stack_mem_pool size 256 * 128 */ + pool->stack_mem_pool = mem_pool_new (call_stack_t, 16); if (!pool->stack_mem_pool) return -1; - ctx->stub_mem_pool = mem_pool_new (call_stub_t, 1024); + ctx->stub_mem_pool = mem_pool_new (call_stub_t, 16); if (!ctx->stub_mem_pool) return -1; + ctx->dict_pool = mem_pool_new (dict_t, 32); + if (!ctx->dict_pool) + return -1; + + ctx->dict_pair_pool = mem_pool_new (data_pair_t, 512); + if (!ctx->dict_pair_pool) + return -1; + + ctx->dict_data_pool = mem_pool_new (data_t, 512); + if (!ctx->dict_data_pool) + return -1; + INIT_LIST_HEAD (&pool->all_frames); LOCK_INIT (&pool->lock); ctx->pool = pool; @@ -225,10 +152,6 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx) cmd_args = &ctx->cmd_args; - /* parsing command line arguments */ - cmd_args->log_file = "/dev/null"; - cmd_args->log_level = GF_LOG_NONE; - INIT_LIST_HEAD (&cmd_args->xlator_options); lim.rlim_cur = RLIM_INFINITY; @@ -240,19 +163,22 @@ glusterfs_ctx_defaults_init (glusterfs_ctx_t *ctx) static int -logging_init (glusterfs_ctx_t *ctx) +logging_init (glusterfs_ctx_t *ctx, struct cli_state *state) { - cmd_args_t *cmd_args = NULL; + char *log_file = state->log_file ? state->log_file : + DEFAULT_CLI_LOG_FILE_DIRECTORY "/cli.log"; - cmd_args = &ctx->cmd_args; - - if (gf_log_init (cmd_args->log_file) == -1) { + /* passing ident as NULL means to use default ident for syslog */ + if (gf_log_init (ctx, log_file, NULL) == -1) { fprintf (stderr, "ERROR: failed to open logfile %s\n", - cmd_args->log_file); + log_file); return -1; } - gf_log_set_loglevel (cmd_args->log_level); + /* CLI should not have something to DEBUG after the release, + hence defaulting to INFO loglevel */ + gf_log_set_loglevel ((state->log_level == -1) ? GF_LOG_INFO : + state->log_level); return 0; } @@ -261,41 +187,41 @@ int cli_submit_request (void *req, call_frame_t *frame, rpc_clnt_prog_t *prog, int procnum, struct iobref *iobref, - cli_serialize_t sfunc, xlator_t *this, - fop_cbk_fn_t cbkfn) + xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc) { int ret = -1; int count = 0; - char start_ping = 0; struct iovec iov = {0, }; struct iobuf *iobuf = NULL; char new_iobref = 0; + ssize_t xdr_size = 0; GF_ASSERT (this); - iobuf = iobuf_get (this->ctx->iobuf_pool); - if (!iobuf) { - goto out; - }; + if (req) { + xdr_size = xdr_sizeof (xdrproc, req); + iobuf = iobuf_get2 (this->ctx->iobuf_pool, xdr_size); + if (!iobuf) { + goto out; + }; - if (!iobref) { - iobref = iobref_new (); if (!iobref) { - goto out; - } + iobref = iobref_new (); + if (!iobref) { + goto out; + } - new_iobref = 1; - } + new_iobref = 1; + } - iobref_add (iobref, iobuf); + iobref_add (iobref, iobuf); - iov.iov_base = iobuf->ptr; - iov.iov_len = 128 * GF_UNIT_KB; + iov.iov_base = iobuf->ptr; + iov.iov_len = iobuf_size (iobuf); - /* Create the xdr payload */ - if (req && sfunc) { - ret = sfunc (iov, req); + /* Create the xdr payload */ + ret = xdr_serialize_generic (iov, req, xdrproc); if (ret == -1) { goto out; } @@ -307,22 +233,13 @@ cli_submit_request (void *req, call_frame_t *frame, ret = rpc_clnt_submit (global_rpc, prog, procnum, cbkfn, &iov, count, NULL, 0, iobref, frame, NULL, 0, NULL, 0, NULL); - - if (ret == 0) { - pthread_mutex_lock (&global_rpc->conn.lock); - { - if (!global_rpc->conn.ping_started) { - start_ping = 1; - } - } - pthread_mutex_unlock (&global_rpc->conn.lock); - } - ret = 0; out: if (new_iobref) iobref_unref (iobref); + if (iobuf) + iobuf_unref (iobuf); return ret; } @@ -348,6 +265,12 @@ cli_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, { gf_log (this->name, GF_LOG_TRACE, "got RPC_CLNT_DISCONNECT"); connected = 0; + if (!global_state->prompt && global_state->await_connected) { + ret = 1; + cli_out ("Connection failed. Please check if gluster " + "daemon is operational."); + exit (ret); + } break; } @@ -361,11 +284,44 @@ cli_rpc_notify (struct rpc_clnt *rpc, void *mydata, rpc_clnt_event_t event, return ret; } + +/* + * ret: 0: option successfully processed + * 1: signalling end of option list + * -1: unknown option or other issue + */ int cli_opt_parse (char *opt, struct cli_state *state) { char *oarg; + if (strcmp (opt, "") == 0) + return 1; + + if (strcmp (opt, "version") == 0) { + cli_out ("%s", argp_program_version); + exit (0); + } + + if (strcmp (opt, "print-logdir") == 0) { + cli_out ("%s", DEFAULT_LOG_FILE_DIRECTORY); + exit (0); + } + + if (strcmp (opt, "print-statedumpdir") == 0) { + cli_out ("%s", DEFAULT_VAR_RUN_DIRECTORY); + exit (0); + } + + if (strcmp (opt, "xml") == 0) { +#if (HAVE_LIB_XML) + state->mode |= GLUSTER_MODE_XML; +#else + cli_err ("XML output not supported. Ignoring '--xml' option"); +#endif + return 0; + } + oarg = strtail (opt, "mode="); if (oarg) { if (strcmp (oarg, "script") == 0) { @@ -383,6 +339,26 @@ cli_opt_parse (char *opt, struct cli_state *state) return 0; } + oarg = strtail (opt, "log-file="); + if (oarg) { + state->log_file = oarg; + return 0; + } + + oarg = strtail (opt, "log-level="); + if (oarg) { + state->log_level = glusterd_check_log_level(oarg); + if (state->log_level == -1) + return -1; + return 0; + } + + oarg = strtail (opt, "glusterd-sock="); + if (oarg) { + state->glusterd_sock = oarg; + return 0; + } + return -1; } @@ -393,28 +369,32 @@ parse_cmdline (int argc, char *argv[], struct cli_state *state) int i = 0; int j = 0; char *opt = NULL; - struct argp argp = { 0,}; - argp.options = gf_options; - argp.parser = parse_opts; - argp.args_doc = argp_doc; - argp.doc = gf_doc; + state->argc=argc-1; + state->argv=&argv[1]; - for (i = 0; i < argc; i++) { - opt = strtail (argv[i], "--"); + for (i = 0; i < state->argc; i++) { + opt = strtail (state->argv[i], "--"); if (opt) { ret = cli_opt_parse (opt, state); if (ret == -1) { + cli_out ("unrecognized option --%s", opt); + return ret; + } + for (j = i; j < state->argc - 1; j++) + state->argv[j] = state->argv[j + 1]; + state->argc--; + /* argv shifted, next check should be at i again */ + i--; + if (ret == 1) { + /* end of cli options */ + ret = 0; break; } - for (j = i; j < argc - 1; j++) - argv[j] = argv[j + 1]; - argc--; } } - ret = argp_parse (&argp, argc, argv, - ARGP_IN_ORDER, NULL, state); + state->argv[state->argc] = NULL; return ret; } @@ -440,7 +420,7 @@ cli_state_init (struct cli_state *state) int ret = 0; - state->remote_host = "localhost"; + state->log_level = -1; tree = &state->tree; tree->state = state; @@ -459,12 +439,36 @@ cli_usage_out (const char *usage) if (!usage || usage[0] == '\0') return -1; - cli_out ("Usage: %s", usage); + cli_err ("Usage: %s", usage); return 0; } int -cli_out (const char *fmt, ...) +_cli_err (const char *fmt, ...) +{ + struct cli_state *state = NULL; + va_list ap; + int ret = 0; + + state = global_state; + + va_start (ap, fmt); + +#ifdef HAVE_READLINE + if (state->rl_enabled && !state->rl_processing) + return cli_rl_err(state, fmt, ap); +#endif + + ret = vfprintf (stderr, fmt, ap); + fprintf (stderr, "\n"); + va_end (ap); + + return ret; +} + + +int +_cli_out (const char *fmt, ...) { struct cli_state *state = NULL; va_list ap; @@ -502,23 +506,46 @@ cli_rpc_init (struct cli_state *state) if (!options) goto out; - ret = dict_set_str (options, "remote-host", state->remote_host); - if (ret) - goto out; - - if (state->remote_port) - port = state->remote_port; + /* Connect using to glusterd using the specified method, giving + * preference to unix socket connection. If nothing is specified connect + * to the default glusterd socket + */ + if (state->glusterd_sock) { + gf_log ("cli", GF_LOG_INFO, "Connecting to glusterd using " + "sockfile %s", state->glusterd_sock); + ret = rpc_transport_unix_options_build (&options, + state->glusterd_sock, + 0); + if (ret) + goto out; + } else if (state->remote_host) { + gf_log ("cli", GF_LOG_INFO, "Connecting to remote glusterd at " + "%s", state->remote_host); + ret = dict_set_str (options, "remote-host", state->remote_host); + if (ret) + goto out; - ret = dict_set_int32 (options, "remote-port", port); - if (ret) - goto out; + if (state->remote_port) + port = state->remote_port; - ret = dict_set_str (options, "transport.address-family", "inet"); - if (ret) - goto out; + ret = dict_set_int32 (options, "remote-port", port); + if (ret) + goto out; - rpc = rpc_clnt_new (options, this->ctx, this->name); + ret = dict_set_str (options, "transport.address-family", + "inet"); + if (ret) + goto out; + } else { + gf_log ("cli", GF_LOG_DEBUG, "Connecting to glusterd using " + "default socket"); + ret = rpc_transport_unix_options_build + (&options, DEFAULT_GLUSTERD_SOCKFILE, 0); + if (ret) + goto out; + } + rpc = rpc_clnt_new (options, this->ctx, this->name, 16); if (!rpc) goto out; @@ -528,7 +555,7 @@ cli_rpc_init (struct cli_state *state) goto out; } - rpc_clnt_start (rpc); + ret = rpc_clnt_start (rpc); out: if (ret) { if (rpc) @@ -552,32 +579,15 @@ void cli_local_wipe (cli_local_t *local) { if (local) { + GF_FREE (local->get_vol.volname); + if (local->dict) + dict_unref (local->dict); GF_FREE (local); } return; } -void -cli_path_strip_trailing_slashes (char *path) -{ - int i = 0; - int len = 0; - - if (!path) - return; - - len = strlen (path); - for (i = len - 1; i > 0 ; i--) { - if (path[i] != '/') - break; - - } - - if (i < (len - 1)) - path[i + 1] = '\0'; -} - struct cli_state *global_state; int @@ -587,13 +597,19 @@ main (int argc, char *argv[]) int ret = -1; glusterfs_ctx_t *ctx = NULL; - ret = glusterfs_globals_init (); + ctx = glusterfs_ctx_new (); + if (!ctx) + return ENOMEM; + +#ifdef DEBUG + gf_mem_acct_enable_set (ctx); +#endif + + ret = glusterfs_globals_init (ctx); if (ret) return ret; - ctx = glusterfs_ctx_get (); - if (!ctx) - return ENOMEM; + THIS->ctx = ctx; ret = glusterfs_ctx_defaults_init (ctx); if (ret) @@ -610,19 +626,14 @@ main (int argc, char *argv[]) if (ret) goto out; - if (geteuid ()) { - printf ("Only super user can run this command\n"); - return EPERM; - } + ret = logging_init (ctx, &state); + if (ret) + goto out; global_rpc = cli_rpc_init (&state); if (!global_rpc) goto out; - ret = logging_init (ctx); - if (ret) - goto out; - ret = cli_cmds_register (&state); if (ret) goto out; @@ -642,3 +653,14 @@ out: return ret; } + +void +cli_print_line (int len) +{ + GF_ASSERT (len > 0); + + while (len--) + printf ("-"); + + printf ("\n"); +} |
