From d6889f2b58c0caeb31dc3f117ae33c31ec74df8c Mon Sep 17 00:00:00 2001 From: wlad Date: Fri, 19 Oct 2018 21:56:15 +0100 Subject: [PATCH] MDEV-17504 : add diagnostics if creation of directories fail in mysql_install_db.exe In addition,don't remove datadir if it was not created or was not empty. --- sql/CMakeLists.txt | 2 +- sql/mysql_install_db.cc | 87 ++++++++++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 074dd89ec7a..f2c1eeb6566 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -485,7 +485,7 @@ IF(WIN32) COMPONENT Server ) SET_TARGET_PROPERTIES(mysql_install_db PROPERTIES COMPILE_FLAGS -DINSTALL_PLUGINDIR=${INSTALL_PLUGINDIR}) - TARGET_LINK_LIBRARIES(mysql_install_db mysys) + TARGET_LINK_LIBRARIES(mysql_install_db mysys shlwapi) ADD_LIBRARY(winservice STATIC winservice.c) TARGET_LINK_LIBRARIES(winservice shell32) diff --git a/sql/mysql_install_db.cc b/sql/mysql_install_db.cc index ce40b5edc2c..737ed97d790 100644 --- a/sql/mysql_install_db.cc +++ b/sql/mysql_install_db.cc @@ -26,6 +26,7 @@ #include #include #include +#include #define USAGETEXT \ "mysql_install_db.exe Ver 1.00 for Windows\n" \ @@ -93,9 +94,7 @@ static struct my_option my_long_options[]= static my_bool -get_one_option(int optid, - const struct my_option *opt __attribute__ ((unused)), - char *argument __attribute__ ((unused))) +get_one_option(int optid, const struct my_option *, char *) { DBUG_ENTER("get_one_option"); switch (optid) { @@ -109,7 +108,7 @@ get_one_option(int optid, } -static void die(const char *fmt, ...) +ATTRIBUTE_NORETURN static void die(const char *fmt, ...) { va_list args; DBUG_ENTER("die"); @@ -290,7 +289,7 @@ static int create_myini() FILE *myini= fopen("my.ini","wt"); if (!myini) { - die("Cannot create my.ini in data directory"); + die("Can't create my.ini in data directory"); } /* Write out server settings. */ @@ -308,7 +307,7 @@ static int create_myini() if (enable_named_pipe) { - fprintf(myini,"enable-named-pipe\n"); + fprintf(myini,"named-pipe=ON\n"); } if (opt_socket && opt_socket[0]) @@ -523,6 +522,7 @@ static int set_directory_permissions(const char *dir, const char *os_user) } + /* Create database instance (including registering as service etc) .*/ static int create_db_instance() @@ -532,19 +532,78 @@ static int create_db_instance() DWORD cwd_len= MAX_PATH; char cmdline[3*MAX_PATH]; FILE *in; + bool cleanup_datadir= true; + DWORD last_error; verbose("Running bootstrap"); GetCurrentDirectory(cwd_len, cwd); - CreateDirectory(opt_datadir, NULL); /*ignore error, it might already exist */ + + /* Create datadir and datadir/mysql, if they do not already exist. */ + + if (!CreateDirectory(opt_datadir, NULL) && (GetLastError() != ERROR_ALREADY_EXISTS)) + { + last_error = GetLastError(); + switch(last_error) + { + case ERROR_ACCESS_DENIED: + die("Can't create data directory '%s' (access denied)\n", + opt_datadir); + break; + case ERROR_PATH_NOT_FOUND: + die("Can't create data directory '%s' " + "(one or more intermediate directories do not exist)\n", + opt_datadir); + break; + default: + die("Can't create data directory '%s', last error %u\n", + opt_datadir, last_error); + break; + } + } if (!SetCurrentDirectory(opt_datadir)) { - die("Cannot set current directory to '%s'\n",opt_datadir); - return -1; + last_error = GetLastError(); + switch (last_error) + { + case ERROR_DIRECTORY: + die("Can't set current directory to '%s', the path is not a valid directory \n", + opt_datadir); + break; + default: + die("Can' set current directory to '%s', last error %u\n", + opt_datadir, last_error); + break; + } } - CreateDirectory("mysql",NULL); + if (PathIsDirectoryEmpty(opt_datadir)) + { + cleanup_datadir= false; + } + + if (!CreateDirectory("mysql",NULL)) + { + last_error = GetLastError(); + DWORD attributes; + switch(last_error) + { + case ERROR_ACCESS_DENIED: + die("Can't create subdirectory 'mysql' in '%s' (access denied)\n",opt_datadir); + break; + case ERROR_ALREADY_EXISTS: + attributes = GetFileAttributes("mysql"); + + if (attributes == INVALID_FILE_ATTRIBUTES) + die("GetFileAttributes() failed for existing file '%s\\mysql', last error %u", + opt_datadir, GetLastError()); + else if (!(attributes & FILE_ATTRIBUTE_DIRECTORY)) + die("File '%s\\mysql' exists, but it is not a directory", opt_datadir); + + break; + } + } /* Set data directory permissions for both current user and @@ -565,11 +624,11 @@ static int create_db_instance() if (setvbuf(in, NULL, _IONBF, 0)) { - verbose("WARNING: Cannot disable buffering on mysqld's stdin"); + verbose("WARNING: Can't disable buffering on mysqld's stdin"); } if (fwrite("use mysql;\n",11,1, in) != 1) { - verbose("ERROR: Cannot write to mysqld's stdin"); + verbose("ERROR: Can't write to mysqld's stdin"); ret= 1; goto end; } @@ -580,7 +639,7 @@ static int create_db_instance() /* Write the bootstrap script to stdin. */ if (fwrite(mysql_bootstrap_sql[i], strlen(mysql_bootstrap_sql[i]), 1, in) != 1) { - verbose("ERROR: Cannot write to mysqld's stdin"); + verbose("ERROR: Can't write to mysqld's stdin"); ret= 1; goto end; } @@ -649,7 +708,7 @@ static int create_db_instance() } end: - if (ret) + if (ret && cleanup_datadir) { SetCurrentDirectory(cwd); clean_directory(opt_datadir);