diff options
Diffstat (limited to 'cli/src/cli-cmd.c')
| -rw-r--r-- | cli/src/cli-cmd.c | 244 |
1 files changed, 212 insertions, 32 deletions
diff --git a/cli/src/cli-cmd.c b/cli/src/cli-cmd.c index 4ef8e86cd..b81f75b5b 100644 --- a/cli/src/cli-cmd.c +++ b/cli/src/cli-cmd.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 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/>. -*/ + 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> @@ -31,12 +21,72 @@ #include "cli.h" #include "cli-cmd.h" #include "cli-mem-types.h" +#include "protocol-common.h" #include <fnmatch.h> static int cmd_done; +static int cmd_sent; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; static pthread_mutex_t cond_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t conn = PTHREAD_COND_INITIALIZER; +static pthread_mutex_t conn_mutex = PTHREAD_MUTEX_INITIALIZER; + +int cli_op_ret = 0; +int connected = 0; + +int cli_cmd_log_help_cbk (struct cli_state *state, struct cli_cmd_word *in_word, + const char **words, int wordcount); + +static unsigned +cli_cmd_needs_connection (struct cli_cmd_word *word) +{ + if (!strcasecmp ("quit", word->word)) + return 0; + + if (!strcasecmp ("help", word->word)) + return 0; + + if (!strcasecmp ("getwd", word->word)) + return 1; + + if (!strcasecmp ("exit", word->word)) + return 0; + + return CLI_DEFAULT_CONN_TIMEOUT; +} + +int +cli_cmd_status_reset (void) +{ + int ret = 0; + + ret = cli_cmd_lock (); + { + if (ret == 0) { + cmd_sent = 0; + cmd_done = 0; + } + } + ret = cli_cmd_unlock (); + return ret; + +} + +int +cli_cmd_sent_status_get (int *status) +{ + int ret = 0; + GF_ASSERT (status); + + ret = cli_cmd_lock (); + { + if (ret == 0) + *status = cmd_sent; + } + ret = cli_cmd_unlock (); + return ret; +} int cli_cmd_process (struct cli_state *state, int argc, char **argv) @@ -73,12 +123,25 @@ cli_cmd_process (struct cli_state *state, int argc, char **argv) return -1; } - ret = word->cbkfn (state, word, (const char **)argv, argc); + if ( strcmp (word->word,"help")==0 ) + goto callback; + state->await_connected = cli_cmd_needs_connection (word); + + ret = cli_cmd_await_connected (state->await_connected); + if (ret) { + cli_out ("Connection failed. Please check if gluster " + "daemon is operational."); + gf_log ("", GF_LOG_INFO, "Exiting with: %d", ret); + exit (ret); + } + +callback: + ret = word->cbkfn (state, word, (const char **)argv, argc); + (void) cli_cmd_status_reset (); return ret; } - int cli_cmd_input_token_count (const char *text) { @@ -138,8 +201,7 @@ cli_cmd_process_line (struct cli_state *state, const char *text) ret = cli_cmd_process (state, count, tokens); out: - if (copy) - free (copy); + free (copy); if (tokens) cli_cmd_tokens_destroy (tokens); @@ -161,46 +223,164 @@ cli_cmds_register (struct cli_state *state) if (ret) goto out; + ret = cli_cmd_system_register (state); + if (ret) + goto out; + ret = cli_cmd_misc_register (state); if (ret) goto out; + ret = cli_cmd_snapshot_register (state); + if (ret) + goto out; out: return ret; } int -cli_cmd_await_response () +cli_cmd_cond_init () { + pthread_mutex_init (&cond_mutex, NULL); pthread_cond_init (&cond, NULL); - cmd_done = 0; + pthread_mutex_init (&conn_mutex, NULL); + pthread_cond_init (&conn, NULL); + + return 0; +} + +int +cli_cmd_lock () +{ pthread_mutex_lock (&cond_mutex); - { - while (!cmd_done) { - pthread_cond_wait (&cond, &cond_mutex); - } - } + return 0; +} + +int +cli_cmd_unlock () +{ pthread_mutex_unlock (&cond_mutex); + return 0; +} - pthread_mutex_destroy (&cond_mutex); - pthread_cond_destroy (&cond); +static void +seconds_from_now (unsigned secs, struct timespec *ts) +{ + struct timeval tv = {0,}; - return 0; + gettimeofday (&tv, NULL); + + ts->tv_sec = tv.tv_sec + secs; + ts->tv_nsec = tv.tv_usec * 1000; +} + +int +cli_cmd_await_response (unsigned time) +{ + struct timespec ts = {0,}; + int ret = 0; + + cli_op_ret = -1; + + seconds_from_now (time, &ts); + while (!cmd_done && !ret) { + ret = pthread_cond_timedwait (&cond, &cond_mutex, + &ts); + } + + cmd_done = 0; + + if (ret) + return ret; + + return cli_op_ret; } int -cli_cmd_broadcast_response () +cli_cmd_broadcast_response (int32_t status) { + pthread_mutex_lock (&cond_mutex); { + if (!cmd_sent) + goto out; cmd_done = 1; + cli_op_ret = status; pthread_cond_broadcast (&cond); } + +out: pthread_mutex_unlock (&cond_mutex); + return 0; +} + +int32_t +cli_cmd_await_connected (unsigned conn_timo) +{ + int32_t ret = 0; + struct timespec ts = {0,}; + + if (!conn_timo) + return 0; + + pthread_mutex_lock (&conn_mutex); + { + seconds_from_now (conn_timo, &ts); + while (!connected && !ret) { + ret = pthread_cond_timedwait (&conn, &conn_mutex, + &ts); + } + } + pthread_mutex_unlock (&conn_mutex); + + + return ret; +} + +int32_t +cli_cmd_broadcast_connected () +{ + pthread_mutex_lock (&conn_mutex); + { + connected = 1; + pthread_cond_broadcast (&conn); + } + + pthread_mutex_unlock (&conn_mutex); return 0; } +int +cli_cmd_submit (void *req, call_frame_t *frame, + rpc_clnt_prog_t *prog, + int procnum, struct iobref *iobref, + xlator_t *this, fop_cbk_fn_t cbkfn, xdrproc_t xdrproc) +{ + int ret = -1; + unsigned timeout = 0; + + if ((GLUSTER_CLI_PROFILE_VOLUME == procnum) || + (GLUSTER_CLI_HEAL_VOLUME == procnum)) + timeout = CLI_TEN_MINUTES_TIMEOUT; + else + timeout = CLI_DEFAULT_CMD_TIMEOUT; + + cli_cmd_lock (); + cmd_sent = 0; + ret = cli_submit_request (req, frame, prog, + procnum, NULL, this, cbkfn, xdrproc); + + if (!ret) { + cmd_sent = 1; + ret = cli_cmd_await_response (timeout); + } + + cli_cmd_unlock (); + + gf_log ("cli", GF_LOG_DEBUG, "Returning %d", ret); + return ret; +} |
