summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xtests/bugs/core/io-stats-1322825.t16
-rw-r--r--xlators/debug/io-stats/src/io-stats.c67
2 files changed, 59 insertions, 24 deletions
diff --git a/tests/bugs/core/io-stats-1322825.t b/tests/bugs/core/io-stats-1322825.t
new file mode 100755
index 00000000000..924251a432c
--- /dev/null
+++ b/tests/bugs/core/io-stats-1322825.t
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+. $(dirname $0)/../../include.rc
+
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 $H0:$B0/${V0} $H0:$B1/${V0}
+TEST $CLI volume start $V0
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0
+TEST "echo hello > $M0/file1"
+TEST setfattr -n trusted.io-stats-dump -v /tmp/io-stats.log $M0
+TEST ! getfattr -n trusted.io-stats-dump $B0/${V0}
+
+cleanup;
diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c
index 3a7f53da4ab..62e85bbb99b 100644
--- a/xlators/debug/io-stats/src/io-stats.c
+++ b/xlators/debug/io-stats/src/io-stats.c
@@ -2837,32 +2837,29 @@ conditional_dump (dict_t *dict, char *key, data_t *value, void *data)
memset (filename, 0, value->len + 1);
memcpy (filename, data_to_str (value), value->len);
- if (fnmatch ("*io*stat*dump", key, 0) == 0) {
- pid = getpid ();
+ pid = getpid ();
-
- if (!strncmp (filename, "", 1)) {
- gf_log (this->name, GF_LOG_ERROR, "No filename given");
- return -1;
- }
- logfp = fopen (filename, "w+");
- if (!logfp) {
- gf_log (this->name, GF_LOG_ERROR, "failed to open %s "
+ if (!strncmp (filename, "", 1)) {
+ gf_log (this->name, GF_LOG_ERROR, "No filename given");
+ return -1;
+ }
+ logfp = fopen (filename, "w+");
+ if (!logfp) {
+ gf_log (this->name, GF_LOG_ERROR, "failed to open %s "
"for writing", filename);
- return -1;
- }
- sprintf (dump_key, "*io*stat*%d_json_dump", pid);
- if (fnmatch (dump_key, key, 0) == 0) {
- (void) ios_dump_args_init (
- &args, IOS_DUMP_TYPE_JSON_FILE,
- logfp);
- } else {
- (void) ios_dump_args_init (&args, IOS_DUMP_TYPE_FILE,
- logfp);
- }
- io_stats_dump (this, &args, GF_CLI_INFO_ALL, _gf_false);
- fclose (logfp);
+ return -1;
+ }
+ sprintf (dump_key, "*io*stat*%d_json_dump", pid);
+ if (fnmatch (dump_key, key, 0) == 0) {
+ (void) ios_dump_args_init (
+ &args, IOS_DUMP_TYPE_JSON_FILE,
+ logfp);
+ } else {
+ (void) ios_dump_args_init (&args, IOS_DUMP_TYPE_FILE,
+ logfp);
}
+ io_stats_dump (this, &args, GF_CLI_INFO_ALL, _gf_false);
+ fclose (logfp);
return 0;
}
@@ -2992,11 +2989,23 @@ out:
return NULL;
}
+static gf_boolean_t
+match_special_xattr (dict_t *d, char *k, data_t *val, void *mdata)
+{
+ gf_boolean_t ret = _gf_false;
+ if (fnmatch ("*io*stat*dump", k, 0) == 0) {
+ ret = _gf_true;
+ }
+
+ return ret;
+}
+
int
io_stats_setxattr (call_frame_t *frame, xlator_t *this,
loc_t *loc, dict_t *dict,
int32_t flags, dict_t *xdata)
{
+ int ret = 0;
struct {
xlator_t *this;
inode_t *inode;
@@ -3007,7 +3016,13 @@ io_stats_setxattr (call_frame_t *frame, xlator_t *this,
stub.inode = loc->inode;
stub.path = loc->path;
- dict_foreach (dict, conditional_dump, &stub);
+ ret = dict_foreach_match (dict, match_special_xattr, NULL,
+ conditional_dump, &stub);
+ if (ret > 0) {
+ /* Setxattr was on key 'io-stat-dump', hence dump and unwind
+ * from here */
+ goto out;
+ }
START_FOP_LATENCY (frame);
@@ -3016,6 +3031,10 @@ io_stats_setxattr (call_frame_t *frame, xlator_t *this,
FIRST_CHILD(this)->fops->setxattr,
loc, dict, flags, xdata);
return 0;
+
+out:
+ STACK_UNWIND_STRICT (setxattr, frame, 0, 0, NULL);
+ return 0;
}