diff options
author | N Balachandran <nbalacha@redhat.com> | 2018-10-17 18:48:19 +0530 |
---|---|---|
committer | Shyamsundar Ranganathan <srangana@redhat.com> | 2018-10-18 12:48:09 +0000 |
commit | 7e918e9a0724fd50a672fa5a9c844af7f903e9fc (patch) | |
tree | 44fc056dcc756d8ae7f0b9deb06c73b101aad773 /xlators/debug | |
parent | 5bc2fd4fc6a8aa65d8d2b2c22ffb6c5b70ef9dac (diff) |
debug/io-stats: io stats filenames contain garbage
As dict_unserialize does not null terminate the value,
using snprintf adds garbage characters to the buffer
used to create the filename.
The code also used this->name in the filename which
will be the same for all bricks for a volume. The
files were thus overwritten if a node contained
multiple bricks for a volume. The code now uses
the conf->unique instead if available.
Change-Id: I2c72534b32634b87961d3b3f7d53c5f2ca2c068c
fixes: bz#1640392
Signed-off-by: N Balachandran <nbalacha@redhat.com>
(cherry picked from commit 219cd649fdbd7bfd6c2268a0a4f66bcc15918e31)
Diffstat (limited to 'xlators/debug')
-rw-r--r-- | xlators/debug/io-stats/src/io-stats.c | 27 |
1 files changed, 23 insertions, 4 deletions
diff --git a/xlators/debug/io-stats/src/io-stats.c b/xlators/debug/io-stats/src/io-stats.c index 6f6104033d8..4c6b91dcdc9 100644 --- a/xlators/debug/io-stats/src/io-stats.c +++ b/xlators/debug/io-stats/src/io-stats.c @@ -2918,9 +2918,12 @@ conditional_dump(dict_t *dict, char *key, data_t *value, void *data) char dump_key[100]; char *slash_ptr = NULL; char *path_in_value = NULL; + char *identifier = NULL; + struct ios_conf *conf = NULL; stub = data; this = stub->this; + conf = this->private; /* Create a file name that is appended with the io-stats instance name as well. This helps when there is more than a single io-stats @@ -2933,21 +2936,37 @@ conditional_dump(dict_t *dict, char *key, data_t *value, void *data) /* name format: /var/run/gluster/<passed in path/filename>.<xlator name * slashes to -> */ - path_in_value = data_to_str(value); + path_in_value = alloca0(value->len + 1); + + /* We need a memcpy here because of the way dict_unserialize works */ + + memcpy(path_in_value, data_to_str(value), value->len); + path_in_value[value->len] = '\0'; if (strstr(path_in_value, "../")) { gf_log(this->name, GF_LOG_ERROR, "%s: no \"../\" allowed in path", path_in_value); return -1; } + + if (path_in_value[0] == '/') { + path_in_value = path_in_value + 1; + } + dirlen = strlen(IOS_STATS_DUMP_DIR); - namelen = (dirlen + value->len + strlen(this->name) + 3); + if (conf->unique_id) { + /* this->name will be the same for all bricks of the volume */ + identifier = conf->unique_id; + } else { + identifier = this->name; + } + + namelen = (dirlen + value->len + strlen(identifier) + 3); /* +3 for '/', '.' and '\0' added in snprintf below*/ filename = alloca0(namelen); - snprintf(filename, namelen, "%s/%s.%s", IOS_STATS_DUMP_DIR, path_in_value, - this->name); + identifier); /* convert any slashes to '-' so that fopen works correctly */ slash_ptr = strchr(filename + dirlen + 1, '/'); |