core/statedump: parse the file and set the path of the statedump files

* As of now "gluster volume set statedump-path" option sets the path of
  the statedump files for brick processes only. If SIGUSR1 is sent directly
  to all the gluster processes instead of using gluster cli command, then
  some of the statedumps will still be in /tmp (such as nfs server, glustershd).

* This patch makes glusterfs processes search for the file
  /tmp/glusterdump.options and consider the options given in it. There if path
  key is set, then all the processes use that path when SIGUSR1 is sent or cli
  statedump command is executed. (Note that after taking statedump, if
  /tmp/glusterdump.options file is removed, then the default way is resumed).

Change-Id: I2e8fbfb4823318512e03b234e90d3a3888724ddc
BUG: 851175
Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
Reviewed-on: http://review.gluster.org/3907
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
This commit is contained in:
Raghavendra Bhat 2012-09-05 13:07:49 +05:30 committed by Vijay Bellur
parent d6c99b6134
commit be1d21a879
2 changed files with 119 additions and 15 deletions

View File

@ -80,6 +80,45 @@ gf_proc_dump_close (void)
gf_dump_fd = -1;
}
static int
gf_proc_dump_set_path (char *dump_options_file)
{
int ret = -1;
FILE *fp = NULL;
char buf[256];
char *key = NULL, *value = NULL;
char *saveptr = NULL;
fp = fopen (dump_options_file, "r");
if (!fp)
goto out;
ret = fscanf (fp, "%s", buf);
while (ret != EOF) {
key = strtok_r (buf, "=", &saveptr);
if (!key) {
ret = fscanf (fp, "%s", buf);
continue;
}
value = strtok_r (NULL, "=", &saveptr);
if (!value) {
ret = fscanf (fp, "%s", buf);
continue;
}
if (!strcmp (key, "path")) {
dump_options.dump_path = gf_strdup (value);
break;
}
}
out:
if (fp)
fclose (fp);
return ret;
}
int
gf_proc_dump_add_section (char *key, ...)
@ -489,6 +528,44 @@ gf_proc_dump_enable_all_options ()
return 0;
}
gf_boolean_t
is_gf_proc_dump_all_disabled ()
{
gf_boolean_t all_disabled = _gf_true;
GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_mem, all_disabled, out);
GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_iobuf, all_disabled, out);
GF_CHECK_DUMP_OPTION_ENABLED (dump_options.dump_callpool, all_disabled,
out);
GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_priv,
all_disabled, out);
GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_inode,
all_disabled, out);
GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_fd,
all_disabled, out);
GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_inodectx,
all_disabled, out);
GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_fdctx,
all_disabled, out);
GF_CHECK_DUMP_OPTION_ENABLED (dump_options.xl_options.dump_history,
all_disabled, out);
out:
return all_disabled;
}
/* These options are dumped by default if /tmp/glusterdump.options
file exists and it is emtpty
*/
static int
gf_proc_dump_enable_default_options ()
{
GF_PROC_DUMP_SET_OPTION (dump_options.dump_mem, _gf_true);
GF_PROC_DUMP_SET_OPTION (dump_options.dump_callpool, _gf_true);
return 0;
}
static int
gf_proc_dump_disable_all_options ()
{
@ -567,28 +644,43 @@ gf_proc_dump_options_init ()
int ret = -1;
FILE *fp = NULL;
char buf[256];
char dumpbuf[GF_DUMP_MAX_BUF_LEN];
char *key = NULL, *value = NULL;
char *saveptr = NULL;
char dump_option_file[PATH_MAX];
/* glusterd will create a file /tmp/glusterdump.<pid>.options and
sets the statedump options for the process and the file is removed
after the statedump is taken. Direct issue of SIGUSR1 does not have
mechanism for considering the statedump options. So to have a way
of configuring the statedump of all the glusterfs processes through
both cli command and SIGUSR1, /tmp/glusterdump.options file
is searched and the options mentioned in it are given the higher
priority.
*/
snprintf (dump_option_file, sizeof (dump_option_file),
"/tmp/glusterdump.%d.options", getpid ());
"/tmp/glusterdump.options");
fp = fopen (dump_option_file, "r");
if (!fp) {
//ENOENT, return success
(void) gf_proc_dump_enable_all_options ();
return 0;
snprintf (dump_option_file, sizeof (dump_option_file),
"/tmp/glusterdump.%d.options", getpid ());
fp = fopen (dump_option_file, "r");
if (!fp) {
//ENOENT, return success
(void) gf_proc_dump_enable_all_options ();
return 0;
}
}
(void) gf_proc_dump_disable_all_options ();
// swallow the errors if setting statedump file path is failed.
ret = gf_proc_dump_set_path (dump_option_file);
ret = fscanf (fp, "%s", buf);
while (ret != EOF) {
key = strtok_r (buf, "=", &saveptr);
if (!key) {
ret = fscanf (fp, "%s", buf);
@ -602,20 +694,18 @@ gf_proc_dump_options_init ()
continue;
}
snprintf (dumpbuf, sizeof (dumpbuf), "[Debug]:key=%s, value=%s\n",key,value);
ret = write (gf_dump_fd, dumpbuf, strlen (dumpbuf));
gf_proc_dump_parse_set_option (key, value);
}
if (is_gf_proc_dump_all_disabled ())
(void) gf_proc_dump_enable_default_options ();
if (fp)
fclose (fp);
return 0;
}
void
gf_proc_dump_info (int signum, glusterfs_ctx_t *ctx)
{
@ -637,11 +727,14 @@ gf_proc_dump_info (int signum, glusterfs_ctx_t *ctx)
} else
strncpy (brick_name, "glusterdump", sizeof (brick_name));
ret = gf_proc_dump_open (ctx->statedump_path, brick_name);
ret = gf_proc_dump_options_init ();
if (ret < 0)
goto out;
ret = gf_proc_dump_options_init ();
if (dump_options.dump_path)
ret = gf_proc_dump_open (dump_options.dump_path, brick_name);
else
ret = gf_proc_dump_open (ctx->statedump_path, brick_name);
if (ret < 0)
goto out;
@ -710,6 +803,8 @@ gf_proc_dump_info (int signum, glusterfs_ctx_t *ctx)
out:
if (gf_dump_fd != -1)
gf_proc_dump_close ();
GF_FREE (dump_options.dump_path);
dump_options.dump_path = NULL;
gf_proc_dump_unlock ();
return;

View File

@ -31,6 +31,7 @@ typedef struct gf_dump_options_ {
gf_boolean_t dump_iobuf;
gf_boolean_t dump_callpool;
gf_dump_xl_options_t xl_options; //options for all xlators
char *dump_path;
} gf_dump_options_t;
extern gf_dump_options_t dump_options;
@ -55,6 +56,14 @@ void _gf_proc_dump_build_key (char *key, const char *prefix, char *fmt,...)
#define GF_PROC_DUMP_SET_OPTION(opt,val) opt = val
#define GF_CHECK_DUMP_OPTION_ENABLED(option_dump, var, label) \
do { \
if (option_dump == _gf_true) { \
var = _gf_false; \
goto label; \
} \
} while (0);
void gf_proc_dump_init();
void gf_proc_dump_fini(void);