diff options
author | Marc Alff <marc.alff@oracle.com> | 2010-07-15 19:25:03 -0600 |
---|---|---|
committer | Marc Alff <marc.alff@oracle.com> | 2010-07-15 19:25:03 -0600 |
commit | 102d04dd659e3ac6a12b358041be93284f5f1748 (patch) | |
tree | 7be67f452840c749812c625a7c664ed526af9ff7 /storage/perfschema/pfs_instr.cc | |
parent | 3725080c2560be76674300296f3ed2b536d9067b (diff) | |
download | mariadb-git-102d04dd659e3ac6a12b358041be93284f5f1748.tar.gz |
Bug#52134 performance schema file io, symlink in path
Backport from mysql-next-mr (5.6) to mysql-trunk (5.5)
Diffstat (limited to 'storage/perfschema/pfs_instr.cc')
-rw-r--r-- | storage/perfschema/pfs_instr.cc | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/storage/perfschema/pfs_instr.cc b/storage/perfschema/pfs_instr.cc index 3071df17325..0c7b25a03de 100644 --- a/storage/perfschema/pfs_instr.cc +++ b/storage/perfschema/pfs_instr.cc @@ -829,7 +829,7 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass, - it fits into pfs->m_filename - it is safe to use mysys apis to normalize the file name. */ - memcpy(safe_buffer, filename, FN_REFLEN - 2); + memcpy(safe_buffer, filename, FN_REFLEN - 1); safe_buffer[FN_REFLEN - 1]= 0; safe_filename= safe_buffer; } @@ -840,16 +840,58 @@ find_or_create_file(PFS_thread *thread, PFS_file_class *klass, Normalize the file name to avoid duplicates when using aliases: - absolute or relative paths - symbolic links + Names are resolved as follows: + - /real/path/to/real_file ==> same + - /path/with/link/to/real_file ==> /real/path/to/real_file + - real_file ==> /real/path/to/real_file + - ./real_file ==> /real/path/to/real_file + - /real/path/to/sym_link ==> same + - /path/with/link/to/sym_link ==> /real/path/to/sym_link + - sym_link ==> /real/path/to/sym_link + - ./sym_link ==> /real/path/to/sym_link + When the last component of a file is a symbolic link, + the last component is *not* resolved, so that all file io + operations on a link (create, read, write, delete) are counted + against the link itself, not the target file. + Resolving the name would lead to create counted against the link, + and read/write/delete counted against the target, leading to + incoherent results and instrumentation leaks. + Also note that, when creating files, this name resolution + works properly for files that do not exist (yet) on the file system. */ char buffer[FN_REFLEN]; + char dirbuffer[FN_REFLEN]; + size_t dirlen; 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, safe_filename, MYF(0)); + dirlen= dirname_length(safe_filename); + if (dirlen == 0) + { + dirbuffer[0]= FN_CURLIB; + dirbuffer[1]= FN_LIBCHAR; + dirbuffer[2]= '\0'; + } + else + { + memcpy(dirbuffer, safe_filename, dirlen); + dirbuffer[dirlen]= '\0'; + } + + if (my_realpath(buffer, dirbuffer, MYF(0)) != 0) + { + file_lost++; + return NULL; + } + + /* Append the unresolved file name to the resolved path */ + char *ptr= buffer + strlen(buffer); + char *buf_end= &buffer[sizeof(buffer)-1]; + if (buf_end > ptr) + *ptr++= FN_LIBCHAR; + if (buf_end > ptr) + strncpy(ptr, safe_filename + dirlen, buf_end - ptr); + *buf_end= '\0'; normalized_filename= buffer; normalized_length= strlen(normalized_filename); |