1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-9566 prepare mysqltest for mariabackup

- Do not throw output of exec command, if disable_result_log is set
save and dump it if exec fails. Need tha to meaningfully analyze
errors from mariabackup.

- rmdir now removes the entire tree. need that because xtrabackup tests
clean the whole directory.

- all filesystem modifying commands now require the argument to
  be under MYSQLTEST_VARDIR or MYSQL_TMP_DIR.
This commit is contained in:
Vladislav Vaintroub
2017-04-18 17:09:28 +00:00
committed by Sergei Golubchik
parent 7bf409593e
commit ec68f764f6
6 changed files with 131 additions and 533 deletions

View File

@@ -3373,6 +3373,12 @@ void do_exec(struct st_command *command)
#endif
#endif
if (disable_result_log)
{
/* Collect stderr output as well, for the case app. crashes or returns error.*/
dynstr_append(&ds_cmd, " 2>&1");
}
DBUG_PRINT("info", ("Executing '%s' as '%s'",
command->first_argument, ds_cmd.str));
@@ -3408,16 +3414,7 @@ void do_exec(struct st_command *command)
len--;
}
#endif
if (disable_result_log)
{
if (len)
buf[len-1] = 0;
DBUG_PRINT("exec_result",("%s", buf));
}
else
{
replace_dynstr_append_mem(ds_result, buf, len);
}
replace_dynstr_append_mem(ds_result, buf, len);
}
error= pclose(res_file);
@@ -3427,7 +3424,7 @@ void do_exec(struct st_command *command)
dynstr_free(&ds_sorted);
}
if (error > 0)
if (error)
{
uint status= WEXITSTATUS(error);
int i;
@@ -3473,6 +3470,12 @@ void do_exec(struct st_command *command)
}
dynstr_free(&ds_cmd);
if (disable_result_log)
{
/* Disable output in case of successful exit.*/
dynstr_set(&ds_res,"");
}
DBUG_VOID_RETURN;
}
@@ -3610,6 +3613,37 @@ void do_system(struct st_command *command)
}
/* returns TRUE if path is inside a sandbox */
bool is_sub_path(const char *path, size_t plen, const char *sandbox)
{
size_t len= strlen(sandbox);
if (!sandbox || !len || plen <= len || memcmp(path, sandbox, len - 1)
|| path[len] != '/')
return false;
return true;
}
/* returns TRUE if path cannot be modified */
bool bad_path(const char *path)
{
size_t plen= strlen(path);
const char *vardir= getenv("MYSQLTEST_VARDIR");
if (is_sub_path(path, plen, vardir))
return false;
const char *tmpdir= getenv("MYSQL_TMP_DIR");
if (is_sub_path(path, plen, tmpdir))
return false;
report_or_die("Path '%s' is not a subdirectory of MYSQLTEST_VARDIR '%s'"
"or MYSQL_TMP_DIR '%s'",
path, vardir, tmpdir);
return true;
}
/*
SYNOPSIS
set_wild_chars
@@ -3668,6 +3702,9 @@ void do_remove_file(struct st_command *command)
rm_args, sizeof(rm_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_filename.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("removing file: %s", ds_filename.str));
error= my_delete(ds_filename.str, MYF(disable_warnings ? 0 : MY_WME)) != 0;
handle_command_error(command, error, my_errno);
@@ -3711,6 +3748,9 @@ void do_remove_files_wildcard(struct st_command *command)
' ');
fn_format(dirname, ds_directory.str, "", "", MY_UNPACK_FILENAME);
if (bad_path(ds_directory.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("listing directory: %s", dirname));
if (!(dir_info= my_dir(dirname, MYF(MY_DONT_SORT | MY_WANT_STAT | MY_WME))))
{
@@ -3785,6 +3825,9 @@ void do_copy_file(struct st_command *command)
sizeof(copy_file_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_to_file.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("Copy %s to %s", ds_from_file.str, ds_to_file.str));
/* MY_HOLD_ORIGINAL_MODES prevents attempts to chown the file */
error= (my_copy(ds_from_file.str, ds_to_file.str,
@@ -3822,6 +3865,9 @@ void do_move_file(struct st_command *command)
sizeof(move_file_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_to_file.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("Move %s to %s", ds_from_file.str, ds_to_file.str));
error= (my_rename(ds_from_file.str, ds_to_file.str,
MYF(disable_warnings ? 0 : MY_WME)) != 0);
@@ -3860,6 +3906,9 @@ void do_chmod_file(struct st_command *command)
sizeof(chmod_file_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_file.str))
DBUG_VOID_RETURN;
/* Parse what mode to set */
if (ds_mode.length != 4 ||
str2int(ds_mode.str, 8, 0, INT_MAX, &mode) == NullS)
@@ -3931,6 +3980,9 @@ void do_mkdir(struct st_command *command)
mkdir_args, sizeof(mkdir_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_dirname.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("creating directory: %s", ds_dirname.str));
error= my_mkdir(ds_dirname.str, 0777, MYF(MY_WME)) != 0;
handle_command_error(command, error, my_errno);
@@ -3938,6 +3990,47 @@ void do_mkdir(struct st_command *command)
DBUG_VOID_RETURN;
}
/*
Remove directory recursively.
*/
static int rmtree(const char *dir)
{
char path[FN_REFLEN];
char sep[]={ FN_LIBCHAR, 0 };
int err=0;
MY_DIR *dir_info= my_dir(dir, MYF(MY_DONT_SORT | MY_WANT_STAT));
if (!dir_info)
return 1;
for (uint i= 0; i < dir_info->number_of_files; i++)
{
FILEINFO *file= dir_info->dir_entry + i;
/* Skip "." and ".." */
if (!strcmp(file->name, ".") || !strcmp(file->name, ".."))
continue;
strxnmov(path, sizeof(path), dir, sep, file->name, NULL);
if (!MY_S_ISDIR(file->mystat->st_mode))
err= my_delete(path, 0);
else
err= rmtree(path);
if(err)
break;
}
my_dirend(dir_info);
if (!err)
err= rmdir(dir);
return err;
}
/*
SYNOPSIS
do_rmdir
@@ -3945,12 +4038,11 @@ void do_mkdir(struct st_command *command)
DESCRIPTION
rmdir <dir_name>
Remove the empty directory <dir_name>
Remove the directory tree
*/
void do_rmdir(struct st_command *command)
{
int error;
static DYNAMIC_STRING ds_dirname;
const struct command_arg rmdir_args[] = {
{ "dirname", ARG_STRING, TRUE, &ds_dirname, "Directory to remove" }
@@ -3961,9 +4053,13 @@ void do_rmdir(struct st_command *command)
rmdir_args, sizeof(rmdir_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_dirname.str))
DBUG_VOID_RETURN;
DBUG_PRINT("info", ("removing directory: %s", ds_dirname.str));
error= rmdir(ds_dirname.str) != 0;
handle_command_error(command, error, errno);
if (rmtree(ds_dirname.str))
handle_command_error(command, 1, errno);
dynstr_free(&ds_dirname);
DBUG_VOID_RETURN;
}
@@ -4076,6 +4172,9 @@ static void do_list_files_write_file_command(struct st_command *command,
list_files_args,
sizeof(list_files_args)/sizeof(struct command_arg), ' ');
if (bad_path(ds_filename.str))
DBUG_VOID_RETURN;
init_dynamic_string(&ds_content, "", 1024, 1024);
error= get_list_files(&ds_content, &ds_dirname, &ds_wild);
handle_command_error(command, error, my_errno);
@@ -4127,7 +4226,8 @@ void read_until_delimiter(DYNAMIC_STRING *ds,
while (1)
{
c= my_getc(cur_file->file);
if (c == '\r')
c= my_getc(cur_file->file);
if (c == '\n')
{
cur_file->lineno++;
@@ -4178,6 +4278,9 @@ void do_write_file_command(struct st_command *command, my_bool append)
sizeof(write_file_args)/sizeof(struct command_arg),
' ');
if (bad_path(ds_filename.str))
DBUG_VOID_RETURN;
if (!append && access(ds_filename.str, F_OK) == 0)
{
/* The file should not be overwritten */