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
This commit is contained in:
parent
eea7af04c0
commit
a94150cdcb
@ -3934,15 +3934,43 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
create_info->table_existed= 0; // Mark that table is created
|
||||
|
||||
#ifdef HAVE_READLINK
|
||||
if (test_if_data_home_dir(create_info->data_file_name))
|
||||
{
|
||||
my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
|
||||
goto unlock_and_end;
|
||||
}
|
||||
if (test_if_data_home_dir(create_info->index_file_name))
|
||||
{
|
||||
my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
|
||||
goto unlock_and_end;
|
||||
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");
|
||||
goto unlock_and_end;
|
||||
}
|
||||
}
|
||||
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");
|
||||
goto unlock_and_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
|
Loading…
x
Reference in New Issue
Block a user