diff options
author | Amar Tumballi <amar@gluster.com> | 2010-07-08 08:16:13 +0000 |
---|---|---|
committer | Anand V. Avati <avati@dev.gluster.com> | 2010-07-08 23:28:08 -0700 |
commit | 915adb9c1291d140e57765b7fad0c5bb0e7d5ed5 (patch) | |
tree | 0330fa8796e18601ef7ef1441b6d4eb0df8cb9b6 /cli/src/cli.c | |
parent | 7e489f3cc7f3eb738d2698dcf588bad0bdc12a8b (diff) |
gluster-CLI-and-mgmt-glusterd-added-to-codebase
Signed-off-by: Vijay Bellur <vijay@gluster.com>
Signed-off-by: Amar Tumballi <amar@gluster.com>
Signed-off-by: Anand V. Avati <avati@dev.gluster.com>
BUG: 971 (dynamic volume management)
URL: http://bugs.gluster.com/cgi-bin/bugzilla3/show_bug.cgi?id=971
Diffstat (limited to 'cli/src/cli.c')
-rw-r--r-- | cli/src/cli.c | 467 |
1 files changed, 467 insertions, 0 deletions
diff --git a/cli/src/cli.c b/cli/src/cli.c new file mode 100644 index 00000000000..970db712fe3 --- /dev/null +++ b/cli/src/cli.c @@ -0,0 +1,467 @@ +/* + 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 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 + 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 <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/resource.h> +#include <sys/file.h> +#include <netdb.h> +#include <signal.h> +#include <libgen.h> + +#include <sys/utsname.h> + +#include <stdint.h> +#include <pthread.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <semaphore.h> +#include <errno.h> + +#ifndef _CONFIG_H +#define _CONFIG_H +#include "config.h" +#endif + +#ifdef HAVE_MALLOC_H +#include <malloc.h> +#endif + +#ifdef HAVE_MALLOC_STATS +#ifdef DEBUG +#include <mcheck.h> +#endif +#endif + +#include "cli.h" +#include "cli-cmd.h" +#include "cli-mem-types.h" + +#include "xlator.h" +#include "glusterfs.h" +#include "compat.h" +#include "logging.h" +#include "dict.h" +#include "list.h" +#include "timer.h" +#include "stack.h" +#include "revision.h" +#include "common-utils.h" +#include "event.h" +#include "globals.h" +#include "syscall.h" + +#include <fnmatch.h> + +/* using argp for command line parsing */ +static char gf_doc[] = ""; + +static char argp_doc[] = "COMMAND [PARAM ...]"; + +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. " \ + "<http://www.gluster.com>\n" \ + "GlusterFS comes with ABSOLUTELY NO WARRANTY.\n" \ + "You may redistribute copies of GlusterFS under the terms of "\ + "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:"}, + {"debug", ARGP_DEBUG_KEY, 0, 0, + "Process runs in foreground and logs to console"}, + {0, } +}; + +struct rpc_clnt *global_rpc; + +rpc_clnt_prog_t *cli_rpc_prog; + + +extern struct rpc_clnt_program cli3_1_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_DEBUG_KEY: + break; + 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) +{ + cmd_args_t *cmd_args = NULL; + struct rlimit lim = {0, }; + call_pool_t *pool = NULL; + + xlator_mem_acct_init (THIS, cli_mt_end); + + ctx->process_uuid = generate_uuid (); + 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); + if (!ctx->iobuf_pool) + return -1; + + ctx->event_pool = event_pool_new (DEFAULT_EVENT_POOL_SIZE); + if (!ctx->event_pool) + return -1; + + pool = GF_CALLOC (1, sizeof (call_pool_t), + cli_mt_call_pool_t); + if (!pool) + return -1; + INIT_LIST_HEAD (&pool->all_frames); + LOCK_INIT (&pool->lock); + ctx->pool = pool; + + pthread_mutex_init (&(ctx->lock), NULL); + + cmd_args = &ctx->cmd_args; + + /* parsing command line arguments */ + cmd_args->log_file = "/dev/stderr"; + cmd_args->log_level = GF_LOG_NORMAL; + + INIT_LIST_HEAD (&cmd_args->xlator_options); + + lim.rlim_cur = RLIM_INFINITY; + lim.rlim_max = RLIM_INFINITY; + setrlimit (RLIMIT_CORE, &lim); + + return 0; +} + + +static int +logging_init (glusterfs_ctx_t *ctx) +{ + cmd_args_t *cmd_args = NULL; + + cmd_args = &ctx->cmd_args; + + if (gf_log_init (cmd_args->log_file) == -1) { + fprintf (stderr, + "failed to open logfile %s. exiting\n", + cmd_args->log_file); + return -1; + } + + gf_log_set_loglevel (cmd_args->log_level); + + return 0; +} + +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) +{ + int ret = -1; + int count = 0; + char start_ping = 0; + struct iovec iov = {0, }; + struct iobuf *iobuf = NULL; + char new_iobref = 0; + + GF_ASSERT (this); + + iobuf = iobuf_get (this->ctx->iobuf_pool); + if (!iobuf) { + goto out; + }; + + if (!iobref) { + iobref = iobref_new (); + if (!iobref) { + goto out; + } + + new_iobref = 1; + } + + iobref_add (iobref, iobuf); + + iov.iov_base = iobuf->ptr; + iov.iov_len = 128 * GF_UNIT_KB; + + + /* Create the xdr payload */ + if (req && sfunc) { + ret = sfunc (iov, req); + if (ret == -1) { + goto out; + } + iov.iov_len = ret; + count = 1; + } + + /* Send the msg */ + ret = rpc_clnt_submit (global_rpc, prog, procnum, cbkfn, + &iov, count, + NULL, 0, iobref, frame); + + 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); + } + + if (start_ping) + //client_start_ping ((void *) this); + + ret = 0; + +out: + return ret; +} + +int +parse_cmdline (int argc, char *argv[], struct cli_state *state) +{ + int ret = 0; + struct argp argp = { 0,}; + + argp.options = gf_options; + argp.parser = parse_opts; + argp.args_doc = argp_doc; + argp.doc = gf_doc; + + ret = argp_parse (&argp, argc, argv, ARGP_IN_ORDER, NULL, state); + + return ret; +} + + +int +cli_cmd_tree_init (struct cli_cmd_tree *tree) +{ + struct cli_cmd_word *root = NULL; + int ret = 0; + + root = &tree->root; + root->tree = tree; + + return ret; +} + + +int +cli_state_init (struct cli_state *state) +{ + struct cli_cmd_tree *tree = NULL; + int ret = 0; + + tree = &state->tree; + tree->state = state; + + ret = cli_cmd_tree_init (tree); + + return ret; +} + + +int +cli_out (const char *fmt, ...) +{ + struct cli_state *state = NULL; + va_list ap; + + state = global_state; + + va_start (ap, fmt); + +#ifdef HAVE_READLINE + if (state->rl_enabled && !state->rl_processing) + return cli_rl_out(state, fmt, ap); +#endif + + return vprintf (fmt, ap); +} + +struct rpc_clnt * +cli_rpc_init (struct cli_state *state) +{ + struct rpc_clnt *rpc = NULL; + struct rpc_clnt_config rpc_cfg = {0,}; + dict_t *options = NULL; + int ret = -1; + + rpc_cfg.remote_host = "localhost"; + rpc_cfg.remote_port = CLI_GLUSTERD_PORT; + + cli_rpc_prog = &cli3_1_prog; + options = dict_new (); + if (!options) + goto out; + + ret = dict_set_str (options, "remote-host", "localhost"); + if (ret) + goto out; + + ret = dict_set_int32 (options, "remote-port", CLI_GLUSTERD_PORT); + if (ret) + goto out; + + ret = dict_set_str (options, "transport.address-family", "inet"); + if (ret) + goto out; + + rpc = rpc_clnt_init (&rpc_cfg, options, THIS->ctx, THIS->name); + +out: + return rpc; +} + +struct cli_state *global_state; + +int +main (int argc, char *argv[]) +{ + struct cli_state state = {0, }; + int ret = -1; + glusterfs_ctx_t *ctx = NULL; + + ret = glusterfs_globals_init (); + if (ret) + return ret; + + ctx = glusterfs_ctx_get (); + if (!ctx) + return ENOMEM; + + ret = glusterfs_ctx_defaults_init (ctx); + if (ret) + goto out; + + ret = cli_state_init (&state); + if (ret) + goto out; + + state.ctx = ctx; + global_state = &state; + + ret = parse_cmdline (argc, argv, &state); + if (ret) + goto out; + + ret = logging_init (ctx); + if (ret) + goto out; + + ret = cli_cmds_register (&state); + if (ret) + goto out; + + ret = cli_input_init (&state); + if (ret) + goto out; + + global_rpc = cli_rpc_init (&state); + if (!global_rpc) + goto out; + + ret = event_dispatch (ctx->event_pool); + +out: +// glusterfs_ctx_destroy (ctx); + + return ret; +} |