summaryrefslogtreecommitdiffstats
path: root/libglusterfs
diff options
context:
space:
mode:
authorRaghavendra Bhat <raghavendra@redhat.com>2012-09-06 18:20:39 +0530
committerVijay Bellur <vijay@gluster.com>2012-09-07 10:44:34 +0530
commit7ed72a4fd16c54ed8fd49dff7db5ac1c15311414 (patch)
treef5b91ba332d55b388a4e5e7ef99d31964ff85f25 /libglusterfs
parentae9ea44760e5a5f3bba0f19072e3f654a52be9f2 (diff)
core/statedump: statedump enahancements
* append timestamp to the statedump filename to prevent old files getting over written * Add start and end markers to statedump to indicate beginning and finishing of statedump information * Make glusterfs take options through /tmp/glusterdump.options file and treating those options with higher prioriry * do not dump the entire inode table in the statedump. Instead just dump the ltable and the fdtable Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
Diffstat (limited to 'libglusterfs')
-rw-r--r--libglusterfs/src/fd.c7
-rw-r--r--libglusterfs/src/statedump.c182
-rw-r--r--libglusterfs/src/statedump.h9
3 files changed, 172 insertions, 26 deletions
diff --git a/libglusterfs/src/fd.c b/libglusterfs/src/fd.c
index b0b75a5ad3e..aafda5ecc27 100644
--- a/libglusterfs/src/fd.c
+++ b/libglusterfs/src/fd.c
@@ -960,6 +960,13 @@ fd_dump (fd_t *fd, char *prefix)
gf_proc_dump_write("pid", "%llu", fd->pid);
gf_proc_dump_write("refcount", "%d", fd->refcount);
gf_proc_dump_write("flags", "%d", fd->flags);
+
+ if (fd->inode) {
+ gf_proc_dump_build_key (key, "inode", NULL);
+ gf_proc_dump_add_section(key);
+ inode_dump (fd->inode, key);
+ }
+
}
diff --git a/libglusterfs/src/statedump.c b/libglusterfs/src/statedump.c
index 899d8ef2b1b..8e0b7aeca24 100644
--- a/libglusterfs/src/statedump.c
+++ b/libglusterfs/src/statedump.c
@@ -60,8 +60,9 @@ gf_proc_dump_open (char *dump_dir, char *brickname)
char path[PATH_MAX] = {0,};
int dump_fd = -1;
- snprintf (path, sizeof (path), "%s/%s.%d.dump", (dump_dir ?
- dump_dir : "/tmp"), brickname, getpid());
+ snprintf (path, sizeof (path), "%s/%s.%d.dump.%"PRIu64,
+ (dump_dir ? dump_dir : "/tmp"), brickname, getpid(),
+ (uint64_t) time (NULL));
dump_fd = open (path, O_CREAT|O_RDWR|O_TRUNC|O_APPEND, 0600);
if (dump_fd < 0)
@@ -79,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, ...)
@@ -395,8 +435,6 @@ gf_proc_dump_xlator_info (xlator_t *top)
(trav->itable)) {
snprintf (itable_key, 1024, "%d.%s.itable",
ctx->graph_id, trav->name);
-
- inode_table_dump (trav->itable, itable_key);
}
if (!trav->dumpops) {
@@ -430,24 +468,20 @@ static void
gf_proc_dump_oldgraph_xlator_info (xlator_t *top)
{
xlator_t *trav = NULL;
- glusterfs_ctx_t *ctx = NULL;
- char itable_key[1024] = {0,};
if (!top)
return;
- ctx = glusterfs_ctx_get ();
-
trav = top;
while (trav) {
gf_proc_dump_xlator_mem_info_only_in_use (trav);
if (GF_PROC_DUMP_IS_XL_OPTION_ENABLED (inode) &&
(trav->itable)) {
- snprintf (itable_key, 1024, "%d.%s.itable",
- ctx->graph_id, trav->name);
-
- inode_table_dump (trav->itable, itable_key);
+ /*TODO: dump inode table info if necessary by
+ printing the graph id (taken by glusterfs_cbtx_t)
+ in the key
+ */
}
if (!trav->dumpops) {
@@ -488,6 +522,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 ()
{
@@ -566,28 +638,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);
@@ -601,13 +688,15 @@ 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;
}
@@ -619,6 +708,9 @@ gf_proc_dump_info (int signum)
glusterfs_ctx_t *ctx = NULL;
glusterfs_graph_t *trav = NULL;
char brick_name[PATH_MAX] = {0,};
+ struct timeval tv = {0,};
+ char timestr[256] = {0,};
+ char sign_string[512] = {0,};
gf_proc_dump_lock ();
@@ -631,14 +723,37 @@ gf_proc_dump_info (int signum)
} 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;
+ //continue even though gettimeofday() has failed
+ ret = gettimeofday (&tv, NULL);
+ if (0 == ret) {
+ strftime (timestr, sizeof timestr, "%Y-%m-%d %H:%M:%S",
+ localtime (&tv.tv_sec));
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, tv.tv_usec);
+ }
+
+ snprintf (sign_string, sizeof (sign_string), "DUMP-START-TIME: %s\n",
+ timestr);
+
+ //swallow the errors of write for start and end marker
+ ret = write (gf_dump_fd, sign_string, strlen (sign_string));
+
+ memset (sign_string, 0, sizeof (sign_string));
+ memset (timestr, 0, sizeof (timestr));
+ memset (&tv, 0, sizeof (tv));
+
if (GF_PROC_DUMP_IS_OPTION_ENABLED (mem)) {
gf_proc_dump_mem_info ();
gf_proc_dump_mempool_info (ctx);
@@ -670,9 +785,24 @@ gf_proc_dump_info (int signum)
i++;
}
+ ret = gettimeofday (&tv, NULL);
+ if (0 == ret) {
+ strftime (timestr, sizeof timestr, "%Y-%m-%d %H:%M:%s",
+ localtime (&tv.tv_sec));
+ snprintf (timestr + strlen (timestr),
+ sizeof timestr - strlen (timestr),
+ ".%"GF_PRI_SUSECONDS, tv.tv_usec);
+ }
+
+ snprintf (sign_string, sizeof (sign_string), "\nDUMP-END-TIME: %s",
+ timestr);
+ ret = write (gf_dump_fd, sign_string, strlen (sign_string));
+
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;
diff --git a/libglusterfs/src/statedump.h b/libglusterfs/src/statedump.h
index dc56bda0cbb..e8d304e66d4 100644
--- a/libglusterfs/src/statedump.h
+++ b/libglusterfs/src/statedump.h
@@ -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);