mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
MDEV-7021 allow config file parameter for mysql_install_db.exe
The new parameter is called --config The config file is copied to the data directory as my.ini, and possibly modified. Bootstrap will now use my.ini to create tables. In case of non-standard directory/file placements, this will ensure correct permissions for the service user. mysql_install_db_win test is extended to test --config with non-trivial config file.
This commit is contained in:
@ -1,8 +1,8 @@
|
|||||||
Running bootstrap
|
Running bootstrap
|
||||||
|
Creating my.ini file
|
||||||
Removing default user
|
Removing default user
|
||||||
Allowing remote access for user root
|
Allowing remote access for user root
|
||||||
Setting root password
|
Setting root password
|
||||||
Creating my.ini file
|
|
||||||
Creation of the database was successful
|
Creation of the database was successful
|
||||||
# Kill the server
|
# Kill the server
|
||||||
# restart: --datadir=MYSQLTEST_VARDIR/tmp/ddir --loose-innodb
|
# restart: --datadir=MYSQLTEST_VARDIR/tmp/ddir --loose-innodb
|
||||||
@ -12,4 +12,24 @@ SELECT @@datadir;
|
|||||||
DATADIR/
|
DATADIR/
|
||||||
# Kill the server
|
# Kill the server
|
||||||
connection default;
|
connection default;
|
||||||
|
[mysqld]
|
||||||
|
long_query_time=15.000000
|
||||||
|
#slow_query_log_file=l:/errorlog/mariadb.slow.log
|
||||||
|
slow_query_log_file=BASEDIR/data/slow_query_log_01.log
|
||||||
|
datadir=BASEDIR/data
|
||||||
|
server-id=1
|
||||||
|
port=3307
|
||||||
|
#tmpdir=C:/mysql_tmpdir
|
||||||
|
tmpdir=BASEDIR/temp
|
||||||
|
innodb_data_file_path=ibdata1:10M;ibdata2:10M:autoextend
|
||||||
|
innodb_log_group_home_dir=BASEDIR/data
|
||||||
|
skip-name-resolve
|
||||||
|
|
||||||
|
#*********************************************************
|
||||||
|
# performance_schema
|
||||||
|
#*********************************************************
|
||||||
|
performance_schema=OFF
|
||||||
|
|
||||||
|
[client]
|
||||||
|
port=3307
|
||||||
# restart
|
# restart
|
||||||
|
@ -20,5 +20,39 @@ SELECT @@datadir;
|
|||||||
rmdir $ddir;
|
rmdir $ddir;
|
||||||
let $restart_parameters=;
|
let $restart_parameters=;
|
||||||
connection default;
|
connection default;
|
||||||
|
|
||||||
|
# Test --template option
|
||||||
|
let _BASEDIR = $MYSQLTEST_VARDIR/tmp/basedir;
|
||||||
|
perl;
|
||||||
|
|
||||||
|
open(IN, '<', "std_data/mysql_install_db_win.ini.in") or die;
|
||||||
|
open(OUT, '>', "$ENV{MYSQLTEST_VARDIR}/tmp/mysql_install_db_win.ini") or die;
|
||||||
|
while (<IN>) {
|
||||||
|
s/BASEDIR/$ENV{_BASEDIR}/g;
|
||||||
|
print OUT $_;
|
||||||
|
}
|
||||||
|
close IN;
|
||||||
|
close OUT
|
||||||
|
EOF
|
||||||
|
mkdir $_BASEDIR;
|
||||||
|
mkdir $_BASEDIR/temp;
|
||||||
|
|
||||||
|
# Run mysql_install_db.exe with config parameter
|
||||||
|
--disable_result_log
|
||||||
|
exec $MYSQL_INSTALL_DB_EXE -o --port=3307 --config=$MYSQLTEST_VARDIR/tmp/mysql_install_db_win.ini;
|
||||||
|
--enable_result_log
|
||||||
|
|
||||||
|
# dump the modified config in data directory
|
||||||
|
perl;
|
||||||
|
open(IN, '<', "$ENV{_BASEDIR}/data/my.ini") or die;
|
||||||
|
while (<IN>) {
|
||||||
|
s/$ENV{_BASEDIR}/BASEDIR/g;
|
||||||
|
# when testing on installation layout, client's plugin
|
||||||
|
# dir is added, but when testing in build dir.
|
||||||
|
print unless $_ =~ /plugin-dir/;
|
||||||
|
}
|
||||||
|
close IN;
|
||||||
|
EOF
|
||||||
|
rmdir $_BASEDIR;
|
||||||
--source include/start_mysqld.inc
|
--source include/start_mysqld.inc
|
||||||
|
|
||||||
|
18
mysql-test/std_data/mysql_install_db_win.ini.in
Normal file
18
mysql-test/std_data/mysql_install_db_win.ini.in
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
[mysqld]
|
||||||
|
long_query_time=15.000000
|
||||||
|
#slow_query_log_file=l:/errorlog/mariadb.slow.log
|
||||||
|
slow_query_log_file=BASEDIR/data/slow_query_log_01.log
|
||||||
|
datadir=BASEDIR/data/
|
||||||
|
server-id=1
|
||||||
|
port=3306
|
||||||
|
#tmpdir=C:/mysql_tmpdir
|
||||||
|
tmpdir=BASEDIR/temp
|
||||||
|
innodb_data_file_path=ibdata1:10M;ibdata2:10M:autoextend
|
||||||
|
innodb_log_group_home_dir=BASEDIR/data
|
||||||
|
skip-name-resolve
|
||||||
|
|
||||||
|
#*********************************************************
|
||||||
|
# performance_schema
|
||||||
|
#*********************************************************
|
||||||
|
performance_schema=OFF
|
||||||
|
|
@ -43,9 +43,8 @@ struct IUnknown;
|
|||||||
|
|
||||||
extern "C" const char* mysql_bootstrap_sql[];
|
extern "C" const char* mysql_bootstrap_sql[];
|
||||||
|
|
||||||
static char default_os_user[]= "NT AUTHORITY\\NetworkService";
|
|
||||||
static char default_datadir[MAX_PATH];
|
static char default_datadir[MAX_PATH];
|
||||||
static int create_db_instance();
|
static int create_db_instance(const char *datadir);
|
||||||
static uint opt_silent;
|
static uint opt_silent;
|
||||||
static char datadir_buffer[FN_REFLEN];
|
static char datadir_buffer[FN_REFLEN];
|
||||||
static char mysqld_path[FN_REFLEN];
|
static char mysqld_path[FN_REFLEN];
|
||||||
@ -61,6 +60,7 @@ static my_bool opt_skip_networking;
|
|||||||
static my_bool opt_verbose_bootstrap;
|
static my_bool opt_verbose_bootstrap;
|
||||||
static my_bool verbose_errors;
|
static my_bool verbose_errors;
|
||||||
static my_bool opt_large_pages;
|
static my_bool opt_large_pages;
|
||||||
|
static char *opt_config;
|
||||||
|
|
||||||
#define DEFAULT_INNODB_PAGE_SIZE 16*1024
|
#define DEFAULT_INNODB_PAGE_SIZE 16*1024
|
||||||
|
|
||||||
@ -94,9 +94,10 @@ static struct my_option my_long_options[]=
|
|||||||
&opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
&opt_silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"verbose-bootstrap", 'o', "Include mysqld bootstrap output",&opt_verbose_bootstrap,
|
{"verbose-bootstrap", 'o', "Include mysqld bootstrap output",&opt_verbose_bootstrap,
|
||||||
&opt_verbose_bootstrap, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
&opt_verbose_bootstrap, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{"large-pages",'l', "Use large pages", &opt_large_pages,
|
{ "large-pages",'l', "Use large pages", &opt_large_pages,
|
||||||
&opt_large_pages, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
&opt_large_pages, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
|
{"config",'c', "my.ini config template file", &opt_config,
|
||||||
|
&opt_config, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||||
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -156,15 +157,16 @@ static void verbose( const char *fmt, ...)
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char full_config_path[MAX_PATH];
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
char self_name[FN_REFLEN];
|
char self_name[MAX_PATH];
|
||||||
char *p;
|
char *p;
|
||||||
|
char *datadir = NULL;
|
||||||
MY_INIT(argv[0]);
|
MY_INIT(argv[0]);
|
||||||
GetModuleFileName(NULL, self_name, FN_REFLEN);
|
GetModuleFileName(NULL, self_name, MAX_PATH);
|
||||||
strcpy(mysqld_path,self_name);
|
strcpy(mysqld_path,self_name);
|
||||||
p= strrchr(mysqld_path, FN_LIBCHAR);
|
p= strrchr(mysqld_path, FN_LIBCHAR);
|
||||||
if (p)
|
if (p)
|
||||||
@ -174,7 +176,56 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
if ((error= handle_options(&argc, &argv, my_long_options, get_one_option)))
|
if ((error= handle_options(&argc, &argv, my_long_options, get_one_option)))
|
||||||
exit(error);
|
exit(error);
|
||||||
if (!opt_datadir)
|
|
||||||
|
if (opt_config != 0 && _access(opt_config, 04) != 0)
|
||||||
|
{
|
||||||
|
int err= errno;
|
||||||
|
switch(err)
|
||||||
|
{
|
||||||
|
case EACCES:
|
||||||
|
die("File %s can't be read", opt_config);
|
||||||
|
break;
|
||||||
|
case ENOENT:
|
||||||
|
die("File %s does not exist", opt_config);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
die("Can't access file %s, errno %d",opt_config, err);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (opt_config)
|
||||||
|
{
|
||||||
|
DWORD dwret = GetFullPathName(opt_config, sizeof(full_config_path), full_config_path, NULL);
|
||||||
|
if (dwret == 0)
|
||||||
|
{
|
||||||
|
die("GetFullPathName failed, last error %u", GetLastError());
|
||||||
|
}
|
||||||
|
else if (dwret > sizeof(full_config_path))
|
||||||
|
{
|
||||||
|
die("Can't resolve the config file name, path too large");
|
||||||
|
}
|
||||||
|
opt_config= full_config_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(opt_datadir)
|
||||||
|
datadir = opt_datadir;
|
||||||
|
|
||||||
|
if (!datadir && opt_config)
|
||||||
|
{
|
||||||
|
for(auto section : {"server","mysqld"})
|
||||||
|
{
|
||||||
|
auto ret = GetPrivateProfileStringA(section,"datadir", NULL, default_datadir,
|
||||||
|
sizeof(default_datadir)-1, opt_config);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
datadir= default_datadir;
|
||||||
|
printf("Data directory (from config file) is %s\n",datadir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!datadir)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Figure out default data directory. It "data" directory, next to "bin" directory, where
|
Figure out default data directory. It "data" directory, next to "bin" directory, where
|
||||||
@ -195,26 +246,32 @@ int main(int argc, char **argv)
|
|||||||
my_print_help(my_long_options);
|
my_print_help(my_long_options);
|
||||||
}
|
}
|
||||||
strcat_s(default_datadir, "\\data");
|
strcat_s(default_datadir, "\\data");
|
||||||
opt_datadir= default_datadir;
|
datadir= default_datadir;
|
||||||
printf("Default data directory is %s\n",opt_datadir);
|
printf("Default data directory is %s\n",datadir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DBUG_ASSERT(datadir);
|
||||||
|
|
||||||
/* Print some help on errors */
|
/* Print some help on errors */
|
||||||
verbose_errors= TRUE;
|
verbose_errors= TRUE;
|
||||||
|
|
||||||
/* Workaround WiX bug (strip possible quote character at the end of path) */
|
/* Workaround WiX bug (strip possible quote character at the end of path) */
|
||||||
size_t len= strlen(opt_datadir);
|
size_t len= strlen(datadir);
|
||||||
if (len > 0)
|
if (len > 0)
|
||||||
{
|
{
|
||||||
if (opt_datadir[len-1] == '"')
|
if (datadir[len-1] == '"')
|
||||||
{
|
{
|
||||||
opt_datadir[len-1]= 0;
|
datadir[len-1]= 0;
|
||||||
|
}
|
||||||
|
if (datadir[0] == '"')
|
||||||
|
{
|
||||||
|
datadir++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GetFullPathName(opt_datadir, FN_REFLEN, datadir_buffer, NULL);
|
GetFullPathName(datadir, FN_REFLEN, datadir_buffer, NULL);
|
||||||
opt_datadir= datadir_buffer;
|
datadir= datadir_buffer;
|
||||||
|
|
||||||
if (create_db_instance())
|
if (create_db_instance(datadir))
|
||||||
{
|
{
|
||||||
die("database creation failed");
|
die("database creation failed");
|
||||||
}
|
}
|
||||||
@ -280,19 +337,37 @@ static char *get_plugindir()
|
|||||||
|
|
||||||
static char *init_bootstrap_command_line(char *cmdline, size_t size)
|
static char *init_bootstrap_command_line(char *cmdline, size_t size)
|
||||||
{
|
{
|
||||||
char basedir[MAX_PATH];
|
snprintf(cmdline, size - 1,
|
||||||
get_basedir(basedir, sizeof(basedir), mysqld_path);
|
"\"\"%s\""
|
||||||
|
" --defaults-file=my.ini"
|
||||||
my_snprintf(cmdline, size - 1,
|
" %s"
|
||||||
"\"\"%s\" --no-defaults %s --innodb-page-size=%d --bootstrap"
|
" --bootstrap"
|
||||||
" \"--lc-messages-dir=%s/share\""
|
" --datadir=."
|
||||||
" --basedir=. --datadir=. --default-storage-engine=myisam"
|
" --loose-innodb-buffer-pool-size=10M"
|
||||||
" --max_allowed_packet=9M "
|
"\""
|
||||||
" --net-buffer-length=16k\"", mysqld_path,
|
, mysqld_path, opt_verbose_bootstrap ? "--console" : "");
|
||||||
opt_verbose_bootstrap ? "--console" : "", opt_innodb_page_size, basedir);
|
|
||||||
return cmdline;
|
return cmdline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char my_ini_path[MAX_PATH];
|
||||||
|
|
||||||
|
static void write_myini_str(const char *key, const char* val, const char *section="mysqld")
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(my_ini_path[0]);
|
||||||
|
if (!WritePrivateProfileString(section, key, val, my_ini_path))
|
||||||
|
{
|
||||||
|
die("Can't write to ini file key=%s, val=%s, section=%s, Windows error %u",key,val,section,
|
||||||
|
GetLastError());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void write_myini_int(const char* key, int val, const char* section = "mysqld")
|
||||||
|
{
|
||||||
|
char buf[10];
|
||||||
|
itoa(val, buf, 10);
|
||||||
|
write_myini_str(key, buf, section);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Create my.ini in current directory (this is assumed to be
|
Create my.ini in current directory (this is assumed to be
|
||||||
@ -306,21 +381,22 @@ static int create_myini()
|
|||||||
|
|
||||||
char path_buf[MAX_PATH];
|
char path_buf[MAX_PATH];
|
||||||
GetCurrentDirectory(MAX_PATH, path_buf);
|
GetCurrentDirectory(MAX_PATH, path_buf);
|
||||||
|
snprintf(my_ini_path,sizeof(my_ini_path), "%s\\my.ini", path_buf);
|
||||||
/* Create ini file. */
|
if (opt_config)
|
||||||
FILE *myini= fopen("my.ini","wt");
|
|
||||||
if (!myini)
|
|
||||||
{
|
{
|
||||||
die("Can't create my.ini in data directory");
|
if (!CopyFile(opt_config, my_ini_path,TRUE))
|
||||||
|
{
|
||||||
|
die("Can't copy %s to my.ini , last error %lu", opt_config, GetLastError());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out server settings. */
|
/* Write out server settings. */
|
||||||
fprintf(myini, "[mysqld]\n");
|
|
||||||
convert_slashes(path_buf);
|
convert_slashes(path_buf);
|
||||||
fprintf(myini, "datadir=%s\n", path_buf);
|
write_myini_str("datadir",path_buf);
|
||||||
|
|
||||||
if (opt_skip_networking)
|
if (opt_skip_networking)
|
||||||
{
|
{
|
||||||
fprintf(myini,"skip-networking\n");
|
write_myini_str("skip-networking","ON");
|
||||||
if (!opt_socket)
|
if (!opt_socket)
|
||||||
opt_socket= opt_service;
|
opt_socket= opt_service;
|
||||||
}
|
}
|
||||||
@ -329,40 +405,39 @@ static int create_myini()
|
|||||||
|
|
||||||
if (enable_named_pipe)
|
if (enable_named_pipe)
|
||||||
{
|
{
|
||||||
fprintf(myini,"named-pipe=ON\n");
|
write_myini_str("named-pipe","ON");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_socket && opt_socket[0])
|
if (opt_socket && opt_socket[0])
|
||||||
{
|
{
|
||||||
fprintf(myini, "socket=%s\n", opt_socket);
|
write_myini_str("socket", opt_socket);
|
||||||
}
|
}
|
||||||
if (opt_port)
|
if (opt_port)
|
||||||
{
|
{
|
||||||
fprintf(myini,"port=%d\n", opt_port);
|
write_myini_int("port", opt_port);
|
||||||
}
|
}
|
||||||
if (opt_innodb_page_size != DEFAULT_INNODB_PAGE_SIZE)
|
if (opt_innodb_page_size != DEFAULT_INNODB_PAGE_SIZE)
|
||||||
{
|
{
|
||||||
fprintf(myini, "innodb-page-size=%d\n", opt_innodb_page_size);
|
write_myini_int("innodb-page-size", opt_innodb_page_size);
|
||||||
}
|
}
|
||||||
if (opt_large_pages)
|
if (opt_large_pages)
|
||||||
{
|
{
|
||||||
fprintf(myini, "large-pages=ON\n");
|
write_myini_str("large-pages","ON");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out client settings. */
|
/* Write out client settings. */
|
||||||
fprintf(myini, "[client]\n");
|
|
||||||
|
|
||||||
/* Used for named pipes */
|
/* Used for named pipes */
|
||||||
if (opt_socket && opt_socket[0])
|
if (opt_socket && opt_socket[0])
|
||||||
fprintf(myini,"socket=%s\n",opt_socket);
|
write_myini_str("socket",opt_socket,"client");
|
||||||
if (opt_skip_networking)
|
if (opt_skip_networking)
|
||||||
fprintf(myini,"protocol=pipe\n");
|
write_myini_str("protocol", "pipe", "client");
|
||||||
else if (opt_port)
|
else if (opt_port)
|
||||||
fprintf(myini,"port=%d\n",opt_port);
|
write_myini_int("port",opt_port,"client");
|
||||||
|
|
||||||
char *plugin_dir = get_plugindir();
|
char *plugin_dir = get_plugindir();
|
||||||
if (plugin_dir)
|
if (plugin_dir)
|
||||||
fprintf(myini, "plugin-dir=%s\n", plugin_dir);
|
write_myini_str("plugin-dir", plugin_dir, "client");
|
||||||
fclose(myini);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,20 +532,20 @@ static int handle_user_privileges(const char *account_name, const wchar_t *privi
|
|||||||
|
|
||||||
/* Register service. Assume my.ini is in datadir */
|
/* Register service. Assume my.ini is in datadir */
|
||||||
|
|
||||||
static int register_service(const char *user, const char *passwd)
|
static int register_service(const char *datadir, const char *user, const char *passwd)
|
||||||
{
|
{
|
||||||
char buf[3*MAX_PATH +32]; /* path to mysqld.exe, to my.ini, service name */
|
char buf[3*MAX_PATH +32]; /* path to mysqld.exe, to my.ini, service name */
|
||||||
SC_HANDLE sc_manager, sc_service;
|
SC_HANDLE sc_manager, sc_service;
|
||||||
|
|
||||||
size_t datadir_len= strlen(opt_datadir);
|
size_t datadir_len= strlen(datadir);
|
||||||
const char *backslash_after_datadir= "\\";
|
const char *backslash_after_datadir= "\\";
|
||||||
|
|
||||||
if (datadir_len && opt_datadir[datadir_len-1] == '\\')
|
if (datadir_len && datadir[datadir_len-1] == '\\')
|
||||||
backslash_after_datadir= "";
|
backslash_after_datadir= "";
|
||||||
|
|
||||||
verbose("Registering service '%s'", opt_service);
|
verbose("Registering service '%s'", opt_service);
|
||||||
my_snprintf(buf, sizeof(buf)-1,
|
my_snprintf(buf, sizeof(buf)-1,
|
||||||
"\"%s\" \"--defaults-file=%s%smy.ini\" \"%s\"" , mysqld_path, opt_datadir,
|
"\"%s\" \"--defaults-file=%s%smy.ini\" \"%s\"" , mysqld_path, datadir,
|
||||||
backslash_after_datadir, opt_service);
|
backslash_after_datadir, opt_service);
|
||||||
|
|
||||||
/* Get a handle to the SCM database. */
|
/* Get a handle to the SCM database. */
|
||||||
@ -624,7 +699,7 @@ static int set_directory_permissions(const char *dir, const char *os_user)
|
|||||||
|
|
||||||
/* Create database instance (including registering as service etc) .*/
|
/* Create database instance (including registering as service etc) .*/
|
||||||
|
|
||||||
static int create_db_instance()
|
static int create_db_instance(const char *datadir)
|
||||||
{
|
{
|
||||||
int ret= 0;
|
int ret= 0;
|
||||||
char cwd[MAX_PATH];
|
char cwd[MAX_PATH];
|
||||||
@ -634,6 +709,7 @@ static int create_db_instance()
|
|||||||
bool cleanup_datadir= true;
|
bool cleanup_datadir= true;
|
||||||
DWORD last_error;
|
DWORD last_error;
|
||||||
bool service_created= false;
|
bool service_created= false;
|
||||||
|
std::string mysql_db_dir;
|
||||||
|
|
||||||
verbose("Running bootstrap");
|
verbose("Running bootstrap");
|
||||||
|
|
||||||
@ -641,68 +717,47 @@ static int create_db_instance()
|
|||||||
|
|
||||||
/* Create datadir and datadir/mysql, if they do not already exist. */
|
/* Create datadir and datadir/mysql, if they do not already exist. */
|
||||||
|
|
||||||
if (!CreateDirectory(opt_datadir, NULL) && (GetLastError() != ERROR_ALREADY_EXISTS))
|
if (!CreateDirectory(datadir, NULL) && (GetLastError() != ERROR_ALREADY_EXISTS))
|
||||||
{
|
{
|
||||||
last_error = GetLastError();
|
last_error = GetLastError();
|
||||||
switch(last_error)
|
switch(last_error)
|
||||||
{
|
{
|
||||||
case ERROR_ACCESS_DENIED:
|
case ERROR_ACCESS_DENIED:
|
||||||
die("Can't create data directory '%s' (access denied)\n",
|
die("Can't create data directory '%s' (access denied)\n",
|
||||||
opt_datadir);
|
datadir);
|
||||||
break;
|
break;
|
||||||
case ERROR_PATH_NOT_FOUND:
|
case ERROR_PATH_NOT_FOUND:
|
||||||
die("Can't create data directory '%s' "
|
die("Can't create data directory '%s' "
|
||||||
"(one or more intermediate directories do not exist)\n",
|
"(one or more intermediate directories do not exist)\n",
|
||||||
opt_datadir);
|
datadir);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
die("Can't create data directory '%s', last error %u\n",
|
die("Can't create data directory '%s', last error %u\n",
|
||||||
opt_datadir, last_error);
|
datadir, last_error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SetCurrentDirectory(opt_datadir))
|
if (!SetCurrentDirectory(datadir))
|
||||||
{
|
{
|
||||||
last_error = GetLastError();
|
last_error = GetLastError();
|
||||||
switch (last_error)
|
switch (last_error)
|
||||||
{
|
{
|
||||||
case ERROR_DIRECTORY:
|
case ERROR_DIRECTORY:
|
||||||
die("Can't set current directory to '%s', the path is not a valid directory \n",
|
die("Can't set current directory to '%s', the path is not a valid directory \n",
|
||||||
opt_datadir);
|
datadir);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
die("Can' set current directory to '%s', last error %u\n",
|
die("Can' set current directory to '%s', last error %u\n",
|
||||||
opt_datadir, last_error);
|
datadir, last_error);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PathIsDirectoryEmpty(opt_datadir))
|
if (!PathIsDirectoryEmpty(datadir))
|
||||||
{
|
{
|
||||||
cleanup_datadir= false;
|
fprintf(stderr,"FATAL ERROR: data directory is not empty\n");
|
||||||
}
|
exit(1);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string service_user;
|
std::string service_user;
|
||||||
@ -711,7 +766,7 @@ static int create_db_instance()
|
|||||||
{
|
{
|
||||||
/* Run service under virtual account NT SERVICE\service_name.*/
|
/* Run service under virtual account NT SERVICE\service_name.*/
|
||||||
service_user.append("NT SERVICE\\").append(opt_service);
|
service_user.append("NT SERVICE\\").append(opt_service);
|
||||||
ret = register_service(service_user.c_str(), NULL);
|
ret = register_service(datadir, service_user.c_str(), NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto end;
|
goto end;
|
||||||
service_created = true;
|
service_created = true;
|
||||||
@ -722,34 +777,38 @@ static int create_db_instance()
|
|||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Set data directory permissions for both current user and
|
Set data directory permissions for both current user and
|
||||||
default_os_user (the one who runs services).
|
the one who who runs services.
|
||||||
*/
|
*/
|
||||||
set_directory_permissions(opt_datadir, NULL);
|
set_directory_permissions(datadir, NULL);
|
||||||
if (!service_user.empty())
|
if (!service_user.empty())
|
||||||
{
|
{
|
||||||
set_directory_permissions(opt_datadir, service_user.c_str());
|
set_directory_permissions(datadir, service_user.c_str());
|
||||||
set_directory_permissions("mysql",service_user.c_str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Get security descriptor for the new directory.
|
Get security descriptor for the data directory.
|
||||||
It will be passed, as SDDL text, to the mysqld bootstrap subprocess,
|
It will be passed, as SDDL text, to the mysqld bootstrap subprocess,
|
||||||
to allow for correct subdirectory permissions.
|
to allow for correct subdirectory permissions.
|
||||||
*/
|
*/
|
||||||
PSECURITY_DESCRIPTOR pSD;
|
PSECURITY_DESCRIPTOR pSD;
|
||||||
if (GetNamedSecurityInfoA(opt_datadir,SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
if (GetNamedSecurityInfoA(datadir, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
||||||
0,0,0,0,&pSD) == ERROR_SUCCESS)
|
0, 0, 0, 0, &pSD) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
char* string_sd = NULL;
|
char* string_sd = NULL;
|
||||||
if (ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION_1,
|
if (ConvertSecurityDescriptorToStringSecurityDescriptor(pSD, SDDL_REVISION_1,
|
||||||
DACL_SECURITY_INFORMATION,&string_sd,0))
|
DACL_SECURITY_INFORMATION, &string_sd, 0))
|
||||||
{
|
{
|
||||||
_putenv_s("MARIADB_NEW_DIRECTORY_SDDL",string_sd);
|
_putenv_s("MARIADB_NEW_DIRECTORY_SDDL", string_sd);
|
||||||
LocalFree(string_sd);
|
LocalFree(string_sd);
|
||||||
}
|
}
|
||||||
LocalFree(pSD);
|
LocalFree(pSD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Create my.ini file in data directory.*/
|
||||||
|
ret = create_myini();
|
||||||
|
if (ret)
|
||||||
|
goto end;
|
||||||
|
|
||||||
/* Do mysqld --bootstrap. */
|
/* Do mysqld --bootstrap. */
|
||||||
init_bootstrap_command_line(cmdline, sizeof(cmdline));
|
init_bootstrap_command_line(cmdline, sizeof(cmdline));
|
||||||
|
|
||||||
@ -764,18 +823,23 @@ static int create_db_instance()
|
|||||||
{
|
{
|
||||||
verbose("WARNING: Can't 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)
|
static const char *pre_bootstrap_sql[] = { "create database mysql;\n","use mysql;\n"};
|
||||||
{
|
for (auto cmd : pre_bootstrap_sql)
|
||||||
verbose("ERROR: Can't write to mysqld's stdin");
|
|
||||||
ret= 1;
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
int i;
|
|
||||||
for (i=0; mysql_bootstrap_sql[i]; i++)
|
|
||||||
{
|
{
|
||||||
/* Write the bootstrap script to stdin. */
|
/* Write the bootstrap script to stdin. */
|
||||||
if (fwrite(mysql_bootstrap_sql[i], strlen(mysql_bootstrap_sql[i]), 1, in) != 1)
|
if (fwrite(cmd, strlen(cmd), 1, in) != 1)
|
||||||
|
{
|
||||||
|
verbose("ERROR: Can't write to mysqld's stdin");
|
||||||
|
ret= 1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i= 0; mysql_bootstrap_sql[i]; i++)
|
||||||
|
{
|
||||||
|
auto cmd = mysql_bootstrap_sql[i];
|
||||||
|
/* Write the bootstrap script to stdin. */
|
||||||
|
if (fwrite(cmd, strlen(cmd), 1, in) != 1)
|
||||||
{
|
{
|
||||||
verbose("ERROR: Can't write to mysqld's stdin");
|
verbose("ERROR: Can't write to mysqld's stdin");
|
||||||
ret= 1;
|
ret= 1;
|
||||||
@ -817,7 +881,7 @@ static int create_db_instance()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
On some reason, bootstrap chokes if last command sent via stdin ends with
|
On some reason, bootstrap chokes if last command sent via stdin ends with
|
||||||
newline, so we supply a dummy comment, that does not end with newline.
|
newline, so we supply a dummy comment, that does not end with newline.
|
||||||
*/
|
*/
|
||||||
fputs(end_of_script, in);
|
fputs(end_of_script, in);
|
||||||
@ -831,12 +895,6 @@ static int create_db_instance()
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Create my.ini file in data directory.*/
|
|
||||||
ret= create_myini();
|
|
||||||
if (ret)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return ret;
|
return ret;
|
||||||
@ -845,7 +903,7 @@ end:
|
|||||||
if (cleanup_datadir)
|
if (cleanup_datadir)
|
||||||
{
|
{
|
||||||
SetCurrentDirectory(cwd);
|
SetCurrentDirectory(cwd);
|
||||||
clean_directory(opt_datadir);
|
clean_directory(datadir);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (service_created)
|
if (service_created)
|
||||||
|
Reference in New Issue
Block a user