mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
MDEV-26713 UTF8 support on Windows, mysql_upgrade_service preparation
- Tolerate situation, when datadir for service seems invalid/non-existing prior to upgrade. It could be that my.ini contains legacy ANSI characters for the data directory. Those can't be read correctly by mysql_upgrade_service, which uses a different ANSI codepage(UTF8) . - schedule upgrade_config_file at later stage, because once we convert it to UTF-8 (followup patch), this will render config file uselss with the older version of mariadbd.exe - Refactor upgrade_conf_file.cc, prepare for UTF-8 conversion.
This commit is contained in:
committed by
Sergei Golubchik
parent
a4fc41b6b4
commit
a296c52627
@@ -374,13 +374,17 @@ static void change_service_config()
|
||||
Write datadir to my.ini, after converting backslashes to
|
||||
unix style slashes.
|
||||
*/
|
||||
if (service_properties.datadir[0])
|
||||
{
|
||||
strcpy_s(buf, MAX_PATH, service_properties.datadir);
|
||||
for (i= 0; buf[i]; i++)
|
||||
{
|
||||
if (buf[i] == '\\')
|
||||
buf[i]= '/';
|
||||
}
|
||||
WritePrivateProfileString("mysqld", "datadir",buf, service_properties.inifile);
|
||||
WritePrivateProfileString("mysqld", "datadir", buf,
|
||||
service_properties.inifile);
|
||||
}
|
||||
|
||||
/*
|
||||
Remove basedir from defaults file, otherwise the service wont come up in
|
||||
@@ -465,13 +469,8 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
old_mysqld_exe_exists = (GetFileAttributes(service_properties.mysqld_exe) != INVALID_FILE_ATTRIBUTES);
|
||||
log("Phase %d/%d: Fixing server config file%s", ++phase, max_phases, my_ini_exists ? "" : "(skipped)");
|
||||
|
||||
snprintf(my_ini_bck, sizeof(my_ini_bck), "%s.BCK", service_properties.inifile);
|
||||
CopyFile(service_properties.inifile, my_ini_bck, FALSE);
|
||||
upgrade_config_file(service_properties.inifile);
|
||||
|
||||
old_mysqld_exe_exists= (GetFileAttributes(service_properties.mysqld_exe) !=
|
||||
INVALID_FILE_ATTRIBUTES);
|
||||
bool do_start_stop_server = old_mysqld_exe_exists && initial_service_state != SERVICE_RUNNING;
|
||||
|
||||
log("Phase %d/%d: Start and stop server in the old version, to avoid crash recovery %s", ++phase, max_phases,
|
||||
@@ -526,6 +525,14 @@ int main(int argc, char **argv)
|
||||
start_duration_ms += 500;
|
||||
}
|
||||
}
|
||||
|
||||
log("Phase %d/%d: Fixing server config file%s", ++phase, max_phases,
|
||||
my_ini_exists ? "" : "(skipped)");
|
||||
snprintf(my_ini_bck, sizeof(my_ini_bck), "%s.BCK",
|
||||
service_properties.inifile);
|
||||
CopyFile(service_properties.inifile, my_ini_bck, FALSE);
|
||||
upgrade_config_file(service_properties.inifile);
|
||||
|
||||
/*
|
||||
Start mysqld.exe as non-service skipping privileges (so we do not
|
||||
care about the password). But disable networking and enable pipe
|
||||
|
@@ -158,16 +158,19 @@ static int cmp_strings(const void* a, const void *b)
|
||||
return strcmp((const char *)a, *(const char **)b);
|
||||
}
|
||||
|
||||
/**
|
||||
Convert file from a previous version, by removing
|
||||
*/
|
||||
int upgrade_config_file(const char *myini_path)
|
||||
{
|
||||
|
||||
#define MY_INI_SECTION_SIZE 32 * 1024 + 3
|
||||
static char section_data[MY_INI_SECTION_SIZE];
|
||||
for (const char *section_name : { "mysqld","server","mariadb" })
|
||||
|
||||
|
||||
int fix_section(const char *myini_path, const char *section_name,
|
||||
bool is_server)
|
||||
{
|
||||
DWORD size = GetPrivateProfileSection(section_name, section_data, MY_INI_SECTION_SIZE, myini_path);
|
||||
if (!is_server)
|
||||
return 0;
|
||||
|
||||
static char section_data[MY_INI_SECTION_SIZE];
|
||||
DWORD size= GetPrivateProfileSection(section_name, section_data,
|
||||
MY_INI_SECTION_SIZE, myini_path);
|
||||
if (size == MY_INI_SECTION_SIZE - 2)
|
||||
{
|
||||
return -1;
|
||||
@@ -176,13 +179,19 @@ int upgrade_config_file(const char *myini_path)
|
||||
for (char *keyval= section_data; *keyval; keyval += strlen(keyval)+1)
|
||||
{
|
||||
char varname[256];
|
||||
char *value;
|
||||
char *key_end= strchr(keyval, '=');
|
||||
if (!key_end)
|
||||
key_end= keyval + strlen(keyval);
|
||||
|
||||
if (key_end - keyval > sizeof(varname))
|
||||
continue;
|
||||
// copy and normalize (convert dash to underscore) to variable names
|
||||
|
||||
value= key_end + 1;
|
||||
|
||||
// Check if variable should be removed from config.
|
||||
// First, copy and normalize (convert dash to underscore) to variable
|
||||
// names
|
||||
for (char *p= keyval, *q= varname;; p++, q++)
|
||||
{
|
||||
if (p == key_end)
|
||||
@@ -203,6 +212,49 @@ int upgrade_config_file(const char *myini_path)
|
||||
WritePrivateProfileString(section_name, keyval, 0, myini_path);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool is_mariadb_section(const char *name, bool *is_server)
|
||||
{
|
||||
if (strncmp(name, "mysql", 5)
|
||||
&& strncmp(name, "mariadb", 7)
|
||||
&& strcmp(name, "client")
|
||||
&& strcmp(name, "client-server")
|
||||
&& strcmp(name, "server"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const char *section_name : {"mysqld", "server", "mariadb"})
|
||||
if (*is_server= !strcmp(section_name, name))
|
||||
break;
|
||||
|
||||
return *is_server;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Convert file from a previous version, by removing obsolete variables
|
||||
Also, fix values to be UTF8, if MariaDB is running in utf8 mode
|
||||
*/
|
||||
int upgrade_config_file(const char *myini_path)
|
||||
{
|
||||
static char all_sections[MY_INI_SECTION_SIZE];
|
||||
int sz= GetPrivateProfileSectionNamesA(all_sections, MY_INI_SECTION_SIZE,
|
||||
myini_path);
|
||||
if (!sz)
|
||||
return 0;
|
||||
if (sz > MY_INI_SECTION_SIZE - 2)
|
||||
{
|
||||
fprintf(stderr, "Too many sections in config file\n");
|
||||
return -1;
|
||||
}
|
||||
for (char *section= all_sections; *section; section+= strlen(section) + 1)
|
||||
{
|
||||
bool is_server_section;
|
||||
if (is_mariadb_section(section, &is_server_section))
|
||||
fix_section(myini_path, section, is_server_section);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@@ -134,6 +134,20 @@ static void get_datadir_from_ini(const char *ini, char *service_name, char *data
|
||||
}
|
||||
|
||||
|
||||
static int fix_and_check_datadir(mysqld_service_properties *props)
|
||||
{
|
||||
normalize_path(props->datadir, MAX_PATH);
|
||||
/* Check if datadir really exists */
|
||||
if (GetFileAttributes(props->datadir) != INVALID_FILE_ATTRIBUTES)
|
||||
return 0;
|
||||
/*
|
||||
It is possible, that datadir contains some unconvertable character.
|
||||
We just pretend not to know what's the data directory
|
||||
*/
|
||||
props->datadir[0]= 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Retrieve some properties from windows mysqld service binary path.
|
||||
We're interested in ini file location and datadir, and also in version of
|
||||
@@ -284,16 +298,9 @@ int get_mysql_service_properties(const wchar_t *bin_path,
|
||||
}
|
||||
}
|
||||
|
||||
if (props->datadir[0])
|
||||
if (props->datadir[0] == 0 || fix_and_check_datadir(props))
|
||||
{
|
||||
normalize_path(props->datadir, MAX_PATH);
|
||||
/* Check if datadir really exists */
|
||||
if (GetFileAttributes(props->datadir) == INVALID_FILE_ATTRIBUTES)
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There is no datadir in ini file, bail out.*/
|
||||
/* There is no datadir in ini file, or non-existing dir, bail out.*/
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user