summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarc Alff <marc.alff@sun.com>2010-02-26 10:39:57 -0700
committerMarc Alff <marc.alff@sun.com>2010-02-26 10:39:57 -0700
commitd6131618bb2fa78406091ddc1e0ad42fd895278b (patch)
tree549d59091257b58c388bb6cb4e8a76914cd352d6 /storage
parent88f4990c3333a720b09e43c095bb4257332177c4 (diff)
downloadmariadb-git-d6131618bb2fa78406091ddc1e0ad42fd895278b.tar.gz
Bug#51447 performance schema evil twin files
Before this fix, the performance schema file instrumentation would treat: - a relative path to a file - an absolute path to the same file as two different files. This would lead to: - separate aggregation counters - file leaks when a file is removed. With this fix, a relative and absolute path are resolved to the same file instrument.
Diffstat (limited to 'storage')
-rw-r--r--storage/perfschema/pfs_instr.cc27
1 files changed, 21 insertions, 6 deletions
diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc
index 2ce3a844290..557ec1c14b5 100644
--- a/storage/perfschema/pfs_instr.cc
+++ b/storage/perfschema/pfs_instr.cc
@@ -746,8 +746,23 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
}
}
- if (len >= sizeof(pfs->m_filename))
- len= sizeof(pfs->m_filename) - 1;
+ /*
+ Normalize the file name to avoid duplicates when using aliases:
+ - absolute or relative paths
+ - symbolic links
+ */
+ char buffer[FN_REFLEN];
+ const char *normalized_filename;
+ int normalized_length;
+
+ /*
+ Ignore errors, the file may not exist.
+ my_realpath always provide a best effort result in buffer.
+ */
+ (void) my_realpath(buffer, filename, MYF(0));
+
+ normalized_filename= buffer;
+ normalized_length= strlen(normalized_filename);
PFS_file **entry;
uint retry_count= 0;
@@ -755,7 +770,7 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass,
search:
entry= reinterpret_cast<PFS_file**>
(lf_hash_search(&filename_hash, thread->m_filename_hash_pins,
- filename, len));
+ normalized_filename, normalized_length));
if (entry && (entry != MY_ERRPTR))
{
pfs= *entry;
@@ -783,9 +798,9 @@ search:
if (pfs->m_lock.free_to_dirty())
{
pfs->m_class= klass;
- strncpy(pfs->m_filename, filename, len);
- pfs->m_filename[len]= '\0';
- pfs->m_filename_length= len;
+ strncpy(pfs->m_filename, normalized_filename, normalized_length);
+ pfs->m_filename[normalized_length]= '\0';
+ pfs->m_filename_length= normalized_length;
pfs->m_file_stat.m_open_count= 1;
pfs->m_wait_stat.m_control_flag=
&flag_events_waits_summary_by_instance;