summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendrabhat@gluster.com>2012-01-04 00:08:14 +0530
committerVijay Bellur <vijay@gluster.com>2012-01-27 04:23:41 -0800
commite99cb60af1e153efd616014da6a54d2f95c119d1 (patch)
treebf6e3e92ae6d200b72fd41e0ee7fed0ff720c431
parent5a8c58cf6e6c993c8665a31e6f108744ca27ccf4 (diff)
glusterd: provide option to take statedump of the nfs server
Currently the cli command for taking statedump is for glusterfs servers only. Statedump of nfs server cannot be taken. With this patch if one gives nfs as an option to the statedump command, then the nfs-server's statedump is taken. Change-Id: I4ef7a68e608da4aa2f17541d7b42cd78ce2624b6 BUG: 771587 Signed-off-by: Raghavendra Bhat <raghavendrabhat@gluster.com> Reviewed-on: http://review.gluster.com/2579 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Amar Tumballi <amar@gluster.com> Reviewed-by: Vijay Bellur <vijay@gluster.com>
-rw-r--r--cli/src/cli-cmd-parser.c5
-rw-r--r--cli/src/cli-cmd-volume.c3
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-op-sm.c2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c104
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h5
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-ops.c16
-rw-r--r--xlators/mgmt/glusterd/src/glusterd.h10
7 files changed, 129 insertions, 16 deletions
diff --git a/cli/src/cli-cmd-parser.c b/cli/src/cli-cmd-parser.c
index afd668ea2d2..ef69235d673 100644
--- a/cli/src/cli-cmd-parser.c
+++ b/cli/src/cli-cmd-parser.c
@@ -1934,8 +1934,8 @@ cli_cmd_volume_status_parse (const char **words, int wordcount,
gf_boolean_t
cli_cmd_validate_dumpoption (const char *option)
{
- char *opwords[] = {"all", "mem", "iobuf", "callpool", "priv", "fd",
- "inode", NULL};
+ char *opwords[] = {"all", "nfs", "mem", "iobuf", "callpool", "priv",
+ "fd", "inode", NULL};
char *w = NULL;
w = str_getunamb (option, opwords);
@@ -1965,6 +1965,7 @@ cli_cmd_volume_statedump_options_parse (const char **words, int wordcount,
strncat (option_str, words[i], sizeof (words [i]));
strncat (option_str, " ", 1);
}
+
dict = dict_new ();
if (!dict)
goto out;
diff --git a/cli/src/cli-cmd-volume.c b/cli/src/cli-cmd-volume.c
index 0168628dd0d..521e3eb84f7 100644
--- a/cli/src/cli-cmd-volume.c
+++ b/cli/src/cli-cmd-volume.c
@@ -1749,7 +1749,8 @@ struct cli_cmd volume_cmds[] = {
cli_cmd_volume_heal_cbk,
"Start healing of volume specified by <VOLNAME>"},
- {"volume statedump <VOLNAME> [all|mem|iobuf|callpool|priv|fd|inode]...",
+ {"volume statedump <VOLNAME> [nfs] [all|mem|iobuf|callpool|priv|fd|"
+ "inode]...",
cli_cmd_volume_statedump_cbk,
"perform statedump on bricks"},
diff --git a/xlators/mgmt/glusterd/src/glusterd-op-sm.c b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
index 38d73b1f737..f24cb9b1332 100644
--- a/xlators/mgmt/glusterd/src/glusterd-op-sm.c
+++ b/xlators/mgmt/glusterd/src/glusterd-op-sm.c
@@ -2459,7 +2459,7 @@ glusterd_op_commit_perform (glusterd_op_t op, dict_t *dict, char **op_errstr,
break;
case GD_OP_STATEDUMP_VOLUME:
- ret = glusterd_op_statedump_volume (dict);
+ ret = glusterd_op_statedump_volume (dict, op_errstr);
break;
default:
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index efc7069d8d4..c0462d9c779 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -4532,13 +4532,15 @@ int
glusterd_set_dump_options (char *dumpoptions_path, char *options,
int option_cnt)
{
- int ret = -1;
+ int ret = 0;
char *dup_options = NULL;
char *option = NULL;
char *tmpptr = NULL;
FILE *fp = NULL;
+ int nfs_cnt = 0;
- if (0 == option_cnt) {
+ if (0 == option_cnt ||
+ (option_cnt == 1 && (!strcmp (options, "nfs ")))) {
ret = 0;
goto out;
}
@@ -4553,6 +4555,16 @@ glusterd_set_dump_options (char *dumpoptions_path, char *options,
dup_options);
option = strtok_r (dup_options, " ", &tmpptr);
while (option) {
+ if (!strcmp (option, "nfs")) {
+ if (nfs_cnt > 0) {
+ unlink (dumpoptions_path);
+ ret = 0;
+ goto out;
+ }
+ nfs_cnt++;
+ option = strtok_r (NULL, " ", &tmpptr);
+ continue;
+ }
fprintf (fp, "%s=yes\n", option);
option = strtok_r (NULL, " ", &tmpptr);
}
@@ -4560,13 +4572,15 @@ glusterd_set_dump_options (char *dumpoptions_path, char *options,
out:
if (fp)
fclose (fp);
+ if (dup_options)
+ GF_FREE (dup_options);
return ret;
}
int
glusterd_brick_statedump (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo,
- char *options, int option_cnt)
+ char *options, int option_cnt, char **op_errstr)
{
int ret = -1;
xlator_t *this = NULL;
@@ -4618,8 +4632,13 @@ glusterd_brick_statedump (glusterd_volinfo_t *volinfo,
snprintf (dumpoptions_path, sizeof (dumpoptions_path),
"/tmp/glusterdump.%d.options", pid);
- glusterd_set_dump_options (dumpoptions_path, options, option_cnt);
-
+ ret = glusterd_set_dump_options (dumpoptions_path, options, option_cnt);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_ERROR, "error while parsing the statedump "
+ "options");
+ ret = -1;
+ goto out;
+ }
gf_log ("", GF_LOG_INFO, "Performing statedump on brick with pid %d",
pid);
@@ -4627,12 +4646,87 @@ glusterd_brick_statedump (glusterd_volinfo_t *volinfo,
kill (pid, SIGUSR1);
sleep (1);
+ ret = 0;
+out:
unlink (dumpoptions_path);
+ if (pidfile)
+ fclose (pidfile);
+ return ret;
+}
+
+int
+glusterd_nfs_statedump (char *options, int option_cnt, char **op_errstr)
+{
+ int ret = -1;
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+ char pidfile_path[PATH_MAX] = {0,};
+ char path[PATH_MAX] = {0,};
+ FILE *pidfile = NULL;
+ pid_t pid = -1;
+ char dumpoptions_path[PATH_MAX] = {0,};
+ char *option = NULL;
+ char *tmpptr = NULL;
+ char *dup_options = NULL;
+ char msg[256] = {0,};
+
+ this = THIS;
+ GF_ASSERT (this);
+ conf = this->private;
+ GF_ASSERT (conf);
+
+ dup_options = gf_strdup (options);
+ option = strtok_r (dup_options, " ", &tmpptr);
+ if (strcmp (option, "nfs")) {
+ snprintf (msg, sizeof (msg), "for nfs statedump, options should"
+ " be after the key nfs");
+ *op_errstr = gf_strdup (msg);
+ ret = -1;
+ goto out;
+ }
+
+ GLUSTERD_GET_NFS_DIR (path, conf);
+ GLUSTERD_GET_NFS_PIDFILE (pidfile_path, path);
+
+ pidfile = fopen (pidfile_path, "r");
+ if (!pidfile) {
+ gf_log ("", GF_LOG_ERROR, "Unable to open pidfile: %s",
+ pidfile_path);
+ ret = -1;
+ goto out;
+ }
+
+ ret = fscanf (pidfile, "%d", &pid);
+ if (ret <= 0) {
+ gf_log ("", GF_LOG_ERROR, "Unable to get pid of brick process");
+ ret = -1;
+ goto out;
+ }
+
+ snprintf (dumpoptions_path, sizeof (dumpoptions_path),
+ "/tmp/glusterdump.%d.options", pid);
+ ret = glusterd_set_dump_options (dumpoptions_path, options, option_cnt);
+ if (ret < 0) {
+ gf_log ("", GF_LOG_ERROR, "error while parsing the statedump "
+ "options");
+ ret = -1;
+ goto out;
+ }
+
+ gf_log ("", GF_LOG_INFO, "Performing statedump on nfs server with "
+ "pid %d", pid);
+
+ kill (pid, SIGUSR1);
+
+ sleep (1);
ret = 0;
out:
if (pidfile)
fclose (pidfile);
+ unlink (dumpoptions_path);
+ if (dup_options)
+ GF_FREE (dup_options);
return ret;
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 13ac026018f..ba1b8f67805 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -372,8 +372,9 @@ glusterd_is_fuse_available ();
int
glusterd_brick_statedump (glusterd_volinfo_t *volinfo,
glusterd_brickinfo_t *brickinfo,
- char *options, int option_cnt);
-
+ char *options, int option_cnt, char **op_errstr);
+int
+glusterd_nfs_statedump (char *options, int option_cnt, char **op_errstr);
gf_boolean_t
glusterd_is_volume_replicate (glusterd_volinfo_t *volinfo);
gf_boolean_t
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
index e3971a2763c..1389f78f9d4 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-ops.c
@@ -1383,7 +1383,7 @@ glusterd_op_heal_volume (dict_t *dict, char **op_errstr)
}
int
-glusterd_op_statedump_volume (dict_t *dict)
+glusterd_op_statedump_volume (dict_t *dict, char **op_errstr)
{
int ret = 0;
char *volname = NULL;
@@ -1401,11 +1401,19 @@ glusterd_op_statedump_volume (dict_t *dict)
if (ret)
goto out;
gf_log ("", GF_LOG_DEBUG, "Performing statedump on volume %s", volname);
- list_for_each_entry (brickinfo, &volinfo->bricks, brick_list) {
- ret = glusterd_brick_statedump (volinfo, brickinfo, options,
- option_cnt);
+ if (strstr (options, "nfs") != NULL) {
+ ret = glusterd_nfs_statedump (options, option_cnt, op_errstr);
if (ret)
goto out;
+ } else {
+ list_for_each_entry (brickinfo, &volinfo->bricks,
+ brick_list) {
+ ret = glusterd_brick_statedump (volinfo, brickinfo,
+ options, option_cnt,
+ op_errstr);
+ if (ret)
+ goto out;
+ }
}
out:
diff --git a/xlators/mgmt/glusterd/src/glusterd.h b/xlators/mgmt/glusterd/src/glusterd.h
index 7cd34a00892..fe2402ec26b 100644
--- a/xlators/mgmt/glusterd/src/glusterd.h
+++ b/xlators/mgmt/glusterd/src/glusterd.h
@@ -284,6 +284,9 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
GLUSTERD_VOLUME_DIR_PREFIX, volinfo->volname, \
GLUSTERD_BRICK_INFO_DIR);
+#define GLUSTERD_GET_NFS_DIR(path, priv) \
+ snprintf (path, PATH_MAX, "%s/nfs", priv->workdir);
+
#define GLUSTERD_REMOVE_SLASH_FROM_PATH(path,string) do { \
int i = 0; \
for (i = 1; i < strlen (path); i++) { \
@@ -300,6 +303,11 @@ typedef ssize_t (*gd_serialize_t) (struct iovec outmsg, void *args);
volpath, hostname, exp_path); \
}
+#define GLUSTERD_GET_NFS_PIDFILE(pidfile,nfspath) { \
+ snprintf (pidfile, PATH_MAX, "%s/run/nfs.pid", \
+ nfspath); \
+ }
+
#define GLUSTERD_STACK_DESTROY(frame) do {\
frame->local = NULL; \
STACK_DESTROY (frame->root);\
@@ -565,7 +573,7 @@ int glusterd_op_stage_rebalance (dict_t *dict, char **op_errstr);
int glusterd_op_rebalance (dict_t *dict, char **op_errstr, dict_t *rsp_dict);
int glusterd_op_stage_statedump_volume (dict_t *dict, char **op_errstr);
-int glusterd_op_statedump_volume (dict_t *dict);
+int glusterd_op_statedump_volume (dict_t *dict, char **op_errstr);
/* misc */
void glusterd_do_replace_brick (void *data);