summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c339
1 files changed, 339 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c
new file mode 100644
index 00000000000..83eeda30c81
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-svc-mgmt.c
@@ -0,0 +1,339 @@
+/*
+ Copyright (c) 2014 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 "globals.h"
+#include "run.h"
+#include "glusterd.h"
+#include "glusterfs.h"
+#include "glusterd-utils.h"
+#include "glusterd-svc-mgmt.h"
+#include "glusterd-proc-mgmt.h"
+#include "glusterd-conn-mgmt.h"
+#include "glusterd-messages.h"
+
+int
+glusterd_svc_create_rundir (char *rundir)
+{
+ int ret = -1;
+
+ ret = mkdir (rundir, 0777);
+ if ((ret == -1) && (EEXIST != errno)) {
+ gf_log (THIS->name, GF_LOG_ERROR, "Unable to create rundir %s",
+ rundir);
+ }
+ return ret;
+}
+
+static void
+glusterd_svc_build_logfile_path (char *server, char *logdir, char *logfile,
+ size_t len)
+{
+ snprintf (logfile, len, "%s/%s.log", logdir, server);
+}
+
+static void
+glusterd_svc_build_volfileid_path (char *server, char *volfileid, size_t len)
+{
+ snprintf (volfileid, len, "gluster/%s", server);
+}
+
+static int
+glusterd_svc_init_common (glusterd_svc_t *svc,
+ char *svc_name, char *workdir,
+ char *rundir, char *logdir,
+ glusterd_svc_manager_t manager,
+ glusterd_svc_start_t start,
+ glusterd_svc_stop_t stop,
+ glusterd_conn_notify_t notify)
+{
+ int ret = -1;
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ char pidfile[PATH_MAX] = {0,};
+ char logfile[PATH_MAX] = {0,};
+ char volfile[PATH_MAX] = {0,};
+ char sockfpath[PATH_MAX] = {0,};
+ char volfileid[256] = {0};
+ char *volfileserver = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ ret = snprintf (svc->name, sizeof (svc->name), "%s", svc_name);
+ if (ret < 0)
+ goto out;
+
+ svc->manager = manager;
+ svc->start = start;
+ svc->stop = stop;
+
+ if (!notify)
+ notify = glusterd_svc_common_rpc_notify;
+
+ glusterd_svc_create_rundir (rundir);
+
+ /* Initialize the connection mgmt */
+ glusterd_conn_build_socket_filepath (rundir, MY_UUID,
+ sockfpath, sizeof (sockfpath));
+
+ ret = glusterd_conn_init (&(svc->conn), sockfpath, 600, notify);
+ if (ret)
+ goto out;
+
+ /* Initialize the process mgmt */
+ glusterd_svc_build_pidfile_path (svc_name, workdir, pidfile,
+ sizeof(pidfile));
+ glusterd_svc_build_volfile_path (svc_name, workdir, volfile,
+ sizeof (volfile));
+
+ glusterd_svc_build_logfile_path (svc_name, logdir, logfile,
+ sizeof (logfile));
+ glusterd_svc_build_volfileid_path (svc_name, volfileid,
+ sizeof(volfileid));
+
+ if (dict_get_str (this->options, "transport.socket.bind-address",
+ &volfileserver) != 0) {
+ volfileserver = "localhost";
+ }
+
+ ret = glusterd_proc_init (&(svc->proc), svc_name, pidfile, logdir,
+ logfile, volfile, volfileid, volfileserver);
+ if (ret)
+ goto out;
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+ return ret;
+}
+
+
+static int
+svc_add_args (dict_t *cmdline, char *arg, data_t *value, void *data)
+{
+ runner_t *runner = data;
+ runner_add_arg (runner, value->data);
+ return 0;
+}
+
+int glusterd_svc_init (glusterd_svc_t *svc, char *svc_name,
+ glusterd_svc_manager_t manager,
+ glusterd_svc_start_t start,
+ glusterd_svc_stop_t stop)
+{
+ int ret = -1;
+ char rundir[PATH_MAX] = {0,};
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ glusterd_svc_build_rundir (svc_name, priv->workdir, rundir,
+ sizeof (rundir));
+ ret = glusterd_svc_init_common (svc, svc_name, priv->workdir, rundir,
+ DEFAULT_LOG_FILE_DIRECTORY, manager,
+ start, stop, NULL);
+
+ return ret;
+}
+
+int
+glusterd_svc_start (glusterd_svc_t *svc, int flags, dict_t *cmdline)
+{
+ int ret = -1;
+ runner_t runner = {0,};
+ glusterd_conf_t *priv = NULL;
+ xlator_t *this = NULL;
+ char valgrind_logfile[PATH_MAX] = {0};
+ char glusterd_uuid_option[1024] = {0};
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ if (glusterd_proc_is_running (&(svc->proc))) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = access (svc->proc.volfile, F_OK);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Volfile %s is not present",
+ svc->proc.volfile);
+ goto out;
+ }
+
+ runinit (&runner);
+
+ if (priv->valgrind) {
+ snprintf (valgrind_logfile, PATH_MAX, "%s/valgrind-%s.log",
+ svc->proc.logfile, svc->name);
+
+ runner_add_args (&runner, "valgrind", "--leak-check=full",
+ "--trace-children=yes", "--track-origins=yes",
+ NULL);
+ runner_argprintf (&runner, "--log-file=%s", valgrind_logfile);
+ }
+
+ runner_add_args (&runner, SBIN_DIR"/glusterfs",
+ "-s", svc->proc.volfileserver,
+ "--volfile-id", svc->proc.volfileid,
+ "-p", svc->proc.pidfile,
+ "-l", svc->proc.logfile,
+ "-S", svc->conn.sockpath,
+ NULL);
+
+ if (cmdline)
+ dict_foreach (cmdline, svc_add_args, (void *) &runner);
+
+ gf_log (this->name, GF_LOG_DEBUG, "Starting %s service", svc->name);
+
+ if (flags == PROC_START_NO_WAIT) {
+ ret = runner_run_nowait (&runner);
+ } else {
+ synclock_unlock (&priv->big_lock);
+ {
+ ret = runner_run (&runner);
+ }
+ synclock_lock (&priv->big_lock);
+ }
+
+out:
+ gf_log (this->name, GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+int glusterd_svc_stop (glusterd_svc_t *svc, int sig)
+{
+ int ret = -1;
+
+ ret = glusterd_proc_stop (&(svc->proc), sig, PROC_STOP_FORCE);
+ if (ret)
+ goto out;
+ glusterd_conn_disconnect (&(svc->conn));
+
+ if (ret == 0) {
+ svc->online = _gf_false;
+ (void) glusterd_unlink_file ((char *)svc->conn.sockpath);
+ }
+out:
+ gf_log (THIS->name, GF_LOG_DEBUG, "Returning %d", ret);
+
+ return ret;
+}
+
+void
+glusterd_svc_build_pidfile_path (char *server, char *workdir, char *path,
+ size_t len)
+{
+ char dir[PATH_MAX] = {0};
+
+ GF_ASSERT (len == PATH_MAX);
+
+ glusterd_svc_build_rundir (server, workdir, dir, sizeof (dir));
+ snprintf (path, len, "%s/%s.pid", dir, server);
+}
+
+void
+glusterd_svc_build_volfile_path (char *server, char *workdir, char *volfile,
+ size_t len)
+{
+ char dir[PATH_MAX] = {0,};
+
+ GF_ASSERT (len == PATH_MAX);
+
+ glusterd_svc_build_svcdir (server, workdir, dir, sizeof (dir));
+ snprintf (volfile, len, "%s/%s-server.vol", dir, server);
+}
+
+void
+glusterd_svc_build_svcdir (char *server, char *workdir, char *path, size_t len)
+{
+ GF_ASSERT (len == PATH_MAX);
+
+ snprintf (path, len, "%s/%s", workdir, server);
+}
+
+void
+glusterd_svc_build_rundir (char *server, char *workdir, char *path, size_t len)
+{
+ char dir[PATH_MAX] = {0};
+
+ GF_ASSERT (len == PATH_MAX);
+
+ glusterd_svc_build_svcdir (server, workdir, dir, sizeof (dir));
+ snprintf (path, len, "%s/run", dir);
+}
+
+int
+glusterd_svc_reconfigure (int (*create_volfile) ())
+{
+ int ret = -1;
+
+ ret = create_volfile ();
+ if (ret)
+ goto out;
+
+ ret = glusterd_fetchspec_notify (THIS);
+out:
+ return ret;
+}
+
+int
+glusterd_svc_common_rpc_notify (glusterd_conn_t *conn,
+ rpc_clnt_event_t event)
+{
+ int ret = 0;
+ glusterd_svc_t *svc = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ /* Get the parent onject i.e. svc using list_entry macro */
+ svc = list_entry (conn, glusterd_svc_t, conn);
+ if (!svc) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to get the service");
+ return -1;
+ }
+
+ switch (event) {
+ case RPC_CLNT_CONNECT:
+ gf_log (this->name, GF_LOG_DEBUG, "%s has connected with "
+ "glusterd.", svc->name);
+ svc->online = _gf_true;
+ break;
+
+ case RPC_CLNT_DISCONNECT:
+ if (svc->online) {
+ gf_msg (this->name, GF_LOG_INFO, 0,
+ GD_MSG_NODE_DISCONNECTED, "%s has disconnected "
+ "from glusterd.", svc->name);
+ svc->online = _gf_false;
+ }
+ break;
+
+ default:
+ gf_log (this->name, GF_LOG_TRACE,
+ "got some other RPC event %d", event);
+ break;
+ }
+
+ return ret;
+}