Commit 4dc8e56d authored by Magne Mahre's avatar Magne Mahre

Bug#39277 - symlink.test fails on Debian

      
When the data directory contained a symbolic link to another
file system, and the DATA or INDEX DIRECTORY clause of a
CREATE TABLE statement referred to a subdirectory of the data
directory, this was accepted.
      
The problem was the use of a table file path name, which included
the table name without an extension, for the comparison against
the data directory path name. This was almost always a
non-existent file. The internal algorithm failed to resolve
symbolic links for non-existent files. So we compared unrelated
path names.
      
Fixed by truncating the table name from the path before resolving
symlinks. If this is also a non-existent path, the creation of
the table will fail anyway.

Backport to 5.6.0.    6.0-codebase revid: 2599.60.1


sql/sql_table.cc:
  Changed test for data directory to exclude the table name from the
  comparison.
parent 57edb25c
...@@ -3934,16 +3934,44 @@ bool mysql_create_table_no_lock(THD *thd, ...@@ -3934,16 +3934,44 @@ bool mysql_create_table_no_lock(THD *thd,
create_info->table_existed= 0; // Mark that table is created create_info->table_existed= 0; // Mark that table is created
#ifdef HAVE_READLINK #ifdef HAVE_READLINK
if (test_if_data_home_dir(create_info->data_file_name)) {
size_t dirlen;
char dirpath[FN_REFLEN];
/*
data_file_name and index_file_name include the table name without
extension. Mostly this does not refer to an existing file. When
comparing data_file_name or index_file_name against the data
directory, we try to resolve all symbolic links. On some systems,
we use realpath(3) for the resolution. This returns ENOENT if the
resolved path does not refer to an existing file. my_realpath()
does then copy the requested path verbatim, without symlink
resolution. Thereafter the comparison can fail even if the
requested path is within the data directory. E.g. if symlinks to
another file system are used. To make realpath(3) return the
resolved path, we strip the table name and compare the directory
path only. If the directory doesn't exist either, table creation
will fail anyway.
*/
if (create_info->data_file_name)
{
dirname_part(dirpath, create_info->data_file_name, &dirlen);
if (test_if_data_home_dir(dirpath))
{ {
my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY"); my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
goto unlock_and_end; goto unlock_and_end;
} }
if (test_if_data_home_dir(create_info->index_file_name)) }
if (create_info->index_file_name)
{
dirname_part(dirpath, create_info->index_file_name, &dirlen);
if (test_if_data_home_dir(dirpath))
{ {
my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY"); my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
goto unlock_and_end; goto unlock_and_end;
} }
}
}
#ifdef WITH_PARTITION_STORAGE_ENGINE #ifdef WITH_PARTITION_STORAGE_ENGINE
if (check_partition_dirs(thd->lex->part_info)) if (check_partition_dirs(thd->lex->part_info))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment