diff options
author | Marc Alff <marc.alff@sun.com> | 2010-02-26 10:39:57 -0700 |
---|---|---|
committer | Marc Alff <marc.alff@sun.com> | 2010-02-26 10:39:57 -0700 |
commit | d6131618bb2fa78406091ddc1e0ad42fd895278b (patch) | |
tree | 549d59091257b58c388bb6cb4e8a76914cd352d6 /storage | |
parent | 88f4990c3333a720b09e43c095bb4257332177c4 (diff) | |
download | mariadb-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.cc | 27 |
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; |