summaryrefslogtreecommitdiffstats
path: root/xlators/mgmt/glusterd/src/glusterd-ganesha.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/mgmt/glusterd/src/glusterd-ganesha.c')
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-ganesha.c365
1 files changed, 365 insertions, 0 deletions
diff --git a/xlators/mgmt/glusterd/src/glusterd-ganesha.c b/xlators/mgmt/glusterd/src/glusterd-ganesha.c
new file mode 100644
index 00000000000..267e4b995cd
--- /dev/null
+++ b/xlators/mgmt/glusterd/src/glusterd-ganesha.c
@@ -0,0 +1,365 @@
+/*
+ Copyright (c) 2015 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.
+*/
+
+
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+#include "config.h"
+#endif
+
+#include "common-utils.h"
+#include "glusterd.h"
+#include "glusterd-op-sm.h"
+#include "glusterd-store.h"
+#include "glusterd-utils.h"
+#include "glusterd-nfs-svc.h"
+#define MAXBUF 1024
+#define DELIM "=\""
+
+/* Following 2 functions parses GANESHA_HA_CONF
+ * The sample file looks like below,
+ * HA_NAME="ganesha-ha-360"
+ * HA_VOL_NAME="ha-state"
+ * HA_VOL_MNT="/mount-point"
+ * HA_VOL_SERVER="server1"
+ * HA_CLUSTER_NODES="server1,server2"
+ * VIP_rhs_1="10.x.x.x"
+ * VIP_rhs_2="10.x.x.x." */
+
+gf_boolean_t
+is_ganesha_host (void)
+{
+ char *host_from_file = NULL;
+ FILE *fp;
+ char line[MAXBUF];
+ gf_boolean_t ret = _gf_false;
+ int i = 1;
+ xlator_t *this = NULL;
+
+ this = THIS;
+
+ fp = fopen (GANESHA_HA_CONF, "r");
+
+ if (fp == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "couldn't open the file %s",
+ GANESHA_HA_CONF);
+ return _gf_false;
+ }
+
+ while (fgets (line, sizeof(line), fp) != NULL) {
+ /* Read GANESHA_HA_CONFIG till we find the HA VOL server */
+ host_from_file = strstr ((char *)line, "HA_VOL_SERVER");
+ if (host_from_file != NULL) {
+ host_from_file = strstr (host_from_file, DELIM);
+ host_from_file = host_from_file + strlen(DELIM);
+ i = strlen(host_from_file);
+ host_from_file[i - 2] = '\0';
+ break;
+ }
+ }
+
+ ret = gf_is_local_addr (host_from_file);
+ if (ret) {
+ gf_log (this->name, GF_LOG_INFO, "ganesha host found "
+ "Hostname is %s", host_from_file);
+ }
+
+ fclose (fp);
+ return ret;
+}
+
+/* Check if the localhost is listed as one of nfs-ganesha nodes */
+gf_boolean_t
+check_host_list (void)
+{
+
+ char *host_from_file = NULL;
+ glusterd_conf_t *priv = NULL;
+ char *hostname = NULL;
+ FILE *fp;
+ char line[MAXBUF];
+ int ret = _gf_false;
+ int i = 1;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ fp = fopen (GANESHA_HA_CONF, "r");
+
+ if (fp == NULL) {
+ gf_log (this->name, GF_LOG_INFO, "couldn't open the file %s",
+ GANESHA_HA_CONF);
+ return 0;
+ }
+
+ while (fgets (line, sizeof(line), fp) != NULL) {
+ /* Read GANESHA_HA_CONFIG till we find the list of HA_CLUSTER_NODES */
+ hostname = strstr ((char *)line, "HA_CLUSTER_NODES");
+ if (hostname != NULL) {
+ hostname = strstr (hostname, DELIM);
+ hostname = hostname + strlen(DELIM);
+ i = strlen (hostname);
+ hostname[i - 2] = '\0';
+ break;
+ }
+ }
+
+ /* Hostname is a comma separated list now */
+ hostname = strtok (hostname, ",");
+ while (hostname != NULL) {
+ ret = gf_is_local_addr (hostname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_INFO, "ganesha host found "
+ "Hostname is %s", hostname);
+ break;
+ }
+ hostname = strtok (NULL, ",");
+ }
+
+ fclose (fp);
+ return ret;
+
+}
+
+int
+create_export_config (char *volname, char **op_errstr)
+{
+ runner_t runner = {0,};
+ int ret = -1;
+
+ GF_ASSERT(volname);
+ runinit (&runner);
+ runner_add_args (&runner, "sh",
+ GANESHA_PREFIX"/create-export-ganesha.sh",
+ CONFDIR, volname, NULL);
+ ret = runner_run(&runner);
+
+ if (ret)
+ gf_asprintf (op_errstr, "Failed to create"
+ " NFS-Ganesha export config file.");
+
+ return ret;
+}
+
+int
+ganesha_manage_export (dict_t *dict, char *value, char **op_errstr)
+{
+ runner_t runner = {0,};
+ int ret = -1;
+ char str[1024];
+ glusterd_volinfo_t *volinfo = NULL;
+ char *volname = NULL;
+ xlator_t *this = NULL;
+ int i = 1;
+
+ runinit (&runner);
+ this = THIS;
+
+ GF_ASSERT (value);
+ GF_ASSERT (dict);
+
+ ret = dict_get_str (dict, "volname", &volname);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ "Unable to get volume name");
+ goto out;
+ }
+
+ ret = glusterd_volinfo_find (volname, &volinfo);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR,
+ FMTSTR_CHECK_VOL_EXISTS, volname);
+ goto out;
+ }
+
+ /* Create the export file only when ganesha.enable "on" is executed */
+ if (strcmp (value, "on") == 0) {
+ ret = create_export_config (volname, op_errstr);
+ if (ret) {
+ gf_log (this->name, GF_LOG_ERROR, "Failed to create"
+ "export file for NFS-Ganesha\n");
+ goto out;
+ }
+ }
+
+ if (check_host_list()) {
+ runner_add_args (&runner, "sh", GANESHA_PREFIX"/dbus-send.sh",
+ CONFDIR, value, volname, NULL);
+ ret = runner_run (&runner);
+ if (ret)
+ gf_asprintf(op_errstr, "Dynamic export"
+ " addition/deletion failed."
+ "Please see log file for details");
+ }
+out:
+ return ret;
+}
+
+int
+tear_down_cluster(void)
+{
+ int ret = 0;
+ runner_t runner = {0,};
+
+ if (is_ganesha_host()) {
+ runinit (&runner);
+ runner_add_args (&runner, "sh", CONFDIR,
+ GANESHA_PREFIX"/ganesha-ha.sh", "teardown",
+ CONFDIR, NULL);
+ ret = runner_run(&runner);
+ }
+ return ret;
+}
+
+
+int
+setup_cluster(void)
+{
+ int ret = 0;
+ runner_t runner = {0,};
+
+ if (is_ganesha_host()) {
+ runinit (&runner);
+ runner_add_args (&runner, "sh", GANESHA_PREFIX"/ganesha-ha.sh",
+ "setup", CONFDIR, NULL);
+ ret = runner_run (&runner);
+ }
+ return ret;
+}
+
+
+int
+stop_ganesha (char **op_errstr)
+{
+ runner_t runner = {0,};
+ int ret = 1;
+
+ ret = tear_down_cluster();
+ if (ret == -1) {
+ gf_asprintf (op_errstr, "Cleanup of NFS-Ganesha"
+ "HA config failed.");
+ goto out;
+ }
+
+ if (check_host_list ()) {
+ runinit (&runner);
+ runner_add_args (&runner, "service nfs-ganesha", "stop", NULL);
+ ret = runner_run (&runner);
+ }
+out:
+ return ret;
+}
+
+int
+start_ganesha (char **op_errstr)
+{
+
+ runner_t runner = {0,};
+ int ret = -1;
+ char key[1024] = {0,};
+ char *hostname = NULL;
+ dict_t *vol_opts = NULL;
+ glusterd_volinfo_t *volinfo = NULL;
+ int count = 0;
+ char *volname = NULL;
+ glusterd_conf_t *priv = NULL;
+
+ priv = THIS->private;
+ GF_ASSERT (priv);
+
+ cds_list_for_each_entry (volinfo, &priv->volumes, vol_list) {
+ vol_opts = volinfo->dict;
+ /* Gluster-nfs has to be disabled across the trusted pool */
+ /* before attempting to start nfs-ganesha */
+ ret = dict_set_str (vol_opts, "nfs.disable", "on");
+ if (ret)
+ goto out;
+ }
+
+ ret = priv->nfs_svc.stop (&(priv->nfs_svc), SIGKILL);
+ if (ret) {
+ ret = -1;
+ gf_asprintf (op_errstr, "Gluster-NFS service could"
+ "not be stopped, exiting.");
+ goto out;
+ }
+
+ if (check_host_list()) {
+ runinit(&runner);
+ runner_add_args (&runner, "service",
+ "nfs-ganesha", "start", NULL);
+
+ ret = runner_run (&runner);
+ if (ret) {
+ gf_asprintf (op_errstr, "NFS-Ganesha failed to start."
+ "Please see log file for details");
+ goto out;
+ }
+
+ ret = setup_cluster();
+ if (ret == -1) {
+ gf_asprintf (op_errstr, "Failed to set up HA "
+ "config for NFS-Ganesha."
+ "Please check the log file for details");
+ goto out;
+ }
+ }
+
+out:
+ return ret;
+}
+
+int
+glusterd_handle_ganesha_op (dict_t *dict, char **op_errstr,
+ char *key, char *value)
+{
+
+ int32_t ret = -1;
+ char *volname = NULL;
+ xlator_t *this = NULL;
+ static int export_id = 1;
+ glusterd_volinfo_t *volinfo = NULL;
+ char *option = NULL;
+
+ GF_ASSERT (dict);
+ GF_ASSERT (op_errstr);
+ GF_ASSERT (key);
+ GF_ASSERT (value);
+
+ /* TODO: enable only if global option is set */
+ /* BUG ID : 1200265 */
+
+ if (strcmp (key, "ganesha.enable") == 0) {
+ ret = ganesha_manage_export(dict, value, op_errstr);
+ if (ret < 0)
+ goto out;
+ }
+
+ if (strcmp (key, "features.ganesha") == 0) {
+ if (strcmp (value, "enable") == 0) {
+ ret = start_ganesha(op_errstr);
+ if (ret < 0)
+ goto out;
+ }
+
+ else if (strcmp (value, "disable") == 0) {
+ ret = stop_ganesha (op_errstr);
+ if (ret < 0)
+ goto out;
+ }
+ }
+
+out:
+ return ret;
+}
+